Async gUM headset detection
by jib1
HTML
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<audio id="audio" width="160" height="120" autoplay controls></audio><br>
<div id="div2"></div><br>
<div id="div" style="white-space: pre;"></div>
JavaScript
(async () => {
try {
audio.srcObject = await navigator.mediaDevices.getUserMedia({audio: true});
let [track] = audio.srcObject.getAudioTracks();
let devices = await navigator.mediaDevices.enumerateDevices();
setInterval(() => update(info(track, devices)), 500);
let oldDevices = devices;
track.onended = () => oldDevices = [];
let eventCounter = 0;
navigator.mediaDevices.ondevicechange = async () => {
try {
const id = ++eventCounter;
console.log("devicechange");
devices = await navigator.mediaDevices.enumerateDevices();
if (id != eventCounter) return; // Work around trigger-happy Chrome
const newDevices = devices.filter(d => !oldDevices.find(({deviceId}) => deviceId == d.deviceId));
oldDevices = devices;
const mic = newDevices.find(({kind}) => kind == "audioinput");
const action = `${(track.readyState == "live")? "inserted" : "removed"}`;
if (mic) {
console.log(`mic ${action}`);
track.stop(); // work around Firefox concurrent mic limit
audio.srcObject = await navigator.mediaDevices.getUserMedia({audio: {
deviceId: {exact: mic.deviceId}
}});
[track] = audio.srcObject.getAudioTracks();
track.onended = () => oldDevices = [];
}
const speaker = newDevices.find(({kind}) => kind == "audiooutput");
if (speaker) {
console.log(`speaker ${action}`);
if ("setSinkId" in audio) {
await audio.setSinkId(speaker.deviceId);
}
}
if (audio.sinkId && !devices.find(({deviceId}) => deviceId == audio.sinkId)) {
audio.setSinkId(null);
}
} catch(e) {
console.log(e);
}
};
} catch(e) {
console.log(e);
}
})();
const console = { log: msg => div.innerHTML += msg + "<br>" };
const update = msg => div2.innerHTML = msg;
const info = (track, devices) => `${track.kind == "video" ? "Camera"...