From 2aea41537b32fde35dc8f9f0fe2ad5cdc7bc580d Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Fri, 18 Aug 2023 18:54:45 -0700 Subject: [PATCH] Store preferred webcam device names the user selected * In case the user has remembered their camera/mic permission and the Share Webcam button is able to list their devices before they go on video the first time, we can (try to) select their favorite devices (by name) that they used the last time they were on. --- web/static/js/BareRTC.js | 68 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/web/static/js/BareRTC.js b/web/static/js/BareRTC.js index f3ed62d..1ad48b2 100644 --- a/web/static/js/BareRTC.js +++ b/web/static/js/BareRTC.js @@ -155,6 +155,14 @@ const app = Vue.createApp({ videoDeviceID: null, audioDevices: [], audioDeviceID: null, + + // After we get a device selected, remember it (by name) so that we + // might hopefully re-select it by default IF we are able to enumerate + // devices before they go on camera the first time. + preferredDeviceNames: { + video: null, + audio: null, + }, }, // Video flag constants (sync with values in messages.go) @@ -532,6 +540,13 @@ const app = Vue.createApp({ this.scrollback = parseInt(localStorage.scrollback); } + // Stored user preferred device names for webcam/audio. + if (localStorage.preferredDeviceNames != undefined) { + let dev = JSON.parse(localStorage.preferredDeviceNames); + this.webcam.preferredDeviceNames.video = dev.video; + this.webcam.preferredDeviceNames.audio = dev.audio; + } + // Webcam mutality preferences from last broadcast. if (localStorage.videoMutual === "true") { this.webcam.mutual = true; @@ -1482,7 +1497,11 @@ const app = Vue.createApp({ console.log("device IDs:", this.webcam.videoDeviceID, this.webcam.audioDeviceID); // Collect video and audio devices to let the user change them in their settings. - this.getDevices(); + this.getDevices().then(() => { + // Store their names on localStorage in case we can reselect them by name + // on the user's next visit. + this.storePreferredDeviceNames(); + }); // If we have changed devices, reconnect everybody's WebRTC channels for your existing watchers. if (changeCamera) { @@ -1503,7 +1522,7 @@ const app = Vue.createApp({ this.webcam.gettingDevices = true; - navigator.mediaDevices.enumerateDevices().then(devices => { + return navigator.mediaDevices.enumerateDevices().then(devices => { this.webcam.videoDevices = []; this.webcam.audioDevices = []; devices.forEach(device => { @@ -1526,7 +1545,25 @@ const app = Vue.createApp({ label: device.label, }); } - }) + }); + + // If we don't have the user's current active device IDs (e.g., they have + // not yet started their video the first time), see if we can pre-select + // by their preferred device names. + if (!this.webcam.videoDeviceID && this.webcam.preferredDeviceNames.video) { + for (let dev of this.webcam.videoDevices) { + if (dev.label === this.webcam.preferredDeviceNames.video) { + this.webcam.videoDeviceID = dev.id; + } + } + } + if (!this.webcam.audioDeviceID && this.webcam.preferredDeviceNames.audio) { + for (let dev of this.webcam.audioDevices) { + if (dev.label === this.webcam.preferredDeviceNames.audio) { + this.webcam.audioDeviceID = dev.id; + } + } + } }).catch(err => { this.ChatClient(`Error listing your cameras and microphones: ${err.name}: ${err.message}`); }).finally(() => { @@ -1536,6 +1573,31 @@ const app = Vue.createApp({ }, 500); }) }, + storePreferredDeviceNames() { + // This function looks up the names of the user's selected video/audio device. + // When they come back later, IF we are able to enumerate devices before they + // go on for the first time, we might pre-select their last device by name. + // NOTE: on iOS apparently device IDs shuffle every single time so only names + // may be reliable! + if (this.webcam.videoDeviceID) { + for (let dev of this.webcam.videoDevices) { + if (dev.id === this.webcam.videoDeviceID && dev.label) { + this.webcam.preferredDeviceNames.video = dev.label; + } + } + } + + if (this.webcam.audioDeviceID) { + for (let dev of this.webcam.audioDevices) { + if (dev.id === this.webcam.audioDeviceID && dev.label) { + this.webcam.preferredDeviceNames.audio = dev.label; + } + } + } + + // Put them on localStorage. + localStorage.preferredDeviceNames = JSON.stringify(this.webcam.preferredDeviceNames); + }, // Replace your video/audio streams for your watchers (on camera changes) updateWebRTCStreams() {