@charivo/tts
v0.6.7
Published
TTS manager and browser adapters for Charivo
Maintainers
Readme
@charivo/tts
Stateful TTS manager for Charivo.
This package coordinates a TTSPlayer, audio playback lifecycle, and lip-sync
events. It works with browser-native speech, remote TTS APIs, and direct OpenAI
players.
For "audio" playback mode, the manager analyzes the <audio> element it
creates from the generated bytes using the shared core lip-sync analyzer
(createLipSyncAnalyzer from @charivo/core) and emits tts:lipsync:update.
For "web-speech" mode, lip-sync is simulated from the spoken text instead —
there is no audio to analyze.
Concrete players should declare playbackMode ("audio" or "web-speech")
and can optionally declare audioMimeType so the manager does not need to rely
on constructor-name inference.
"audio" playback mode requires the player to implement generateAudio(),
since the manager needs the raw audio bytes to build the element it plays and
analyzes; createTTSManager(player) throws an explicit error if a player
declares "audio" mode without it. Players that only implement speak() (no
generateAudio(), e.g. the Web Speech API) must use "web-speech" mode
instead.
Install
pnpm add @charivo/ttsUsage
import { createTTSManager } from "@charivo/tts";
import { createRemoteTTSPlayer } from "@charivo/tts/remote";
const ttsManager = createTTSManager(
createRemoteTTSPlayer({ apiEndpoint: "/api/tts" }),
);
await ttsManager.speak("Hello", { voice: "marin" });Exports
createTTSManager(player)@charivo/tts/openai:createOpenAITTSPlayer(config)(browser player, dev/testing only) and, for server-side use,createOpenAITTSProvider(config),OpenAITTSProvider,type OpenAITTSConfig
Event Bridge
TTSManager accepts an emit-only event bridge through setEventEmitter(...).
It emits TTS lifecycle and lip-sync events back into core, but it does not
subscribe to upstream Charivo events.
When connected, the manager emits:
tts:audio:starttts:lipsync:updatetts:audio:end
Audio Lifecycle
stop()— stops active playback. If it interrupts an in-flightspeak()call, that call's promise settles as part of the stop instead of being left pending: a deliberate stop is treated as a cancellation, not a failure, so it resolves rather than rejects.prepareAudio?.()— creates the lip-syncAudioContextup front. Call it from a user-gesture handler before the firstspeak()so mobile browsers that require audio to start from a gesture do not block playback.dispose?.()— releases lip-sync audio resources and unsubscribes browser lifecycle listeners. Callstop()first if speech is in-flight;dispose()does not stop playback.Charivo.dispose()calls this automatically for an attached TTS manager — call it directly only if your app tears aTTSManagerdown outsideCharivo.dispose().
