diff --git a/conference.js b/conference.js index d6fdecf3d..69d377306 100644 --- a/conference.js +++ b/conference.js @@ -2340,6 +2340,10 @@ export default { const promises = []; const audioWasMuted = this.isLocalAudioMuted(); const videoWasMuted = this.isLocalVideoMuted(); + const requestedInput = { + audio: Boolean(newDevices.audioinput), + video: Boolean(newDevices.videoinput) + }; if (typeof newDevices.audiooutput !== 'undefined') { const { dispatch } = APP.store; @@ -2351,6 +2355,18 @@ export default { promises.push(setAudioOutputPromise); } + // Handles the use case when the default device is changed (we are always stopping the streams because it's + // simpler): + // If the default device is changed we need to first stop the local streams and then call GUM. Otherwise GUM + // will return a stream using the old default device. + if (requestedInput.audio && this.localAudio) { + this.localAudio.stopStream(); + } + + if (requestedInput.video && this.localVideo) { + this.localVideo.stopStream(); + } + promises.push( mediaDeviceHelper.createLocalTracksAfterDeviceListChanged( createLocalTracksF, @@ -2369,8 +2385,20 @@ export default { }); return Promise.all(muteSyncPromises) - .then(() => Promise.all( - this._setLocalAudioVideoStreams(tracks))); + .then(() => + Promise.all(Object.keys(requestedInput).map(mediaType => { + if (requestedInput[mediaType]) { + const useStream + = mediaType === 'audio' + ? this.useAudioStream.bind(this) + : this.useVideoStream.bind(this); + + // Use the new stream or null if we failed to obtain it. + return useStream(tracks.find(track => track.getType() === mediaType) || null); + } + + return Promise.resolve(); + }))); }) .then(() => { // Log and sync known mute state. diff --git a/modules/devices/mediaDeviceHelper.js b/modules/devices/mediaDeviceHelper.js index a3bbe6506..4767be63f 100644 --- a/modules/devices/mediaDeviceHelper.js +++ b/modules/devices/mediaDeviceHelper.js @@ -50,7 +50,9 @@ function getNewAudioInputDevice(newDevices, localAudio) { // If we have new audio device and permission to use it was granted // (label is not an empty string), then we will try to use the first // available device. - if (availableAudioInputDevices.length + if (selectedAudioInputDevice && selectedAudioInputDeviceId) { + return selectedAudioInputDeviceId; + } else if (availableAudioInputDevices.length && availableAudioInputDevices[0].label !== '') { return availableAudioInputDevices[0].deviceId; } @@ -87,7 +89,9 @@ function getNewVideoInputDevice(newDevices, localVideo) { // If we have new video device and permission to use it was granted // (label is not an empty string), then we will try to use the first // available device. - if (availableVideoInputDevices.length + if (selectedVideoInputDevice && selectedVideoInputDeviceId) { + return selectedVideoInputDeviceId; + } else if (availableVideoInputDevices.length && availableVideoInputDevices[0].label !== '') { return availableVideoInputDevices[0].deviceId; } @@ -121,8 +125,7 @@ export default { localAudio) { return { audioinput: getNewAudioInputDevice(newDevices, localAudio), - videoinput: !isSharingScreen - && getNewVideoInputDevice(newDevices, localVideo), + videoinput: isSharingScreen ? undefined : getNewVideoInputDevice(newDevices, localVideo), audiooutput: getNewAudioOutputDevice(newDevices) }; }, @@ -180,7 +183,7 @@ export default { /** * */ - function createAudioTrack(showError) { + function createAudioTrack(showError = true) { return ( createLocalTracks({ devices: [ 'audio' ], @@ -198,7 +201,7 @@ export default { /** * */ - function createVideoTrack(showError) { + function createVideoTrack(showError = true) { return ( createLocalTracks({ devices: [ 'video' ], diff --git a/package-lock.json b/package-lock.json index 6dbd003bb..40dd03c1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2662,7 +2662,7 @@ "blueimp-md5": "^2.10.0", "json3": "^3.3.2", "lodash": "^4.17.4", - "ua-parser-js": "github:amplitude/ua-parser-js#ed538f1" + "ua-parser-js": "github:amplitude/ua-parser-js#ed538f16f5c6ecd8357da989b617d4f156dcf35d" }, "dependencies": { "ua-parser-js": { @@ -6433,8 +6433,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -6452,13 +6451,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6471,18 +6468,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -6585,8 +6579,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -6596,7 +6589,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6609,20 +6601,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.2.4", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -6639,7 +6628,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -6712,8 +6700,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -6723,7 +6710,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -6799,8 +6785,7 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -6830,7 +6815,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6848,7 +6832,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6887,13 +6870,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.0.2", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -8634,8 +8615,8 @@ } }, "lib-jitsi-meet": { - "version": "github:jitsi/lib-jitsi-meet#86e3badd5c04e1df72435205d28a58c8a64e343a", - "from": "github:jitsi/lib-jitsi-meet#86e3badd5c04e1df72435205d28a58c8a64e343a", + "version": "github:jitsi/lib-jitsi-meet#f6054a887a5d5363681356aff6e79d89343f0bfc", + "from": "github:jitsi/lib-jitsi-meet#f6054a887a5d5363681356aff6e79d89343f0bfc", "requires": { "@jitsi/sdp-interop": "0.1.14", "@jitsi/sdp-simulcast": "0.2.1", diff --git a/package.json b/package.json index 1df28134f..546dbbe33 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "js-utils": "github:jitsi/js-utils#73a67a7a60d52f8e895f50939c8fcbd1f20fe7b5", "jsrsasign": "8.0.12", "jwt-decode": "2.2.0", - "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#86e3badd5c04e1df72435205d28a58c8a64e343a", + "lib-jitsi-meet": "github:jitsi/lib-jitsi-meet#f6054a887a5d5363681356aff6e79d89343f0bfc", "libflacjs": "github:mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d", "lodash": "4.17.11", "moment": "2.19.4",