164 lines
6.0 KiB
JavaScript
164 lines
6.0 KiB
JavaScript
|
|
"use strict";
|
||
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
|
};
|
||
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
|
exports.createJobsRouter = createJobsRouter;
|
||
|
|
const express_1 = require("express");
|
||
|
|
const path_1 = __importDefault(require("path"));
|
||
|
|
const fs_1 = __importDefault(require("fs"));
|
||
|
|
const jobStore_1 = require("../db/jobStore");
|
||
|
|
function getParam(req, name) {
|
||
|
|
const val = req.params[name];
|
||
|
|
return Array.isArray(val) ? val[0] : val;
|
||
|
|
}
|
||
|
|
function createJobsRouter(jobManager) {
|
||
|
|
const router = (0, express_1.Router)();
|
||
|
|
router.get('/', (_req, res) => {
|
||
|
|
const jobs = jobManager.listJobs();
|
||
|
|
res.json({ jobs });
|
||
|
|
});
|
||
|
|
router.post('/', (req, res) => {
|
||
|
|
const { videoPath, config, outputOptions } = req.body;
|
||
|
|
if (!videoPath) {
|
||
|
|
res.status(400).json({ error: 'videoPath is required' });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (!fs_1.default.existsSync(videoPath)) {
|
||
|
|
res.status(400).json({ error: `Video file not found: ${videoPath}` });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
try {
|
||
|
|
const job = jobManager.createJob(videoPath, config || {}, outputOptions || {});
|
||
|
|
res.status(201).json({ job });
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
res.status(500).json({ error: err.message });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
router.get('/:id', (req, res) => {
|
||
|
|
const job = (0, jobStore_1.getJob)(getParam(req, 'id'));
|
||
|
|
if (!job) {
|
||
|
|
res.status(404).json({ error: 'Job not found' });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
res.json({ job });
|
||
|
|
});
|
||
|
|
router.post('/:id/start', async (req, res) => {
|
||
|
|
try {
|
||
|
|
await jobManager.startJob(getParam(req, 'id'));
|
||
|
|
res.json({ success: true });
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
router.post('/:id/pause', async (req, res) => {
|
||
|
|
try {
|
||
|
|
await jobManager.pauseJob(getParam(req, 'id'));
|
||
|
|
res.json({ success: true });
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
router.post('/:id/restart', async (req, res) => {
|
||
|
|
try {
|
||
|
|
await jobManager.restartJob(getParam(req, 'id'));
|
||
|
|
res.json({ success: true });
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
router.post('/:id/cancel', async (req, res) => {
|
||
|
|
try {
|
||
|
|
await jobManager.cancelJob(getParam(req, 'id'));
|
||
|
|
res.json({ success: true });
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
router.delete('/:id', (req, res) => {
|
||
|
|
try {
|
||
|
|
jobManager.deleteJob(getParam(req, 'id'));
|
||
|
|
res.json({ success: true });
|
||
|
|
}
|
||
|
|
catch (err) {
|
||
|
|
res.status(400).json({ error: err.message });
|
||
|
|
}
|
||
|
|
});
|
||
|
|
router.get('/:id/progress', (req, res) => {
|
||
|
|
res.setHeader('Content-Type', 'text/event-stream');
|
||
|
|
res.setHeader('Cache-Control', 'no-cache');
|
||
|
|
res.setHeader('Connection', 'keep-alive');
|
||
|
|
res.setHeader('X-Accel-Buffering', 'no');
|
||
|
|
const sendProgress = (data) => {
|
||
|
|
res.write(`data: ${JSON.stringify(data)}\n\n`);
|
||
|
|
};
|
||
|
|
const initialJob = (0, jobStore_1.getJob)(getParam(req, 'id'));
|
||
|
|
if (initialJob) {
|
||
|
|
sendProgress({
|
||
|
|
id: initialJob.id,
|
||
|
|
status: initialJob.status,
|
||
|
|
progress: initialJob.progress,
|
||
|
|
currentIndex: initialJob.current_index,
|
||
|
|
totalUnits: initialJob.total_units,
|
||
|
|
segments: JSON.parse(initialJob.segments),
|
||
|
|
error: initialJob.error,
|
||
|
|
output_audio: initialJob.output_audio,
|
||
|
|
output_subtitles_srt: initialJob.output_subtitles_srt,
|
||
|
|
output_subtitles_vtt: initialJob.output_subtitles_vtt,
|
||
|
|
output_muxed: initialJob.output_muxed
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const unsubscribe = jobManager.onJobProgress(getParam(req, 'id'), (data) => {
|
||
|
|
if (data.status === 'completed' || data.status === 'failed' || data.status === 'cancelled') {
|
||
|
|
sendProgress(data);
|
||
|
|
res.end();
|
||
|
|
unsubscribe();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
sendProgress(data);
|
||
|
|
});
|
||
|
|
req.on('close', () => {
|
||
|
|
unsubscribe();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
router.get('/:id/download/:type', (req, res) => {
|
||
|
|
const job = (0, jobStore_1.getJob)(getParam(req, 'id'));
|
||
|
|
if (!job) {
|
||
|
|
res.status(404).json({ error: 'Job not found' });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const type = getParam(req, 'type');
|
||
|
|
let filePath = null;
|
||
|
|
let filename = '';
|
||
|
|
switch (type) {
|
||
|
|
case 'audio':
|
||
|
|
filePath = job.output_audio;
|
||
|
|
filename = `${path_1.default.basename(job.video_filename, path_1.default.extname(job.video_filename))}_description.mp3`;
|
||
|
|
break;
|
||
|
|
case 'subtitles':
|
||
|
|
const format = req.query.format || 'srt';
|
||
|
|
filePath = format === 'vtt' ? job.output_subtitles_vtt : job.output_subtitles_srt;
|
||
|
|
filename = `${path_1.default.basename(job.video_filename, path_1.default.extname(job.video_filename))}_description.${format}`;
|
||
|
|
break;
|
||
|
|
case 'muxed':
|
||
|
|
filePath = job.output_muxed;
|
||
|
|
filename = `${path_1.default.basename(job.video_filename, path_1.default.extname(job.video_filename))}_described.mkv`;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
res.status(400).json({ error: 'Invalid download type' });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (!filePath || !fs_1.default.existsSync(filePath)) {
|
||
|
|
res.status(404).json({ error: 'Output file not found' });
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
res.download(filePath, filename);
|
||
|
|
});
|
||
|
|
return router;
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=jobs.js.map
|