mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
fix(cli): assign w{index} ids when loading JSON transcripts (#3770)
loadTranscript assigns id: w{index} on the srt/vtt branches but never on
the JSON branches: parseWhisperCpp and parseOpenAI drop the field and the
words-json branch defaults it to "". Every engine funnels through
loadTranscript, and transcribeAudio rewrites transcript.json from its
output, so CLI-produced transcripts ship without the stable word ids that
transcribe.md documents for caption overrides — per-word overrides have
nothing to key on.
Assign id: w.id || `w{index}` across the JSON branches, matching the
srt/vtt behavior. || also repairs the empty-string ids older CLIs wrote
to words-json files, which otherwise collapse every word onto one key.
Signed-off-by: Santhi Prakash <b.santhiprakash@gmail.com>
This commit is contained in:
@@ -103,8 +103,8 @@ describe("loadTranscript", () => {
|
||||
const { words, format } = loadTranscript(path);
|
||||
expect(format).toBe("whisper-cpp");
|
||||
expect(words).toEqual([
|
||||
{ text: "Hello,", start: 0, end: 0.55 },
|
||||
{ text: "world.", start: 0.6, end: 1.25 },
|
||||
{ text: "Hello,", start: 0, end: 0.55, id: "w0" },
|
||||
{ text: "world.", start: 0.6, end: 1.25, id: "w1" },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -142,8 +142,8 @@ describe("loadTranscript", () => {
|
||||
const { words, format } = loadTranscript(path);
|
||||
expect(format).toBe("openai");
|
||||
expect(words).toEqual([
|
||||
{ text: "Hello", start: 0, end: 0.5 },
|
||||
{ text: "world", start: 0.6, end: 1.2 },
|
||||
{ text: "Hello", start: 0, end: 0.5, id: "w0" },
|
||||
{ text: "world", start: 0.6, end: 1.2, id: "w1" },
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -205,7 +205,7 @@ Short format
|
||||
expect(words[0]?.text).toBe("Bold and italic");
|
||||
});
|
||||
|
||||
it("passes through normalized word arrays", () => {
|
||||
it("assigns w{index} ids to normalized word arrays", () => {
|
||||
const input = [
|
||||
{ text: "Hello", start: 0.0, end: 0.5 },
|
||||
{ text: "world", start: 0.6, end: 1.2 },
|
||||
@@ -214,10 +214,21 @@ Short format
|
||||
const { words, format } = loadTranscript(path);
|
||||
expect(format).toBe("words-json");
|
||||
expect(words).toEqual([
|
||||
{ text: "Hello", start: 0, end: 0.5, id: "" },
|
||||
{ text: "world", start: 0.6, end: 1.2, id: "" },
|
||||
{ text: "Hello", start: 0, end: 0.5, id: "w0" },
|
||||
{ text: "world", start: 0.6, end: 1.2, id: "w1" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("preserves existing ids and repairs empty-string ids from legacy files", () => {
|
||||
const input = [
|
||||
{ text: "Hello", start: 0.0, end: 0.5, id: "keep-me" },
|
||||
{ text: "world", start: 0.6, end: 1.2, id: "" },
|
||||
{ text: "again", start: 1.3, end: 1.8 },
|
||||
];
|
||||
const path = tmpFile("legacy.json", JSON.stringify(input));
|
||||
const { words } = loadTranscript(path);
|
||||
expect(words.map((w) => w.id)).toEqual(["keep-me", "w1", "w2"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("caption formatting", () => {
|
||||
@@ -375,9 +386,9 @@ describe("whisper-cpp contraction merging", () => {
|
||||
);
|
||||
const { words } = loadTranscript(path);
|
||||
expect(words).toEqual([
|
||||
{ text: "I", start: 0, end: 0.2 },
|
||||
{ text: "didn't", start: 0.2, end: 0.7 },
|
||||
{ text: "know", start: 0.7, end: 1 },
|
||||
{ text: "I", start: 0, end: 0.2, id: "w0" },
|
||||
{ text: "didn't", start: 0.2, end: 0.7, id: "w1" },
|
||||
{ text: "know", start: 0.7, end: 1, id: "w2" },
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
@@ -503,17 +503,21 @@ export function loadTranscript(filePath: string): { words: Word[]; format: Trans
|
||||
const parsed = JSON.parse(content);
|
||||
const format = detectJsonFormat(parsed);
|
||||
|
||||
const words =
|
||||
// JSON parsers never set id — assign w{index} like the srt/vtt branches above
|
||||
// so caption overrides always have a stable key. `||` (not `??`) also repairs
|
||||
// the empty-string ids older CLIs wrote to words-json transcript files.
|
||||
const words = (
|
||||
format === "whisper-cpp"
|
||||
? parseWhisperCpp(parsed)
|
||||
: format === "openai"
|
||||
? parseOpenAI(parsed)
|
||||
: (parsed as Word[]).map((w) => ({
|
||||
id: w.id ?? "",
|
||||
id: w.id,
|
||||
text: w.text.trim(),
|
||||
start: round3(w.start),
|
||||
end: round3(w.end),
|
||||
}));
|
||||
}))
|
||||
).map((w, i) => ({ ...w, id: w.id || `w${i}` }));
|
||||
|
||||
return { words, format };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user