修复后端问题
This commit is contained in:
45
server.js
45
server.js
@@ -92,6 +92,17 @@ const progressMap = {};
|
||||
const transcodeProcesses = new Map();
|
||||
const wsSubscriptions = new Map();
|
||||
const progressApiLogMap = new Map();
|
||||
const progressStateLogMap = new Map();
|
||||
|
||||
const setProgressState = (progressKey, key, nextState, reason = '') => {
|
||||
progressMap[progressKey] = nextState;
|
||||
const signature = `${nextState?.status || 'null'}:${typeof nextState?.percent === 'number' ? nextState.percent : 'na'}:${nextState?.streamSessionId || 'na'}`;
|
||||
if (progressStateLogMap.get(progressKey) !== signature) {
|
||||
progressStateLogMap.set(progressKey, signature);
|
||||
console.log(`[progress-state] key=${key} status=${nextState?.status || 'null'} percent=${typeof nextState?.percent === 'number' ? nextState.percent : 'na'} reason=${reason || 'unspecified'} session=${nextState?.streamSessionId || 'na'}`);
|
||||
}
|
||||
return nextState;
|
||||
};
|
||||
|
||||
const AVAILABLE_VIDEO_ENCODERS = [
|
||||
{ value: 'h264_rkmpp', label: 'h264_rkmpp (RKMPP H.264)' },
|
||||
@@ -800,12 +811,12 @@ app.post('/api/stop-transcode', (req, res) => {
|
||||
return res.status(404).json({ error: 'No active transcode found for this key' });
|
||||
}
|
||||
stopActiveTranscode(progressKey);
|
||||
progressMap[progressKey] = {
|
||||
setProgressState(progressKey, key, {
|
||||
status: 'cancelled',
|
||||
percent: 0,
|
||||
details: 'Transcode stopped by user',
|
||||
mp4Url: null
|
||||
};
|
||||
}, 'stop-transcode');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: progressMap[progressKey] });
|
||||
res.json({ message: 'Transcode stopped' });
|
||||
} catch (error) {
|
||||
@@ -868,7 +879,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
try {
|
||||
const replacedExistingStream = stopActiveTranscode(progressKey);
|
||||
if (replacedExistingStream && startSeconds > 0) {
|
||||
progressMap[progressKey] = {
|
||||
setProgressState(progressKey, key, {
|
||||
...(progressMap[progressKey] || {}),
|
||||
status: 'transcoding',
|
||||
percent: Math.min(Math.max(Math.round((startSeconds / Math.max(progressMap[progressKey]?.duration || startSeconds || 1, 1)) * 100), 0), 100),
|
||||
@@ -876,7 +887,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
streamSessionId,
|
||||
details: `Restarting transcode from ${startSeconds.toFixed(2)}s`,
|
||||
mp4Url: null
|
||||
};
|
||||
}, 'restart-seek');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: progressMap[progressKey] });
|
||||
}
|
||||
|
||||
@@ -885,7 +896,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
const cacheExists = fs.existsSync(downloadPath);
|
||||
|
||||
if (!cacheExists) {
|
||||
progressMap[progressKey] = {
|
||||
setProgressState(progressKey, key, {
|
||||
status: 'downloading',
|
||||
percent: 0,
|
||||
downloadedBytes: 0,
|
||||
@@ -893,7 +904,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
streamSessionId,
|
||||
details: 'Downloading full source before streaming...',
|
||||
mp4Url: null
|
||||
};
|
||||
}, 'download-start');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: progressMap[progressKey] });
|
||||
|
||||
await ensureSourceCached({
|
||||
@@ -915,12 +926,12 @@ app.get('/api/stream', async (req, res) => {
|
||||
details: totalBytes ? `Downloading source ${percent}%` : 'Downloading source...',
|
||||
mp4Url: null
|
||||
};
|
||||
progressMap[progressKey] = downloadState;
|
||||
setProgressState(progressKey, key, downloadState, 'download-progress');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: downloadState });
|
||||
}
|
||||
});
|
||||
|
||||
progressMap[progressKey] = {
|
||||
setProgressState(progressKey, key, {
|
||||
status: 'downloaded',
|
||||
percent: 100,
|
||||
downloadedBytes,
|
||||
@@ -928,14 +939,14 @@ app.get('/api/stream', async (req, res) => {
|
||||
streamSessionId,
|
||||
details: 'Source download complete, starting real-time transcode...',
|
||||
mp4Url: null
|
||||
};
|
||||
}, 'download-complete');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: progressMap[progressKey] });
|
||||
} else {
|
||||
const stats = fs.statSync(downloadPath);
|
||||
totalBytes = stats.size;
|
||||
downloadedBytes = totalBytes;
|
||||
console.log(`[download] cache ready bucket=${bucket} key=${key} path=${downloadPath} bytes=${totalBytes}`);
|
||||
progressMap[progressKey] = {
|
||||
setProgressState(progressKey, key, {
|
||||
status: 'downloaded',
|
||||
percent: 100,
|
||||
downloadedBytes,
|
||||
@@ -943,7 +954,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
streamSessionId,
|
||||
details: 'Source already downloaded locally, starting real-time transcode...',
|
||||
mp4Url: null
|
||||
};
|
||||
}, 'download-cache-hit');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: progressMap[progressKey] });
|
||||
}
|
||||
|
||||
@@ -953,11 +964,11 @@ app.get('/api/stream', async (req, res) => {
|
||||
const metadata = await probeFile(downloadPath);
|
||||
sourceMetadata = metadata;
|
||||
const duration = metadata.format?.duration || 0;
|
||||
progressMap[progressKey] = {
|
||||
setProgressState(progressKey, key, {
|
||||
...(progressMap[progressKey] || {}),
|
||||
duration: parseFloat(duration) || 0,
|
||||
streamSessionId
|
||||
};
|
||||
}, 'duration-probed');
|
||||
broadcastWs(progressKey, { type: 'duration', key, duration: parseFloat(duration) });
|
||||
} catch (probeErr) {
|
||||
console.error('Probe failed:', probeErr);
|
||||
@@ -1049,7 +1060,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
details: `Streaming transcode ${percent}%`,
|
||||
mp4Url: null
|
||||
};
|
||||
progressMap[progressKey] = progressState;
|
||||
setProgressState(progressKey, key, progressState, 'transcode-progress');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: progressState });
|
||||
})
|
||||
.on('stderr', (stderrLine) => {
|
||||
@@ -1064,7 +1075,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
}
|
||||
console.log(`[transcode] complete bucket=${bucket} key=${key} encoder=${encoderName} cache=${convertPath}`);
|
||||
transcodeProcesses.delete(progressKey);
|
||||
progressMap[progressKey] = {
|
||||
setProgressState(progressKey, key, {
|
||||
status: 'finished',
|
||||
percent: 100,
|
||||
duration: progressMap[progressKey]?.duration || null,
|
||||
@@ -1072,7 +1083,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
streamSessionId,
|
||||
details: 'Streaming transcode complete',
|
||||
mp4Url: null
|
||||
};
|
||||
}, 'transcode-finished');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: progressMap[progressKey] });
|
||||
})
|
||||
.on('error', (err) => {
|
||||
@@ -1090,7 +1101,7 @@ app.get('/api/stream', async (req, res) => {
|
||||
details: err.message || 'Streaming transcode failed',
|
||||
mp4Url: null
|
||||
};
|
||||
progressMap[progressKey] = failedState;
|
||||
setProgressState(progressKey, key, failedState, 'transcode-failed');
|
||||
broadcastWs(progressKey, { type: 'progress', key, progress: failedState });
|
||||
if (!res.headersSent) {
|
||||
res.status(500).json({ error: 'Failed to stream transcoded video', detail: err.message });
|
||||
|
||||
Reference in New Issue
Block a user