From cddc6125849da05f027d1003dddc3631cd74974c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 21 Aug 2020 18:23:14 +0200 Subject: [PATCH] Do not use "finally" on promises returned by "getUserMedia" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Promise.finally" is available in older browsers for "hand-made" promises, probably due to a shim or to the code being transpiled (I have not checked). However, it is not available for internal promises returned by "navigator.mediaDevices.getUserMedia()". Moreover, in some browser versions (Firefox >= 58 && <= 68) there seems to be a clash between the internal promise and the shimed/transpiled one, as "Promise.finally" is available for "getUserMedia" promises, but not when used in Nextcloud. Due to all that "finally" uses were replaced by a function called at the end of "then" and "catch". Signed-off-by: Daniel Calviño Sánchez --- src/components/MediaDevicesPreview.vue | 40 ++++++++++++++++--------- src/utils/webrtc/MediaDevicesManager.js | 3 ++ 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/components/MediaDevicesPreview.vue b/src/components/MediaDevicesPreview.vue index 31462d41a19..cc1d8b16e78 100644 --- a/src/components/MediaDevicesPreview.vue +++ b/src/components/MediaDevicesPreview.vue @@ -340,22 +340,28 @@ export default { this.pendingGetUserMediaAudioCount = 1 + const resetPendingGetUserMediaAudioCount = () => { + const updateAudioStreamAgain = this.pendingGetUserMediaAudioCount > 1 + + this.pendingGetUserMediaAudioCount = 0 + + if (updateAudioStreamAgain) { + this.updateAudioStream() + } + } + this.mediaDevicesManager.getUserMedia({ audio: true }) .then(stream => { this.setAudioStream(stream) + + resetPendingGetUserMediaAudioCount() }) .catch(error => { console.error('Error getting audio stream: ' + error.name + ': ' + error.message) this.audioStreamError = error this.setAudioStream(null) - }).finally(() => { - const updateAudioStreamAgain = this.pendingGetUserMediaAudioCount > 1 - - this.pendingGetUserMediaAudioCount = 0 - if (updateAudioStreamAgain) { - this.updateAudioStream() - } + resetPendingGetUserMediaAudioCount() }) }, @@ -386,22 +392,28 @@ export default { this.pendingGetUserMediaVideoCount = 1 + const resetPendingGetUserMediaVideoCount = () => { + const updateVideoStreamAgain = this.pendingGetUserMediaVideoCount > 1 + + this.pendingGetUserMediaVideoCount = 0 + + if (updateVideoStreamAgain) { + this.updateVideoStream() + } + } + this.mediaDevicesManager.getUserMedia({ video: true }) .then(stream => { this.setVideoStream(stream) + + resetPendingGetUserMediaVideoCount() }) .catch(error => { console.error('Error getting video stream: ' + error.name + ': ' + error.message) this.videoStreamError = error this.setVideoStream(null) - }).finally(() => { - const updateVideoStreamAgain = this.pendingGetUserMediaVideoCount > 1 - - this.pendingGetUserMediaVideoCount = 0 - if (updateVideoStreamAgain) { - this.updateVideoStream() - } + resetPendingGetUserMediaVideoCount() }) }, diff --git a/src/utils/webrtc/MediaDevicesManager.js b/src/utils/webrtc/MediaDevicesManager.js index 27077aa198f..6d6dc0a685b 100644 --- a/src/utils/webrtc/MediaDevicesManager.js +++ b/src/utils/webrtc/MediaDevicesManager.js @@ -303,6 +303,9 @@ MediaDevicesManager.prototype = { * constraints do not specify a device already. Otherwise the devices in the * constraints are respected. * + * For compatibility with older browsers "finally" should not be used on the + * returned Promise. + * * @param {MediaStreamConstraints} constraints the constraints specifying * the media to request * @returns {Promise} resolved with a MediaStream object when successful, or