files/en-us/web/api/audiocontext/setsinkid/index.md
{{APIRef("Web Audio API")}}{{SeeCompatTable}}{{SecureContext_Header}}
The setSinkId() method of the {{domxref("AudioContext")}} interface sets the output audio device for the AudioContext. If a sink ID is not explicitly set, the default system audio output device will be used.
To set the audio device to a device different than the default one, the developer needs permission to access to audio devices. If required, the user can be prompted to grant the required permission via a {{domxref("MediaDevices.getUserMedia()")}} call.
In addition, this feature may be blocked by a speaker-selection Permissions Policy.
setSinkId(sinkId)
sinkId
deviceId property of the {{domxref("MediaDeviceInfo")}} objects returned by {{domxref("MediaDevices.enumerateDevices()")}}.AudioSinkOptions
type, with a value of none. Setting this parameter causes the audio to be processed without being played through any audio output device. This is a useful option to minimize power consumption when you don't need playback along with processing.A {{jsxref("Promise")}} that fulfills with a value of undefined.
Attempting to set the sink ID to its existing value (i.e., returned by {{domxref("AudioContext.sinkId")}}), throws no errors, but it aborts the process immediately.
InvalidAccessError {{domxref("DOMException")}}
NotAllowedError {{domxref("DOMException")}}
NotFoundError {{domxref("DOMException")}}
sinkId does not match any audio device found on the system.In our SetSinkId test example (check out the source code), we create an audio graph that generates a three-second burst of white noise via an {{domxref("AudioBufferSourceNode")}}, which we also run through a {{domxref("GainNode")}} to quiet things down a bit.
mediaDeviceBtn.addEventListener("click", async () => {
if ("setSinkId" in AudioContext.prototype) {
selectDiv.textContent = "";
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const devices = await navigator.mediaDevices.enumerateDevices();
// Most of the DOM scripting to generate the dropdown cut out for brevity
const audioOutputs = devices.filter(
(device) =>
device.kind === "audiooutput" && device.deviceId !== "default",
);
audioOutputs.forEach((device) => {
const option = document.createElement("option");
option.value = device.deviceId;
option.textContent = device.label;
select.appendChild(option);
});
const option = document.createElement("option");
option.value = "none";
option.textContent = "None";
select.appendChild(option);
select.addEventListener("change", async () => {
if (select.value === "none") {
await audioCtx.setSinkId({ type: "none" });
} else {
await audioCtx.setSinkId(select.value);
}
});
}
});
We also provide the user with a dropdown menu to allow them to change the audio output device on the fly. To do this, we:
setSinkId() with the { type : 'none' } object parameter to select no audio device, otherwise we run it with the audio device ID contained in the <select> element value attribute as the parameter.The output device can be changed during audio playback, as well as before, or between plays.
{{Specifications}}
{{Compat}}