Skip to main content

Word timings

final result = await tts.generate('Highlight this sentence as it plays.');

for (final timing in result.wordTimings) {
print('${timing.word}: ${timing.startTime}${timing.endTime}');
}

Start the UI timer when playback actually begins:

await tts.play(
result,
AudioPlayOptions(
onPlaybackStart: () {
final startedAt = DateTime.now();
timer = Timer.periodic(const Duration(milliseconds: 50), (_) {
final seconds =
DateTime.now().difference(startedAt).inMilliseconds / 1000;
final active = result.wordTimings
.where((word) => seconds >= word.startTime && seconds < word.endTime)
.firstOrNull;
setActiveWordIndex(active?.wordIndex);
});
},
),
);

Timings are inferred from predicted phoneme duration output. They are designed for read-aloud UI, not forensic forced alignment.

  • Prefer sentences and short paragraphs.
  • Treat indexes as local to the current result.
  • Timings can be empty when duration output is unavailable.
  • Use stream() for long input and switch highlighting data per chunk.