export interface Clip { title: string; caption: string; file: string; startMs: number; endMs: number; narration: { path: string; durationMs: number } | null; } export function msToSrtTimestamp(ms: number): string { const clamped = Math.max(0, Math.round(ms)); const hours = Math.floor(clamped / 3_600_000); const minutes = Math.floor((clamped % 3_600_000) / 60_000); const seconds = Math.floor((clamped % 60_000) / 1000); const millis = clamped % 1000; const pad = (n: number, len = 2) => String(n).padStart(len, "0"); return `${pad(hours)}:${pad(minutes)}:${pad(seconds)},${pad(millis, 3)}`; } /** One subtitle cue per step, spanning its full on-screen duration. */ export function buildSrt(clips: Clip[]): string { return clips .map((clip, i) => { const index = i + 1; return [ String(index), `${msToSrtTimestamp(clip.startMs)} --> ${msToSrtTimestamp(clip.endMs)}`, clip.caption, "", ].join("\n"); }) .join("\n"); }