Async in-content picker remember
by jib1
HTML
<button id="go">Go!</button><br><br>
Camera: <select id="camera"></select><br>
Microphone: <select id="microphone"></select><br>
<video id="video" height="100" autoplay controls></video><br>
<div id="div"></div><br>
JavaScript
const console = { log: msg => div.innerHTML += msg + "<br>" };
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
async function getUserMedia({video, audio}) {
if (video === true) {
video = {deviceId: localStorage.video};
}
if (audio === true) {
audio = {deviceId: localStorage.audio};
}
const stream = await navigator.mediaDevices.getUserMedia({video, audio});
for (const track of stream.getTracks()) {
localStorage[track.kind] = track.getSettings().deviceId;
}
return stream;
}
go.onclick = async () => {
try {
video.srcObject = await getUserMedia({audio: true, video: true});
updateSelectors(video.srcObject.getTracks().map(t => t.getSettings().deviceId));
} catch (e) {
console.log(e);
}
};
async function replaceUserMedia(constraints, ...oldTracks) {
try {
return await getUserMedia(constraints);
} catch (e) {
if (e.name != "NotReadableError") throw e;
for (const track of oldTracks) {
track.stop();
}
return await getUserMedia(constraints);
}
}
microphone.onchange = async () => {
try {
const constraints = {audio: {deviceId: {exact: microphone.value}}};
let [track] = video.srcObject.getAudioTracks();
track = (await replaceUserMedia(constraints, track)).getAudioTracks()[0];
video.srcObject = new MediaStream([track, ...video.srcObject.getVideoTracks()]);
} catch (e) {
updateSelectors([video.srcObject.getAudioTracks()[0].getSettings().deviceId]);
console.log(e);
}
};
camera.onchange = async () => {
try {
const constraints = {video: {deviceId: {exact: camera.value}}};
let [track] = video.srcObject.getVideoTracks();
track = (await replaceUserMedia(constraints, track)).getVideoTracks()[0];
video.srcObject = new MediaStream([track, ...video.srcObject.getAudioTracks()]);
} catch (e) {
updateSelectors([video.srcObject.getVideoTracks()[0].getSettings().deviceId]);
console.log(e);
}
};
navigator.mediaDevices.ondevicechange...