Files
ratatoskr/docs
vh 9041f1f402 fix: Web Audio streaming playback — fixes Safari NotSupportedError
Operator confirmed the "TTS blocked" was NotSupportedError on Safari — WebKit refuses a
streaming 0xFFFFFFFF-length WAV via <audio src> (can't compute duration/seek), exactly
as infra-ops warned. Replaced the <audio src> playback with a Web Audio path that works
in all engines:

- speakOnDone: fetch the chunked /api/tts stream, skip the WAV header to the data chunk,
  decode int16 LE PCM -> Float32, and schedule the samples GAPLESSLY into an AudioContext
  as they arrive (BufferSource per chunk, playAt += buf.duration). Progressive, TTFA
  ~0.5s. Decoding the raw PCM ourselves sidesteps every WAV-container quirk.
- unlock: an AudioContext starts suspended; Safari + Chrome need resume() from a user
  gesture. _unlockTtsAudio() now resumes the ctx on the first interaction anywhere +
  toggle-on + submit, so it's running before the ~15s-delayed speak-on-done.
- cancelTts: aborts the fetch + stops all scheduled BufferSource nodes.

Validated in Chromium (Playwright, strict autoplay): 43 nodes scheduled, 5.1s of PCM
decoded, ctx "running" 6.5s post-gesture, zero errors. Headless WebKit can't launch here
(missing system libs — an infra-ops install), so the operator's live Safari is the final
check; the code is standard Web Audio Safari has supported for years.

Contract FN client:speakOnDone updated (Web Audio; the Safari NotSupportedError reason).
2026-08-02 07:21:48 -07:00
..