Skip to content

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):

EncodingHandling
linear16Raw PCM converted directly to an AudioBuffer
mulaw / alawG.711-decoded to linear16, then as above
mp3 / opusBrowser 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

Implements

Constructors

Constructor

new WebRTCOutput(config?): WebRTCOutput;

Defined in: src/providers/output/WebRTCOutput.ts:262

Creates a new WebRTCOutput instance.

Parameters

ParameterTypeDescription
configWebRTCOutputConfigOptional 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

PropertyModifierTypeDefault valueDescriptionDefined in
rolesreadonlyreadonly ProviderRole[]undefinedPipeline 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
typereadonlyProviderType'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

ParameterTypeDescription
metadataAudioMetadataFormat 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

AudioOutputProvider.configure

Implementation of

AudioOutputProvider.configure


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

AudioOutputProvider.dispose


enqueue()

enqueue(chunk): void;

Defined in: src/providers/output/WebRTCOutput.ts:381

Enqueue an audio chunk for delivery into the WebRTC track.

Parameters

ParameterTypeDescription
chunkAudioChunkAudio 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

AudioOutputProvider.enqueue

Implementation of

AudioOutputProvider.enqueue


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

AudioOutputProvider.flush

Implementation of

AudioOutputProvider.flush


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

AudioOutputProvider.isPlaying

Implementation of

AudioOutputProvider.isPlaying


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

AudioOutputProvider.isReady


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

ParameterTypeDescription
callback() => voidFunction 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

ParameterTypeDescription
callback(error) => voidFunction 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

ParameterTypeDescription
callback() => voidFunction 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

AudioOutputProvider.pause

Implementation of

AudioOutputProvider.pause


resume()

resume(): void;

Defined in: src/providers/output/WebRTCOutput.ts:477

Resume delivery after a pause.

Returns

void

See

Implementation of

AudioOutputProvider.resume


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.

See

AudioOutputProvider.stop

Implementation of

AudioOutputProvider.stop

© 2026 CompositeVoice. All rights reserved.

Font size
Contrast
Motion
Transparency