WebRTCOutput
Browser audio output provider that renders TTS audio into a WebRTC track.
Defined in: src/providers/output/WebRTCOutput.ts:170
Browser audio output provider that renders TTS audio into a WebRTC track.
Remarks
WebRTCOutput is a single-role provider ('output'). It decodes each enqueued AudioChunk into an AudioBuffer and schedules it as an AudioBufferSourceNode on a shared timeline (nextStartTime), so consecutive chunks play back-to-back without gaps. All sources connect to a MediaStreamAudioDestinationNode; the resulting track is exposed via getTrack() for the application to publish on its RTCPeerConnection.
Supported input formats (from configure() metadata or per-chunk metadata):
| Encoding | Handling |
|---|---|
linear16 | Raw PCM converted directly to an AudioBuffer |
mulaw / alaw | G.711-decoded to linear16, then as above |
mp3 / opus | Browser decodeAudioData() (complete frames only) |
Semantics mirror BrowserAudioOutput: flush() resolves once every enqueued chunk has finished playing into the track; stop() is barge-in — it halts all scheduled sources immediately and clears the queue; onPlaybackStart fires when audio begins after idle and onPlaybackEnd when the queue fully drains (or on stop).
The provider uses type: 'rest' because it holds no provider-managed network connection — the WebRTC transport belongs to the application.
Data-flow diagram:
enqueue(chunk) ──> queue ──decode──> AudioBuffer
|
schedule at nextStartTime
|
v
MediaStreamAudioDestinationNode
|
getTrack()
|
v
RTCPeerConnection (app-owned)
Example
import { CompositeVoice, WebRTCInput, DeepgramSTT, AnthropicLLM, DeepgramTTS, WebRTCOutput } from 'composite-voice';
const output = new WebRTCOutput();
const voice = new CompositeVoice({
providers: [
new WebRTCInput(),
new DeepgramSTT({ apiKey: '...' }),
new AnthropicLLM({ apiKey: '...', model: 'claude-haiku-4-5' }),
new DeepgramTTS({ apiKey: '...' }),
output,
],
});
await voice.initialize();
// Publish the agent's voice to the room
const pc = new RTCPeerConnection();
pc.addTrack(output.getTrack(), output.getStream());
output.onPlaybackStart(() => console.log('Agent speaking'));
output.onPlaybackEnd(() => console.log('Agent done'));
See
- WebRTCOutputConfig for configuration options
- WebRTCInput for the corresponding input provider
- AudioOutputProvider for the interface contract
Implements
Constructors
Constructor
new WebRTCOutput(config?): WebRTCOutput;
Defined in: src/providers/output/WebRTCOutput.ts:262
Creates a new WebRTCOutput instance.
Parameters
| Parameter | Type | Description |
|---|---|---|
config | WebRTCOutputConfig | Optional configuration. See WebRTCOutputConfig. |
Returns
WebRTCOutput
Remarks
Construction is side-effect free: the AudioContext and destination node are created in initialize(), so the track is only available after initialization.
Example
const output = new WebRTCOutput({ sampleRate: 48000 });
Properties
| Property | Modifier | Type | Default value | Description | Defined in |
|---|---|---|---|---|---|
roles | readonly | readonly ProviderRole[] | undefined | Pipeline roles covered by this provider. Remarks WebRTCOutput is a single-role provider covering only the 'output' slot. It requires a separate TTS provider for the 'tts' role. | src/providers/output/WebRTCOutput.ts:188 |
type | readonly | ProviderType | 'rest' | Communication type for this provider. Remarks 'rest' — the provider does not manage a persistent network connection. The WebRTC peer connection is owned by the application; this provider only produces a local MediaStreamTrack. | src/providers/output/WebRTCOutput.ts:179 |
Methods
configure()
configure(metadata): void;
Defined in: src/providers/output/WebRTCOutput.ts:362
Configure the output with audio format metadata from the TTS provider.
Parameters
| Parameter | Type | Description |
|---|---|---|
metadata | AudioMetadata | Format description for the incoming audio stream. |
Returns
void
Remarks
The metadata describes how enqueued chunks are decoded. All AudioEncoding values are accepted: linear16 (recommended), mulaw/alaw (G.711-decoded via the SDK’s codecs), and mp3/opus (decoded with the browser’s decodeAudioData, which requires complete frames — prefer linear16 TTS output for streaming, e.g. DeepgramTTS({ encoding: 'linear16', sampleRate: 24000 })).
See
Implementation of
dispose()
dispose(): Promise<void>;
Defined in: src/providers/output/WebRTCOutput.ts:315
Dispose of the provider and release all resources.
Returns
Promise<void>
Remarks
Stops playback, closes the AudioContext (which ends the destination track), and clears callbacks. Any track previously handed to a peer connection goes silent. The instance may be re-initialized, but a new track must then be fetched via getTrack() and re-published.
Implementation of
enqueue()
enqueue(chunk): void;
Defined in: src/providers/output/WebRTCOutput.ts:381
Enqueue an audio chunk for delivery into the WebRTC track.
Parameters
| Parameter | Type | Description |
|---|---|---|
chunk | AudioChunk | Audio data to deliver. |
Returns
void
Remarks
Chunks are decoded and scheduled gaplessly in enqueue order. Per-chunk metadata overrides the format set via configure(). Chunks enqueued before initialize() are dropped with a warning.
See
Implementation of
flush()
flush(): Promise<void>;
Defined in: src/providers/output/WebRTCOutput.ts:404
Wait for all enqueued audio to finish playing into the track.
Returns
Promise<void>
Remarks
Resolves once every scheduled AudioBufferSourceNode has ended and the queue is empty — i.e. everything enqueued has actually been delivered. Also resolves on stop() (barge-in cancels delivery). Resolves immediately when idle.
See
Implementation of
getStream()
getStream(): MediaStream;
Defined in: src/providers/output/WebRTCOutput.ts:585
Get the MediaStream containing the agent’s audio track.
Returns
MediaStream
The destination node’s stream.
Remarks
Some APIs (e.g. RTCPeerConnection.addTrack, LiveKit’s localParticipant.publishTrack) want the stream alongside the track.
Throws
InvalidStateError when called before initialize().
getTrack()
getTrack(): MediaStreamTrack;
Defined in: src/providers/output/WebRTCOutput.ts:561
Get the audio MediaStreamTrack carrying the agent’s voice.
Returns
MediaStreamTrack
The destination node’s audio track.
Remarks
Add this track to any RTCPeerConnection (or SFU SDK publish call) to make the agent audible to remote peers. The track is live for the lifetime of the provider and goes silent between agent turns.
Throws
InvalidStateError when called before initialize().
Example
pc.addTrack(output.getTrack(), output.getStream());
initialize()
initialize(): Promise<void>;
Defined in: src/providers/output/WebRTCOutput.ts:280
Initialize the provider, creating the AudioContext and destination track.
Returns
Promise<void>
Remarks
After this resolves, getTrack() and getStream() return the live track and stream to publish. If already initialized, this is a no-op.
Throws
ProviderInitializationError when the Web Audio API is not available in the current environment.
Implementation of
AudioOutputProvider.initialize
isPlaying()
isPlaying(): boolean;
Defined in: src/providers/output/WebRTCOutput.ts:491
Check whether audio is currently being delivered into the track.
Returns
boolean
true while scheduled audio is playing and not paused.
See
Implementation of
isReady()
isReady(): boolean;
Defined in: src/providers/output/WebRTCOutput.ts:341
Check whether the provider has been initialized.
Returns
boolean
true when initialize has completed and dispose has not yet been called.
Implementation of
onPlaybackEnd()
onPlaybackEnd(callback): void;
Defined in: src/providers/output/WebRTCOutput.ts:521
Register a callback invoked when the queue fully drains (or on stop).
Parameters
| Parameter | Type | Description |
|---|---|---|
callback | () => void | Function called when delivery ends. |
Returns
void
Remarks
Only one callback can be registered at a time; subsequent calls replace the previous callback.
See
AudioOutputProvider.onPlaybackEnd
Implementation of
AudioOutputProvider.onPlaybackEnd
onPlaybackError()
onPlaybackError(callback): void;
Defined in: src/providers/output/WebRTCOutput.ts:537
Register a callback invoked when a decode or playback error occurs.
Parameters
| Parameter | Type | Description |
|---|---|---|
callback | (error) => void | Function called with the error. |
Returns
void
Remarks
Only one callback can be registered at a time; subsequent calls replace the previous callback. A failing chunk is skipped; delivery continues with the next chunk.
See
AudioOutputProvider.onPlaybackError
Implementation of
AudioOutputProvider.onPlaybackError
onPlaybackStart()
onPlaybackStart(callback): void;
Defined in: src/providers/output/WebRTCOutput.ts:506
Register a callback invoked when audio delivery begins after being idle.
Parameters
| Parameter | Type | Description |
|---|---|---|
callback | () => void | Function called when delivery starts. |
Returns
void
Remarks
Only one callback can be registered at a time; subsequent calls replace the previous callback.
See
AudioOutputProvider.onPlaybackStart
Implementation of
AudioOutputProvider.onPlaybackStart
pause()
pause(): void;
Defined in: src/providers/output/WebRTCOutput.ts:464
Temporarily pause delivery by suspending the AudioContext.
Returns
void
Remarks
While suspended, the destination track emits silence and scheduled sources hold their position. Resume with resume().
See
Implementation of
resume()
resume(): void;
Defined in: src/providers/output/WebRTCOutput.ts:477
Resume delivery after a pause.
Returns
void
See
Implementation of
stop()
stop(): void;
Defined in: src/providers/output/WebRTCOutput.ts:424
Stop delivery immediately and clear all buffered audio (barge-in).
Returns
void
Remarks
Halts every scheduled source, clears the pending queue, resets the scheduling timeline, resolves pending flush() promises, and fires onPlaybackEnd if audio was playing. The configured metadata is retained so subsequent chunks (e.g. the next agent turn) play without re-configuration.