Skip to main content

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
Use streaming TTS when:
  • 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
Use batch TTS when:
  • 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
Accepts the same options as createTTS(). See Text-to-Speech for details.
Streaming vs Batch Engines:
  • Use createStreamingTTS() for streaming generation (generateSpeechStream)
  • Use createTTS() for batch generation (generateSpeech, generateSpeechWithTimestamps)
They share the same native TTS instance but provide different JS interfaces.

StreamingTtsEngine: generateSpeechStream(text, options, handlers)

Starts streaming generation with chunk callbacks.
Parameters:
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 scale
  • referenceAudio: Reference audio for voice cloning (Pocket; not supported for Zipvoice streaming)
  • referenceText: Transcript of reference audio
  • numSteps: Flow-matching steps
  • extra: Model-specific options
TtsStreamHandlers
required
Callbacks for chunks, completion, and errors:
  • onChunk?: (chunk: TtsStreamChunk) => void
  • onEnd?: (event: TtsStreamEnd) => void
  • onError?: (event: TtsStreamError) => void
Returns: Promise<TtsStreamController> - Controller to cancel or unsubscribe.
Only one stream per engine can be active at a time. Starting another stream before the first finishes will reject with TTS_STREAM_ERROR.

TtsStreamHandlers

Callbacks for streaming events.

onChunk(chunk)

Called for each generated audio chunk.
TtsStreamChunk:
Keep onChunk lightweight. Forward audio to native playback quickly. Heavy processing can cause stuttering.

onEnd(event)

Called when generation finishes or is cancelled. Listeners are auto-removed after this.
TtsStreamEnd:

onError(event)

Called on generation errors. Listeners are auto-removed after this.
TtsStreamError:

TtsStreamController

Returned by generateSpeechStream(). Use to cancel or unsubscribe.
Methods:
  • cancel(): Stops generation and removes event listeners
  • unsubscribe(): 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 from onChunk.
writePcmChunk() expects float PCM samples in [-1.0, 1.0]. Values outside this range will clip.

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)

Zipvoice does not support streaming with voice cloning. Use batch mode (createTTS() + generateSpeech()) for voice cloning with Zipvoice.

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:
Memory Warning: Accumulating very long audio in JS can exhaust memory. For very long texts, consider:
  • Saving chunks incrementally to native storage
  • Splitting long texts into smaller segments
  • Using batch mode with file output

Performance Tips

Reduce Latency

  1. Use native PCM player (avoid JS audio bridge overhead)
  2. Keep onChunk lightweight (no heavy processing)
  3. Increase numThreads for faster generation
  4. Use hardware acceleration when available

Balance Chunk Size

The maxNumSentences 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

Only one stream per engine can be active. Wait for the previous stream to finish or cancel it:
  • Keep onChunk lightweight (avoid heavy processing)
  • Use native PCM player instead of JS audio APIs
  • Increase numThreads for faster generation
  • Reduce audio bridge overhead by writing larger chunks
  • Use hardware acceleration (provider: 'coreml' on iOS)
  • Increase numThreads
  • Reduce maxNumSentences for smaller chunks
  • Don’t accumulate all chunks in JS
  • Split long texts into smaller requests
  • Use batch mode for very long texts
  • 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