feat(conference): restore video after screen sharing

Will restore the camera video state from before screen sharing was
started (and will mute it if it was muted).
This commit is contained in:
paweldomas 2017-06-20 09:52:44 -05:00 committed by virtuacoplenny
parent a7025c41f6
commit c4c100e26a
1 changed files with 98 additions and 33 deletions

View File

@ -1111,6 +1111,71 @@ export default {
videoSwitchInProgress: false, videoSwitchInProgress: false,
/**
* This fields stores a handler which will create a Promise which turns off
* the screen sharing and restores the previous video state (was there
* any video, before switching to screen sharing ? was it muted ?).
*
* Once called this fields is cleared to <tt>null</tt>.
* @type {Function|null}
*/
_untoggleScreenSharing: null,
/**
* Creates a Promise which turns off the screen sharing and restores
* the previous state described by the arguments.
*
* This method is bound to the appropriate values, after switching to screen
* sharing and stored in {@link _untoggleScreenSharing}.
*
* @param {boolean} didHaveVideo indicates if there was a camera video being
* used, before switching to screen sharing.
* @param {boolean} wasVideoMuted indicates if the video was muted, before
* switching to screen sharing.
* @return {Promise} resolved after the screen sharing is turned off, or
* rejected with some error (no idea what kind of error, possible GUM error)
* in case it fails.
* @private
*/
_turnScreenSharingOff(didHaveVideo, wasVideoMuted) {
this._untoggleScreenSharing = null;
this.videoSwitchInProgress = true;
APP.remoteControl.receiver.stop();
let promise = null;
if (didHaveVideo) {
promise = createLocalTracks({ devices: ['video'] })
.then(([stream]) => this.useVideoStream(stream))
.then(() => {
JitsiMeetJS.analytics.sendEvent(
'conference.sharingDesktop.stop');
logger.log('switched back to local video');
if (!localVideo && wasVideoMuted) {
return Promise.reject('No local video to be muted!');
} else if (wasVideoMuted && localVideo) {
return localVideo.mute();
}
})
.catch(error => {
logger.error('failed to switch back to local video', error);
return this.useVideoStream(null).then(() => {
// Still fail with the original err
return Promise.reject(error);
});
});
} else {
promise = this.useVideoStream(null);
}
return promise.then(
() => {
this.videoSwitchInProgress = false;
},
error => {
this.videoSwitchInProgress = false;
throw error;
});
},
/** /**
* Toggles between screensharing and camera video. * Toggles between screensharing and camera video.
* @param {boolean} [shareScreen] * @param {boolean} [shareScreen]
@ -1121,7 +1186,7 @@ export default {
* 'window', etc.). * 'window', etc.).
* @return {Promise.<T>} * @return {Promise.<T>}
*/ */
toggleScreenSharing(shareScreen = !this.isSharingScreen, options = {}) { toggleScreenSharing(options = {}) {
if (this.videoSwitchInProgress) { if (this.videoSwitchInProgress) {
return Promise.reject('Switch in progress.'); return Promise.reject('Switch in progress.');
} }
@ -1136,11 +1201,11 @@ export default {
return Promise.reject('No screensharing in audio only mode'); return Promise.reject('No screensharing in audio only mode');
} }
if (!this._untoggleScreenSharing) {
this.videoSwitchInProgress = true; this.videoSwitchInProgress = true;
let externalInstallation = false; let externalInstallation = false;
const didHaveVideo = Boolean(localVideo);
if (shareScreen) { const wasVideoMuted = this.videoMuted;
const didHaveVideo = Boolean(this.localVideo);
return createLocalTracks({ return createLocalTracks({
desktopSharingSources: options.desktopSharingSources, desktopSharingSources: options.desktopSharingSources,
@ -1168,22 +1233,26 @@ export default {
} }
} }
}).then(([stream]) => { }).then(([stream]) => {
// Stores the "untoggle" handler which remembers whether was
// there any video before and whether was it muted.
this._untoggleScreenSharing
= this._turnScreenSharingOff
.bind(this, didHaveVideo, wasVideoMuted);
DSExternalInstallationInProgress = false; DSExternalInstallationInProgress = false;
// close external installation dialog on success. // close external installation dialog on success.
if(externalInstallation) if(externalInstallation)
$.prompt.close(); $.prompt.close();
if (didHaveVideo) {
stream.on( stream.on(
TrackEvents.LOCAL_TRACK_STOPPED, TrackEvents.LOCAL_TRACK_STOPPED,
() => { () => {
// If the stream was stopped during screen sharing // If the stream was stopped during screen sharing
// session then we should switch back to video. // session then we should switch back to video.
if (this.isSharingScreen){ if (this.isSharingScreen){
this.toggleScreenSharing(false); this._untoggleScreenSharing
&& this._untoggleScreenSharing();
} }
} }
); );
}
return this.useVideoStream(stream); return this.useVideoStream(stream);
}).then(() => { }).then(() => {
this.videoSwitchInProgress = false; this.videoSwitchInProgress = false;
@ -1200,7 +1269,17 @@ export default {
return Promise.reject(err); return Promise.reject(err);
} }
this.toggleScreenSharing(false); // Pawel: With this call I'm trying to preserve the original
// behaviour although it is not clear why would we "untoggle"
// on failure. I suppose it was to restore video in case there
// was some problem during "this.useVideoStream(desktopStream)".
// It's important to note that the handler will not be available
// if we fail early on trying to get desktop media (which makes
// sense, because the camera video is still being used, so
// nothing to "untoggle").
if (this._untoggleScreenSharing) {
this._untoggleScreenSharing();
}
logger.error('failed to share local desktop', err); logger.error('failed to share local desktop', err);
@ -1233,21 +1312,7 @@ export default {
dialogTitleKey, dialogTxt, false); dialogTitleKey, dialogTxt, false);
}); });
} else { } else {
APP.remoteControl.receiver.stop(); return this._untoggleScreenSharing();
return createLocalTracks(
{ devices: ['video'] })
.then(
([stream]) => this.useVideoStream(stream)
).then(() => {
this.videoSwitchInProgress = false;
JitsiMeetJS.analytics.sendEvent(
'conference.sharingDesktop.stop');
logger.log('sharing local video');
}).catch((err) => {
this.useVideoStream(null);
this.videoSwitchInProgress = false;
logger.error('failed to share local video', err);
});
} }
}, },
/** /**