Overview
Streaming TTS generates speech incrementally, emitting audio chunks as they are produced. This enables:- Lower latency: Start playing audio before generation completes
- Real-time playback: Play while generating for interactive experiences
- Progress tracking: Show generation progress to users
- Memory efficiency: Process long texts without loading all audio into memory
- You need low time-to-first-audio
- You’re building interactive voice assistants
- You want to play audio while it’s being generated
- You’re processing very long texts
- You need the complete audio buffer
- You’re saving to files
- You need timestamps (use
generateSpeechWithTimestamps) - Voice cloning with Zipvoice (streaming + voice cloning not supported for Zipvoice)
Quick Start
API Reference
createStreamingTTS(options)
Creates a streaming TTS engine.src/tts/streaming.ts
createTTS(). See Text-to-Speech for details.
Streaming vs Batch Engines:
- Use
createStreamingTTS()for streaming generation (generateSpeechStream) - Use
createTTS()for batch generation (generateSpeech,generateSpeechWithTimestamps)
StreamingTtsEngine: generateSpeechStream(text, options, handlers)
Starts streaming generation with chunk callbacks.string
required
Text to synthesize.
TtsGenerationOptions
Generation options (same as batch TTS):
sid: Speaker ID (default: 0)speed: Speech speed multiplier (default: 1.0)silenceScale: Silence scalereferenceAudio: Reference audio for voice cloning (Pocket; not supported for Zipvoice streaming)referenceText: Transcript of reference audionumSteps: Flow-matching stepsextra: Model-specific options
TtsStreamHandlers
required
Callbacks for chunks, completion, and errors:
onChunk?: (chunk: TtsStreamChunk) => voidonEnd?: (event: TtsStreamEnd) => voidonError?: (event: TtsStreamError) => void
Promise<TtsStreamController> - Controller to cancel or unsubscribe.
TtsStreamHandlers
Callbacks for streaming events.onChunk(chunk)
Called for each generated audio chunk.onEnd(event)
Called when generation finishes or is cancelled. Listeners are auto-removed after this.onError(event)
Called on generation errors. Listeners are auto-removed after this.TtsStreamController
Returned bygenerateSpeechStream(). Use to cancel or unsubscribe.
cancel(): Stops generation and removes event listenersunsubscribe(): Removes event listeners only (call after completion if you didn’t wait for end/error)
Listeners are automatically removed when
onEnd or onError is called. Call unsubscribe() manually only if you discard the controller early (e.g., navigation away).StreamingTtsEngine: cancelSpeechStream()
Cancel the currently active stream.Native PCM Player
The SDK provides a native PCM player for low-latency audio playback.startPcmPlayer(sampleRate, channels)
Start the native PCM player.writePcmChunk(samples)
Write PCM samples to the player. Call fromonChunk.
stopPcmPlayer()
Stop and release the PCM player.Complete Example: Streaming with Native Playback
Voice Cloning with Streaming
Pocket TTS (Supported)
Pocket TTS supports streaming with voice cloning:Zipvoice (Not Supported)
Multiple Requests
Only one stream can be active per engine at a time.Sequential Requests
Wait for the previous stream to finish:Concurrent Requests (Multiple Engines)
Create multiple engines for concurrent streams:Cancellation
Cancel via Controller
Cancel via Engine
Recording Streamed Audio
Accumulate chunks to save the complete audio:Performance Tips
Reduce Latency
- Use native PCM player (avoid JS audio bridge overhead)
- Keep onChunk lightweight (no heavy processing)
- Increase numThreads for faster generation
- Use hardware acceleration when available
Balance Chunk Size
ThemaxNumSentences option controls chunk size:
- Smaller chunks (1 sentence): Lower latency, more callbacks
- Larger chunks (2+ sentences): Higher latency, fewer callbacks
Avoid Memory Issues
- Don’t accumulate all chunks for very long sessions
- Use native-side streaming-to-file if possible
- Split long texts into smaller generation requests
Common Use Cases
Voice Assistant
Progress Indicator
Text-to-Speech Button with Cancel
Troubleshooting
Error: TTS_STREAM_ERROR (another stream active)
Error: TTS_STREAM_ERROR (another stream active)
Only one stream per engine can be active. Wait for the previous stream to finish or cancel it:
Audio stuttering or choppy
Audio stuttering or choppy
- Keep
onChunklightweight (avoid heavy processing) - Use native PCM player instead of JS audio APIs
- Increase
numThreadsfor faster generation - Reduce audio bridge overhead by writing larger chunks
High latency (slow time-to-first-audio)
High latency (slow time-to-first-audio)
- Use hardware acceleration (
provider: 'coreml'on iOS) - Increase
numThreads - Reduce
maxNumSentencesfor smaller chunks
Out of memory with long texts
Out of memory with long texts
- Don’t accumulate all chunks in JS
- Split long texts into smaller requests
- Use batch mode for very long texts
Voice cloning not working in streaming
Voice cloning not working in streaming
- Pocket TTS: Voice cloning is supported in streaming
- Zipvoice: Voice cloning is not supported in streaming; use batch mode (
createTTS()+generateSpeech())
Next Steps
Text-to-Speech
Batch TTS generation and configuration
Model Setup
Learn how to bundle and load models
Speech-to-Text
Transcribe audio to text
Streaming STT
Real-time speech recognition