JSFiddle - React, Tailwind, and code Playground
by ibcaliax
HTML
"Unfortunatelly" it seems that this issue just happens with WebRTC audio tracks (so it does not happen here). And I don't have time to modify it...
JavaScript
const AUDIO_URL = 'https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3';
let audioElement;
async function run() {
const speakers = (await navigator.mediaDevices.enumerateDevices())
.filter((device) => device.kind === 'audiooutput');
addTitle('SUCCESS: setSinkId() *after* audio element was in the DOM:');
for (const speaker of speakers) {
addButton(speaker, true);
}
addTitle('ERROR: setSinkId() *before* audio element was in the DOM:');
for (const speaker of speakers) {
addButton(speaker, false);
}
}
function addTitle(text) {
const title = document.createElement('h1');
title.textContent = text;
document.body.appendChild(title);
}
function addButton(speaker, success) {
const button = document.createElement('input');
button.type = 'button';
button.value = speaker.label;
button.onclick = () => {
if (success) {
onButtonClickSuccess(speaker);
} else {
onButtonClickError(speaker);
}
};
document.body.appendChild(button);
}
async function onButtonClickSuccess(speaker) {
if (audioElement) {
audioElement.remove();
}
audioElement = document.createElement('audio');
audioElement.src = AUDIO_URL;
document.body.appendChild(audioElement);
await audioElement.setSinkId(speaker.deviceId);
await audioElement.play();
}
async function onButtonClickError(speaker) {
if (audioElement) {
audioElement.remove();
}
audioElement = document.createElement('audio');
audioElement.src = AUDIO_URL;
await audioElement.setSinkId(speaker.deviceId);
await audioElement.play();
document.body.appendChild(audioElement);
}
run();