demo · v133

WebAudio + media element routing

A WebAudio oscillator, a sample player, and an HTML <audio> sharing one preferred sink. Switch sinks once and every audio renderer in the document follows — without rebuilding the graph or per-element setSinkId.

1 · WebAudio oscillator

2 · sample player (decoded buffer)

3 · HTML <audio> element

All three sources are routed through the document-wide preferred sink. No per-source plumbing required.

why a document-level preference matters

Before setPreferredSinkId, every audio renderer had to be addressed individually: each <audio> got a setSinkId, each AudioContext needed to be constructed with { sinkId } (or its sink replaced via AudioContext.setSinkId). Adding a new renderer halfway through a session meant remembering to apply the right sink. navigator.mediaDevices.setPreferredSinkId(id) now sets the default for the whole document — cross-origin iframes included — so renderers can be created without thinking about routing, and switching devices is one call away.

const sinkId = await chooseDevice();
await navigator.mediaDevices.setPreferredSinkId(sinkId);

// these all inherit the preference, no per-renderer wiring:
new AudioContext();
new Audio(url).play();
document.querySelector("iframe").src = "/embedded-player";

see also