demo · v135

Per-participant captions in one tab

The intent-to-ship calls out video conferencing as the killer use case: a single tab receives multiple MediaStreamTracks — one per participant from a RTCPeerConnection — and now each track can drive its own independent SpeechRecognition instance. Before this overload, the API only ever read the default mic, so multi-speaker captioning required round-tripping audio off-device.

SR + track overload: ?

track #1

Alice (real mic)
track not started
awaiting audio…

track #2

Bob (Web Audio routed track)
track not started
awaiting audio…

Bob is not a timer: this demo routes the same microphone through a MediaStreamDestination to create a second real MediaStreamTrack, then starts a second recognizer with that track. In production this is where an RTCPeerConnection remote track would be passed.

the code

// One SpeechRecognition per remote track, fed the track directly.
peer.ontrack = (e) => {
  const rec = new SpeechRecognition();
  rec.continuous = true;
  rec.interimResults = true;
  rec.onresult = (ev) => renderCaptionsFor(e.track.id, ev);
  rec.start(e.track);             // NEW in Chrome 135
};

// This demo creates a second real track from Web Audio so the pattern
// works without a live peer connection.
const destination = audioContext.createMediaStreamDestination();
micSource.connect(destination);
secondRecognizer.start(destination.stream.getAudioTracks()[0]);

see also