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:
parent
a7025c41f6
commit
c4c100e26a
113
conference.js
113
conference.js
|
@ -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);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue