优化页面布局,修复故障视频拉动进度条的故障

This commit is contained in:
CN-JS-HuiBai
2026-04-04 13:58:12 +08:00
parent b8bd8a8d76
commit a6af3765a8
3 changed files with 87 additions and 102 deletions

View File

@@ -7,7 +7,7 @@ const path = require('path');
const http = require('http');
const WebSocket = require('ws');
const ffmpeg = require('fluent-ffmpeg');
const { S3Client, ListBucketsCommand, ListObjectsV2Command, GetObjectCommand } = require('@aws-sdk/client-s3');
const { S3Client, ListBucketsCommand, ListObjectsV2Command, GetObjectCommand, HeadObjectCommand } = require('@aws-sdk/client-s3');
const crypto = require('crypto');
const Redis = require('ioredis');
@@ -396,16 +396,36 @@ const ensureS3Downloaded = async (s3Client, bucket, key, tmpInputPath, progressK
}
}
let shouldDownload = true;
let s3Metadata = null;
if (fs.existsSync(tmpInputPath)) {
const stats = fs.statSync(tmpInputPath);
const totalBytes = stats.size;
const localSize = stats.size;
try {
const headCommand = new HeadObjectCommand({ Bucket: bucket, Key: key });
s3Metadata = await s3Client.send(headCommand);
if (s3Metadata.ContentLength === localSize) {
shouldDownload = false;
console.log(`[Cache] Verified ${key}: Local size matches S3 (${localSize} bytes).`);
} else {
console.log(`[Cache] Mismatch for ${key}: Local ${localSize} vs S3 ${s3Metadata.ContentLength}. Re-downloading.`);
}
} catch (err) {
console.error(`[Cache] Failed to verify S3 metadata for ${key}:`, err.message);
}
}
if (!shouldDownload) {
progressMap[progressKey] = {
status: 'downloaded',
percent: 100,
downloadedBytes: totalBytes,
totalBytes,
downloadedBytes: s3Metadata.ContentLength,
totalBytes: s3Metadata.ContentLength,
streamSessionId,
details: 'Source already downloaded locally...',
details: 'Source cached locally and verified against S3...',
mp4Url: null
};
broadcastWs(progressKey, { type: 'progress', key, progress: progressMap[progressKey] });
@@ -489,39 +509,7 @@ const ensureS3Downloaded = async (s3Client, bucket, key, tmpInputPath, progressK
}
};
const clearDownloadCache = () => {
const tmpDir = CACHE_DIR;
try {
if (!fs.existsSync(tmpDir)) return;
const files = fs.readdirSync(tmpDir);
for (const file of files) {
if (file.startsWith('s3-input-') && (file.endsWith('.tmp') || file.endsWith('.downloading'))) {
const filePath = path.join(tmpDir, file);
fs.rmSync(filePath, { force: true });
}
}
} catch (err) {
console.error('Failed to clear download cache:', err);
throw err;
}
};
const clearTranscodeCache = () => {
const tmpDir = CACHE_DIR;
try {
if (!fs.existsSync(tmpDir)) return;
const files = fs.readdirSync(tmpDir);
for (const file of files) {
if (file.startsWith('hls-')) {
const filePath = path.join(tmpDir, file);
fs.rmSync(filePath, { recursive: true, force: true });
}
}
} catch (err) {
console.error('Failed to clear transcode cache:', err);
throw err;
}
};
app.get('/api/buckets', async (req, res) => {
@@ -573,6 +561,15 @@ app.get('/api/videos', async (req, res) => {
if (!key) return false;
const lowerKey = key.toLowerCase();
return videoExtensions.some(ext => lowerKey.endsWith(ext));
})
.map(key => {
const safeBucket = bucket.replace(/[^a-z0-9]/gi, '_');
const safeKeySegments = key.split('/').map(segment => segment.replace(/[^a-z0-9]/gi, '_'));
const hlsDir = path.join(CACHE_DIR, `hls-${safeBucket}-${safeKeySegments.join('-')}`);
return {
key: key,
hasTranscodeCache: fs.existsSync(hlsDir)
};
});
res.json({ videos });
@@ -622,22 +619,22 @@ app.get('/api/config', (req, res) => {
});
});
app.post('/api/clear-download-cache', (req, res) => {
app.post('/api/clear-video-transcode-cache', async (req, res) => {
try {
clearDownloadCache();
res.json({ message: 'Download cache cleared' });
} catch (error) {
console.error('Error clearing download cache:', error);
res.status(500).json({ error: 'Failed to clear download cache', detail: error.message });
}
});
const { bucket, key } = req.body;
if (!bucket || !key) {
return res.status(400).json({ error: 'Bucket and key are required' });
}
const safeBucket = bucket.replace(/[^a-z0-9]/gi, '_');
const safeKeySegments = key.split('/').map(segment => segment.replace(/[^a-z0-9]/gi, '_'));
const hlsDir = path.join(CACHE_DIR, `hls-${safeBucket}-${safeKeySegments.join('-')}`);
app.post('/api/clear-transcode-cache', (req, res) => {
try {
clearTranscodeCache();
res.json({ message: 'Transcode cache cleared' });
if (fs.existsSync(hlsDir)) {
fs.rmSync(hlsDir, { recursive: true, force: true });
}
res.json({ message: 'Transcode cache cleared for video' });
} catch (error) {
console.error('Error clearing transcode cache:', error);
console.error('Error clearing video transcode cache:', error);
res.status(500).json({ error: 'Failed to clear transcode cache', detail: error.message });
}
});