From d0ed30130063ff189651883699d1f258d158c199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 18 Apr 2024 16:08:29 +0200 Subject: [PATCH 1/2] fix: Populate preferences before using them MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lists of preferences are used to select the default input devices when none was selected yet, so they need to be populated first. Otherwise the first time that the devices are updated the lists will be empty, so no default device would be set. Signed-off-by: Daniel Calviño Sánchez --- src/utils/webrtc/MediaDevicesManager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/webrtc/MediaDevicesManager.js b/src/utils/webrtc/MediaDevicesManager.js index ef3b3917b28..cb6eb61b1c8 100644 --- a/src/utils/webrtc/MediaDevicesManager.js +++ b/src/utils/webrtc/MediaDevicesManager.js @@ -205,6 +205,8 @@ MediaDevicesManager.prototype = { this._addDevice(addedDevice) }) + this._populatePreferences(devices) + // Selecting preferred device in case it was removed/unplugged, or it is a first initialization after reload, // or we add/plug preferred device and overwriting automatic selection if (this.attributes.audioInputId === undefined || this.attributes.audioInputId === previousFirstAvailableAudioInputId) { @@ -226,8 +228,6 @@ MediaDevicesManager.prototype = { } this._pendingEnumerateDevicesPromise = null - - this._populatePreferences(devices) }).catch(function(error) { console.error('Could not update known media devices: ' + error.name + ': ' + error.message) From 30856b2d546408752ae5ae7f10250b7249cfee86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 18 Apr 2024 16:24:09 +0200 Subject: [PATCH 2/2] fix: Fix handling of devices when no permissions were given in Chromium MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When no permissions were given yet a single device of each kind with an empty deviceId may be returned (it is in the MediaDevices spec, but implemented by Chromium and not by Firefox yet). Those devices are not registered in the preference lists, so the lists are empty and no default devices are set. Indirectly this causes that no media is requested by the media settings dialog, so no permissions are asked for and thus the list is not updated with the real devices either. Signed-off-by: Daniel Calviño Sánchez --- src/utils/webrtc/MediaDevicesManager.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/utils/webrtc/MediaDevicesManager.js b/src/utils/webrtc/MediaDevicesManager.js index cb6eb61b1c8..4c8ea756afc 100644 --- a/src/utils/webrtc/MediaDevicesManager.js +++ b/src/utils/webrtc/MediaDevicesManager.js @@ -209,12 +209,18 @@ MediaDevicesManager.prototype = { // Selecting preferred device in case it was removed/unplugged, or it is a first initialization after reload, // or we add/plug preferred device and overwriting automatic selection + // If the preference list is empty the default device falls back to + // the first device of that kind found. This can happen, for + // example, when no permissions were given yet. In that case, + // according to the spec, a single device of each kind (if at least + // one device of that kind is available) with an empty deviceId is + // returned, which will not be registered in the preference list. if (this.attributes.audioInputId === undefined || this.attributes.audioInputId === previousFirstAvailableAudioInputId) { - this.attributes.audioInputId = getFirstAvailableMediaDevice(devices, this._preferenceAudioInputList) + this.attributes.audioInputId = getFirstAvailableMediaDevice(devices, this._preferenceAudioInputList) || devices.find(device => device.kind === 'audioinput')?.deviceId console.debug(listMediaDevices(this.attributes, this._preferenceAudioInputList, this._preferenceVideoInputList)) } if (this.attributes.videoInputId === undefined || this.attributes.videoInputId === previousFirstAvailableVideoInputId) { - this.attributes.videoInputId = getFirstAvailableMediaDevice(devices, this._preferenceVideoInputList) + this.attributes.videoInputId = getFirstAvailableMediaDevice(devices, this._preferenceVideoInputList) || devices.find(device => device.kind === 'videoinput')?.deviceId console.debug(listMediaDevices(this.attributes, this._preferenceAudioInputList, this._preferenceVideoInputList)) }