(filePath: string)
| 446 | * - Pre-normalized JSON array ([{text, start, end}]) |
| 447 | */ |
| 448 | export function loadTranscript(filePath: string): { words: Word[]; format: TranscriptFormat } { |
| 449 | const ext = extname(filePath).toLowerCase(); |
| 450 | const content = readFileSync(filePath, "utf-8"); |
| 451 | |
| 452 | if (ext === ".srt") { |
| 453 | const words = parseSrt(content).map((w, i) => ({ ...w, id: w.id ?? `w${i}` })); |
| 454 | return { words, format: "srt" }; |
| 455 | } |
| 456 | if (ext === ".vtt") { |
| 457 | const words = parseVtt(content).map((w, i) => ({ ...w, id: w.id ?? `w${i}` })); |
| 458 | return { words, format: "vtt" }; |
| 459 | } |
| 460 | |
| 461 | // JSON formats — parse once, detect, then extract words |
| 462 | const parsed = JSON.parse(content); |
| 463 | const format = detectJsonFormat(parsed); |
| 464 | |
| 465 | const words = |
| 466 | format === "whisper-cpp" |
| 467 | ? parseWhisperCpp(parsed) |
| 468 | : format === "openai" |
| 469 | ? parseOpenAI(parsed) |
| 470 | : (parsed as Word[]).map((w) => ({ |
| 471 | id: w.id ?? "", |
| 472 | text: w.text.trim(), |
| 473 | start: round3(w.start), |
| 474 | end: round3(w.end), |
| 475 | })); |
| 476 | |
| 477 | return { words, format }; |
| 478 | } |
| 479 | |
| 480 | /** |
| 481 | * Remove words that fall before the detected speech onset. |
no test coverage detected