This commit is contained in:
legop3
2026-04-28 02:08:32 -04:00
parent 07b1e8bd86
commit 76e966abec
+33 -42
View File
@@ -90,8 +90,6 @@ function listDesiredSources() {
function buildWorkerArgs(source) { function buildWorkerArgs(source) {
const dir = sourceDirForKey(sourceKey(source)); const dir = sourceDirForKey(sourceKey(source));
const pattern = path.join(dir, 'seg-%06d.mp4'); const pattern = path.join(dir, 'seg-%06d.mp4');
const listPath = path.join(dir, 'index.csv');
const listSize = Math.ceil((BUFFER_SECONDS + 10) / SEGMENT_SECONDS);
const common = [ const common = [
'-hide_banner', '-hide_banner',
@@ -115,7 +113,7 @@ function buildWorkerArgs(source) {
'-ar', '-ar',
'48000', '48000',
'-af', '-af',
'aresample=48000', 'aresample=async=1:first_pts=0:min_hard_comp=0.100000,asetpts=N/SR/TB',
'-c:a', '-c:a',
'aac', 'aac',
'-b:a', '-b:a',
@@ -126,14 +124,6 @@ function buildWorkerArgs(source) {
String(SEGMENT_SECONDS), String(SEGMENT_SECONDS),
'-segment_atclocktime', '-segment_atclocktime',
'1', '1',
'-segment_list',
listPath,
'-segment_list_type',
'csv',
'-segment_list_size',
String(listSize),
'-segment_list_flags',
'+live',
'-reset_timestamps', '-reset_timestamps',
'1', '1',
pattern, pattern,
@@ -165,14 +155,6 @@ function buildWorkerArgs(source) {
String(SEGMENT_SECONDS), String(SEGMENT_SECONDS),
'-segment_atclocktime', '-segment_atclocktime',
'1', '1',
'-segment_list',
listPath,
'-segment_list_type',
'csv',
'-segment_list_size',
String(listSize),
'-segment_list_flags',
'+live',
'-reset_timestamps', '-reset_timestamps',
'1', '1',
pattern, pattern,
@@ -249,37 +231,50 @@ async function syncWorkers() {
} }
} }
function parseCsvLine(line) { async function probeDurationSec(filePath) {
const trimmed = String(line || '').trim(); try {
if (!trimmed) return null; const { stdout } = await execFileAsync('ffprobe', [
const parts = trimmed.split(','); '-v',
if (parts.length < 3) return null; 'error',
return { '-show_entries',
filename: parts[0], 'format=duration',
startSec: Number(parts[1]), '-of',
endSec: Number(parts[2]), 'default=noprint_wrappers=1:nokey=1',
}; filePath,
]);
const value = Number(String(stdout || '').trim());
if (Number.isFinite(value) && value > 0 && value < SEGMENT_SECONDS * 10) {
return value;
}
} catch {
// ignore probe failures; fallback below
}
return SEGMENT_SECONDS;
} }
async function refreshIndexForWorker(worker) { async function refreshIndexForWorker(worker) {
const key = worker.key; const key = worker.key;
const dir = sourceDirForKey(key); const dir = sourceDirForKey(key);
const csvPath = path.join(dir, 'index.csv'); let files;
let csv;
try { try {
csv = await fsp.readFile(csvPath, 'utf8'); files = await fsp.readdir(dir, { withFileTypes: true });
} catch { } catch {
return; return;
} }
const lines = csv.split(/\r?\n/).map(parseCsvLine).filter(Boolean); const segmentFiles = files
if (!lines.length) return; .filter((entry) => entry.isFile() && /^seg-\d{6}\.mp4$/.test(entry.name))
.map((entry) => entry.name)
.sort();
if (!segmentFiles.length) {
segmentIndex.set(key, []);
return;
}
const cutoffMs = Date.now() - BUFFER_SECONDS * 1000 - 5000; const cutoffMs = Date.now() - BUFFER_SECONDS * 1000 - 5000;
const entries = []; const entries = [];
for (const row of lines) { for (const filename of segmentFiles) {
if (!Number.isFinite(row.startSec) || !Number.isFinite(row.endSec)) continue; const filePath = path.join(dir, filename);
const filePath = path.join(dir, row.filename);
let stat; let stat;
try { try {
stat = await fsp.stat(filePath); stat = await fsp.stat(filePath);
@@ -287,11 +282,7 @@ async function refreshIndexForWorker(worker) {
continue; continue;
} }
if (!stat.isFile() || stat.size < 4096) continue; if (!stat.isFile() || stat.size < 4096) continue;
const durSecRaw = row.endSec - row.startSec; const durationSec = await probeDurationSec(filePath);
const durationSec =
Number.isFinite(durSecRaw) && durSecRaw > 0 && durSecRaw < SEGMENT_SECONDS * 6
? durSecRaw
: SEGMENT_SECONDS;
const endMs = Math.round(stat.mtimeMs); const endMs = Math.round(stat.mtimeMs);
const startMs = Math.round(endMs - durationSec * 1000); const startMs = Math.round(endMs - durationSec * 1000);
if (endMs < cutoffMs) continue; if (endMs < cutoffMs) continue;