#!/usr/bin/env node // E2E fake whisper-cli. Mimics the args runWhisperBatch passes: // whisper-cli -ojf -l en -m -of // Writes .json next to cwd (which runWhisperBatch sets to the // video dir). Format matches what common/lib/whisper.ts parses. import { writeFile } from "node:fs/promises"; import { installFixtureWatchdog } from "./_watchdog.mjs"; // Never outlive the run that spawned us — see _watchdog.mjs. installFixtureWatchdog(); const argv = process.argv.slice(2); function arg(flag) { const i = argv.indexOf(flag); return i < 0 ? undefined : argv[i + 1]; } const tmpBase = arg("-of"); const audio = argv[argv.length - 1]; if (!tmpBase) { process.stderr.write(`[fake-whisper] missing -of\n`); process.exit(2); } const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const pad = (n) => String(n).padStart(2, "0"); const clock = (s) => `00:${pad(Math.floor(s / 60))}:${pad(s % 60)}.000`; // Videos whose dir (== video id) contains the SLOWOP marker emit whisper-style // progress output with real delays, so the per-operation progress bars and // drain (soft-cancel) behaviour can be observed on the Active Jobs screen. // Videos without the marker stay instant so the rest of the suite is fast. if (process.cwd().toLowerCase().includes("slowop")) { const totalSec = 50; process.stdout.write( `main: processing '${audio}' (800000 samples, ${totalSec}.0 sec), 4 threads, 1 processors, 5 beams + best of 5, lang = en, task = transcribe, timestamps = 1 ...\n`, ); for (let t = 5; t <= totalSec; t += 5) { process.stdout.write( `[${clock(t - 5)} --> ${clock(t)}] slow whisper segment ${t}\n`, ); await sleep(700); } } const doc = { systeminfo: "fake", model: { type: "fake" }, result: { language: "en" }, transcription: [ { offsets: { from: 0, to: 5000 }, text: `Synthetic whisper output for ${audio} #1`, }, { offsets: { from: 5000, to: 10000 }, text: `Synthetic whisper output for ${audio} #2`, }, ], }; const outPath = `${tmpBase}.json`; await writeFile(outPath, JSON.stringify(doc)); process.stdout.write(`[fake-whisper] wrote ${outPath}\n`);