diff options
author | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2021-05-06 02:23:05 +0300 |
---|---|---|
committer | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2021-05-06 20:12:11 +0300 |
commit | 37330d2fe5c4d1a483da1cd911fa4f4876c7fb10 (patch) | |
tree | ca54e482261a5650ecccbcc57fb47ed67b736355 /src | |
parent | fa38b02c33a7b56cf839931edfa1d615462ee7a8 (diff) |
Fix switching devices in Firefox
If a device is currently active and a different one is requested Firefox
returns the currently active device. To overcome this all the tracks of
the same device kind as the requested one are stopped before performing
the request.
However, a device is also "active" as long as any other device returned
in the same "getUserMedia" request is active. Both audio and video are
requested at once when a call is started, so during calls it was needed
to stop both devices first to be able to switch just one of them.
Moreover, since Firefox 88 there is a grace period for requesting again
the media permissions to the user once a track stops. During that grace
period the device is also "active" and it is not possible to switch to
another device even if the previous one was requested on its own,
without any other device. In this case the permissions have to be
manually revoked to be able to switch to another device before the grace
period ended.
To solve all that now the ID of the requested device is marked as a
required constraint instead of an optional one, which forces Firefox to
honour the requested device and return it instead of the active one.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/utils/webrtc/MediaDevicesManager.js | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/src/utils/webrtc/MediaDevicesManager.js b/src/utils/webrtc/MediaDevicesManager.js index fd4239887..9c0ca5122 100644 --- a/src/utils/webrtc/MediaDevicesManager.js +++ b/src/utils/webrtc/MediaDevicesManager.js @@ -383,7 +383,7 @@ MediaDevicesManager.prototype = { if (!(constraints.audio instanceof Object)) { constraints.audio = {} } - constraints.audio.deviceId = this.attributes.audioInputId + constraints.audio.deviceId = { exact: this.attributes.audioInputId } } else if (this.attributes.audioInputId === null) { constraints.audio = false } @@ -394,7 +394,7 @@ MediaDevicesManager.prototype = { if (!(constraints.video instanceof Object)) { constraints.video = {} } - constraints.video.deviceId = this.attributes.videoInputId + constraints.video.deviceId = { exact: this.attributes.videoInputId } } else if (this.attributes.videoInputId === null) { constraints.video = false } @@ -429,15 +429,17 @@ MediaDevicesManager.prototype = { _stopIncompatibleTracks: function(constraints) { this._tracks.forEach(track => { if (constraints.audio && constraints.audio.deviceId && track.kind === 'audio') { + const constraintsAudioDeviceId = constraints.audio.deviceId.exact || constraints.audio.deviceId.ideal || constraints.audio.deviceId const settings = track.getSettings() - if (settings && settings.deviceId !== constraints.audio.deviceId) { + if (settings && settings.deviceId !== constraintsAudioDeviceId) { track.stop() } } if (constraints.video && constraints.video.deviceId && track.kind === 'video') { + const constraintsVideoDeviceId = constraints.video.deviceId.exact || constraints.video.deviceId.ideal || constraints.video.deviceId const settings = track.getSettings() - if (settings && settings.deviceId !== constraints.video.deviceId) { + if (settings && settings.deviceId !== constraintsVideoDeviceId) { track.stop() } } |