Output, emit samples alongside frames,
and the runtime handles encoding, transport, and synchronization.
Declaring an audio track
emit(). When a tick produces no audio,
send an empty array rather than omitting the field:
Audio format
The runtime encodes to Opus for transport. 48 kHz is the Opus native rate, so audio already at 48
kHz needs no resampling.
Custom sample rates
If your model generates at a different rate, subclassAudio and declare it:
Keeping audio and video in sync
When you emit an output carrying both tracks, the runtime keeps them aligned. If the video payload is a batch, the audio is split proportionally across those frames. The rule that follows: each emit should carry the audio that belongs to its video. At 30 fps, one video frame is48000 / 30 = 1600 samples, so a batch of 3 frames should carry about 4,800
samples (100 ms).
Emitting a frame’s worth of video with a second’s worth of audio will drift, however well the
transport behaves.
Rate-matching two streams
Models whose audio and video come from separate producers need to pair them before emitting. Buffer whichever stream runs ahead, and emit only when both have material for the same span:Reading audio from the client
Inbound audio arrives as(1, samples) int16 at 48 kHz, read the same way as video but in FIFO
order so no samples are dropped:
Next
Media Input
Read the client’s camera and microphone.
Recording
Capture the model’s output into downloadable clips.