feat(subtitles): refine dialogue-focused subtitle generation

- Split long speech at quiet pauses with overlapping context
- Stitch overlapping cues without merging repeated dialogue
- Clarify dialogue controls and hide the sidebar button when cues load
This commit is contained in:
2026-09-07 23:28:32 -07:00
parent 2d623838d5
commit 773664db78
17 changed files with 251 additions and 27 deletions
@@ -0,0 +1,35 @@
import { runSubtitleGenerationProcess } from './subtitle-generation-process';
// Each completed silencedetect line contains both the end and duration of a quiet interval.
export async function findSpeechPauses(input: {
ffmpegPath: string;
wavPath: string;
signal?: AbortSignal;
}): Promise<number[]> {
const pauses: number[] = [];
await runSubtitleGenerationProcess({
command: input.ffmpegPath.trim() || 'ffmpeg',
args: [
'-nostdin',
'-hide_banner',
'-nostats',
'-i',
input.wavPath,
'-af',
'silencedetect=noise=-35dB:d=0.12',
'-f',
'null',
'-',
],
signal: input.signal,
onLine: (line) => {
const match = /silence_end: (\S+) \| silence_duration: (\S+)/.exec(line);
if (!match) return;
const end = Number(match[1]);
const duration = Number(match[2]);
if (Number.isFinite(end) && Number.isFinite(duration) && duration > 0 && end >= duration)
pauses.push(end - duration / 2);
},
});
return pauses.sort((a, b) => a - b);
}