Skip to content

Word timing ​

Every indexed word carries tStart, the second it is spoken inside the clip. This is what separates the index from a transcript dump, and it is the field most integrations are built on.

Where it comes from ​

Automatic captions arrive with per-word timing, not just per-line. The pipeline keeps that resolution: a caption line becomes a cue with t0 and t1, and each catalogue word inside it keeps its own tStart.

Accuracy ​

Timings are good to roughly a quarter of a second. That is accurate enough to seek to a word and hear it, and to highlight a cue in sync with playback. It is not accurate enough for phoneme-level alignment or for cutting audio at word boundaries.

Two practical consequences:

  • Seek slightly early. Math.floor(tStart) gives you the word plus a fraction of what came before it. Landing late clips the first sound.
  • Do not trust the gap between two words as a measurement of pause length.

Cue indexes are stable ​

captionIdx in a word occurrence points at a cue in GET /clips/{clipId}/transcript. Cue 7 stays cue 7, so you can cache the transcript and resolve occurrences against it without refetching.

Syncing captions to the player ​

Poll the player clock four to ten times a second and show the cue whose t0 and t1 bracket it. Higher polling rates buy nothing visible and cost battery; lower rates are noticeable on fast speech.

js
function activeCue(cues, time) {
	return cues.find((cue) => time >= cue.t0 && time < cue.t1)
}

A drift of 100 to 250 ms between the highlight and the audio is invisible to users. Chasing better than that is not worth the complexity.