Skip to main content

Word timings

Each KittenTTSResult can include model-predicted timings:

type KittenWordTiming = {
wordIndex: number;
word: string;
startTime: number;
endTime: number;
};
const result = await tts.generate('Highlight these words as they play.');

await tts.play(result, {
onPlaybackStart: () => {
const startedAt = Date.now();
const timer = setInterval(() => {
const seconds = (Date.now() - startedAt) / 1000;
const active = result.wordTimings.find(
word => seconds >= word.startTime && seconds < word.endTime,
);
setActiveWordIndex(active?.wordIndex ?? null);
}, 50);
},
});

Accuracy and scope

Timings come from predicted phoneme durations. They are useful for read-aloud highlighting but are not forced alignment.

  • Generate one sentence or short paragraph for the most stable mapping.
  • wordIndex is local to the generated result.
  • Timings may be empty if the model did not return duration data.
  • Timings may be unavailable when input is split across multiple inference chunks.
  • Start clocks from actual playback, not from generation completion.

For long content, use generateStreaming() and update highlighting separately for each yielded result.