MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / wordsToCues

Function wordsToCues

packages/cli/src/whisper/normalize.ts:367–403  ·  view source on GitHub ↗
(words: Word[], opts: WordsToCuesOptions = {})

Source from the content-addressed store, hash-verified

365}
366
367export function wordsToCues(words: Word[], opts: WordsToCuesOptions = {}): Cue[] {
368 // Phrase-level transcripts (imported .srt/.vtt cues) must keep their existing
369 // cue boundaries — re-grouping would merge distinct captions and lose timing.
370 // The caller can force this via `preGrouped`; otherwise infer it from the data
371 // (any entry containing internal whitespace is a multi-word phrase, so the
372 // whole transcript is phrase-level rather than word-level whisper output).
373 const preGrouped = opts.preGrouped ?? words.some((w) => /\s/.test(w.text.trim()));
374 if (preGrouped) return entriesToCues(words);
375
376 const maxChars = opts.maxChars ?? 42;
377 const maxGap = opts.maxGap ?? 0.8;
378 const cues: Cue[] = [];
379 let current: Cue | undefined;
380
381 const flush = (): void => {
382 pushCue(cues, current);
383 current = undefined;
384 };
385
386 for (const word of words) {
387 const text = word.text.trim();
388 if (!text) continue;
389
390 if (current && !breaksCue(current, word, text, maxChars, maxGap)) {
391 current.text = joinTokens(current.text, text);
392 current.end = word.end;
393 } else {
394 flush();
395 current = { text, start: word.start, end: word.end };
396 }
397
398 if (endsSentence(text)) flush();
399 }
400
401 flush();
402 return cues;
403}
404
405export function formatSrt(words: Word[], opts?: WordsToCuesOptions): string {
406 const cues = wordsToCues(words, opts);

Callers 3

formatSrtFunction · 0.85
formatVttFunction · 0.85
normalize.test.tsFile · 0.85

Calls 5

entriesToCuesFunction · 0.85
breaksCueFunction · 0.85
joinTokensFunction · 0.85
endsSentenceFunction · 0.85
flushFunction · 0.70

Tested by

no test coverage detected