I am attempting to use the Web Audio API to play a sine tone to a specific audio output device (if you're interested - the use case is to play a short 1750 Hz tone to an audio interface attached to a ham radio, which "opens" a repeater).
For that, I first use navigator.mediaDevices.enumerateDevices() to get a list of audio output interfaces available and populate a dropdown with it. Then, in a function attached to a "run" button, I use the device ID currently selected as a constraint in navigator.mediaDevices .getUserMedia() to get that specific audio device's MediaStream, create an AudioContext instance, a MediaStreamDestinationNode on that audio context from the stream, and finally create and connect an OscillatorNode's output to the destination.
However, I run into a problem already at the second step - it appears that (tested on Chrome 145.0.7632.117, macOS Tahoe 26.3), going by the track's label, the MediaStream's first and only track is always my MacBook's microphone instead of the speaker device that I selected - and for that reason I also do not hear any audio playing.
I made a minimum reproduction Snippet here showing the issue - you'll need to go into the Console to see the weird label, and you might have to grant stacksnippets.net the microphone and speaker permissions manually because for some reason Chrome doesn't prompt you.
$(document).ready(function() {
let enumeratorPromise = navigator.mediaDevices.enumerateDevices();
enumeratorPromise.then((devices) => {
console.log(devices);
devices.forEach((device) => {
console.log("Got device from enumerator", device);
if (device.kind !== "audiooutput") return;
let $deviceOption = $("
Select audio device: