eldouma-graphics / src /lib /export-formats.ts
Moeeldouma's picture
Deploy Eldouma Graphics — Docker Space, bring-your-own-key demo
39d98a0 verified
Raw
History Blame Contribute Delete
1.53 kB
import { buildCaptionWords, buildCaptionLines, type CaptionLine } from "./captions";
import type { EDLItem, Word } from "./timeline-model";
const pad = (n: number, w = 2) => String(n).padStart(w, "0");
// HH:MM:SS,mmm (SRT, comma) or HH:MM:SS.mmm (VTT, dot)
const clock = (ms: number, sep: "," | ".") => {
const t = Math.max(0, Math.round(ms));
const h = Math.floor(t / 3600000), m = Math.floor((t % 3600000) / 60000), s = Math.floor((t % 60000) / 1000);
return `${pad(h)}:${pad(m)}:${pad(s)}${sep}${pad(t % 1000, 3)}`;
};
export const captionLinesFor = (edl: EDLItem[], wordsById: Record<string, Word>): CaptionLine[] =>
buildCaptionLines(buildCaptionWords(edl, wordsById));
const lineText = (l: CaptionLine) => l.words.map((w) => w.text).join(" ").trim();
export function toSRT(lines: CaptionLine[]): string {
return lines.filter(lineText).map((l, i) =>
`${i + 1}\n${clock(l.startMs, ",")} --> ${clock(l.endMs, ",")}\n${lineText(l)}`
).join("\n\n") + "\n";
}
export function toVTT(lines: CaptionLine[]): string {
return "WEBVTT\n\n" + lines.filter(lineText).map((l) =>
`${clock(l.startMs, ".")} --> ${clock(l.endMs, ".")}\n${lineText(l)}`
).join("\n\n") + "\n";
}
export function downloadFile(name: string, content: BlobPart, type: string) {
const url = URL.createObjectURL(new Blob([content], { type }));
const a = document.createElement("a");
a.href = url; a.download = name;
document.body.appendChild(a); a.click(); a.remove();
setTimeout(() => URL.revokeObjectURL(url), 1000);
}