Ein Projekt hält die ausgewählten Clips samt Absender und Beschriftung. Videos kommen in Stücken bis 16 MB; die Größe der Teildatei ist der Stand, sodass ein abgebrochener Upload dort weitermacht. Nach dem letzten Stück liest ffprobe Länge, Größe, Drehung und Tonspur aus. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
43 lines
1.4 KiB
JavaScript
43 lines
1.4 KiB
JavaScript
import http from 'node:http';
|
||
import path from 'node:path';
|
||
import { fileURLToPath } from 'node:url';
|
||
import express from 'express';
|
||
import { createApp } from './app.js';
|
||
import { loadSessionSecret } from './auth.js';
|
||
import { loadConfig } from './config.js';
|
||
import { probe } from './media.js';
|
||
import { createProjectStore } from './projects.js';
|
||
|
||
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||
|
||
const config = loadConfig();
|
||
if (!config.pin) {
|
||
console.warn('APP_PIN ist nicht gesetzt – Anmeldung ist nicht möglich.');
|
||
}
|
||
|
||
const store = createProjectStore({ dataDir: config.dataDir, probe });
|
||
const app = createApp({ config, secret: loadSessionSecret(config), store });
|
||
const server = http.createServer(app);
|
||
|
||
if (config.isProduction) {
|
||
const distDir = path.join(rootDir, 'dist');
|
||
app.use(express.static(distDir));
|
||
app.use((req, res, next) => {
|
||
if (req.method !== 'GET') return next();
|
||
res.sendFile(path.join(distDir, 'index.html'));
|
||
});
|
||
} else {
|
||
// Im Entwicklungsbetrieb liefert Vite das Frontend über denselben Port aus.
|
||
const { createServer } = await import('vite');
|
||
const vite = await createServer({
|
||
root: rootDir,
|
||
appType: 'spa',
|
||
server: { middlewareMode: true, hmr: { server } },
|
||
});
|
||
app.use(vite.middlewares);
|
||
}
|
||
|
||
server.listen(config.port, '0.0.0.0', () => {
|
||
console.log(`FuerDieCuts läuft auf Port ${config.port}`);
|
||
});
|