Export im Hintergrund mit Fortschritt, Abbruch und Download
Exporte laufen nacheinander. Der Fortschritt steht im Speicher; ein nach einem Neustart verwaister Export wird als unterbrochen gemeldet. Nach Änderungen an Einstellungen oder Dateien gilt ein fertiges Video als veraltet. Der Download trägt den Zeitraum im Dateinamen. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
03bfda09b2
commit
6e497ffc45
4 files changed
+183
-8
No files matched your search
+27
-6
@@ -10,7 +10,7 @@ import {
|
||||
} from './auth.js';
|
||||
import { HttpError, badRequest } from './http-error.js';
|
||||
|
||||
export function createApp({ config, secret, store }) {
|
||||
export function createApp({ config, secret, store, queue }) {
|
||||
const app = express();
|
||||
app.disable('x-powered-by');
|
||||
app.set('trust proxy', true);
|
||||
@@ -57,20 +57,22 @@ export function createApp({ config, secret, store }) {
|
||||
});
|
||||
|
||||
const route = (handler) => (req, res, next) => Promise.resolve(handler(req, res)).catch(next);
|
||||
const present = (project) => ({ ...project, render: queue.describe(project) });
|
||||
|
||||
app.get('/api/projects', route(async (req, res) => {
|
||||
res.json(await store.list());
|
||||
}));
|
||||
|
||||
app.post('/api/projects', route(async (req, res) => {
|
||||
res.status(201).json(await store.create(req.body ?? {}));
|
||||
res.status(201).json(present(await store.create(req.body ?? {})));
|
||||
}));
|
||||
|
||||
app.get('/api/projects/:id', route(async (req, res) => {
|
||||
res.json(await store.get(req.params.id));
|
||||
res.json(present(await store.get(req.params.id)));
|
||||
}));
|
||||
|
||||
app.delete('/api/projects/:id', route(async (req, res) => {
|
||||
if (queue.isRunning(req.params.id)) queue.cancel(req.params.id);
|
||||
await store.remove(req.params.id);
|
||||
res.status(204).end();
|
||||
}));
|
||||
@@ -82,7 +84,7 @@ export function createApp({ config, secret, store }) {
|
||||
};
|
||||
|
||||
app.patch('/api/projects/:id/settings', route(async (req, res) => {
|
||||
res.json(await store.updateSettings(req.params.id, req.body));
|
||||
res.json(present(await store.updateSettings(req.params.id, req.body)));
|
||||
}));
|
||||
|
||||
app.put('/api/projects/:id/clips/:index', route(async (req, res) => {
|
||||
@@ -96,7 +98,7 @@ export function createApp({ config, secret, store }) {
|
||||
}));
|
||||
|
||||
app.post('/api/projects/:id/assets/:slot', route(async (req, res) => {
|
||||
res.status(201).json(await store.createAsset(req.params.id, req.params.slot, req.body));
|
||||
res.status(201).json(present(await store.createAsset(req.params.id, req.params.slot, req.body)));
|
||||
}));
|
||||
|
||||
app.put('/api/projects/:id/assets/:slot', route(async (req, res) => {
|
||||
@@ -105,7 +107,7 @@ export function createApp({ config, secret, store }) {
|
||||
}));
|
||||
|
||||
app.delete('/api/projects/:id/assets/:slot', route(async (req, res) => {
|
||||
res.json(await store.removeAsset(req.params.id, req.params.slot));
|
||||
res.json(present(await store.removeAsset(req.params.id, req.params.slot)));
|
||||
}));
|
||||
|
||||
app.get('/api/projects/:id/assets/:slot/file', route(async (req, res) => {
|
||||
@@ -113,6 +115,25 @@ export function createApp({ config, secret, store }) {
|
||||
res.sendFile(store.readyPath(project, { type: 'asset', slot: req.params.slot }));
|
||||
}));
|
||||
|
||||
app.post('/api/projects/:id/render', route(async (req, res) => {
|
||||
await queue.start(req.params.id);
|
||||
res.status(202).json(present(await store.get(req.params.id)));
|
||||
}));
|
||||
|
||||
app.delete('/api/projects/:id/render', route(async (req, res) => {
|
||||
queue.cancel(req.params.id);
|
||||
res.status(202).json(present(await store.get(req.params.id)));
|
||||
}));
|
||||
|
||||
// ?download=1 speichert die Datei, sonst Wiedergabe im Browser
|
||||
app.get('/api/projects/:id/output', route(async (req, res) => {
|
||||
const project = await store.get(req.params.id);
|
||||
const file = await queue.outputPath(project);
|
||||
if (req.query.download === undefined) return res.sendFile(file);
|
||||
const { from, to } = project.range;
|
||||
res.download(file, from && to ? `FuerDieCuts_${from}_bis_${to}.mp4` : 'FuerDieCuts.mp4');
|
||||
}));
|
||||
|
||||
app.use('/api', (req, res) => res.status(404).json({ error: 'Nicht gefunden.' }));
|
||||
|
||||
// eslint-disable-next-line no-unused-vars -- Express erkennt Fehlerbehandler an vier Parametern
|
||||
|
||||
Reference in new issue
Block a user