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.