|
@@ -815,7 +815,7 @@ export default {
|
815
|
815
|
* @param {boolean} [showUI] when set to false will not display any error
|
816
|
816
|
* dialogs in case of media permissions error.
|
817
|
817
|
*/
|
818
|
|
- async mutePresenterVideo(mute, showUI = true) {
|
|
818
|
+ async mutePresenter(mute, showUI = true) {
|
819
|
819
|
const maybeShowErrorDialog = error => {
|
820
|
820
|
showUI && APP.store.dispatch(notifyCameraError(error));
|
821
|
821
|
};
|
|
@@ -823,33 +823,17 @@ export default {
|
823
|
823
|
if (mute) {
|
824
|
824
|
try {
|
825
|
825
|
await this.localVideo.setEffect(undefined);
|
826
|
|
- APP.store.dispatch(
|
827
|
|
- setVideoMuted(mute, MEDIA_TYPE.PRESENTER));
|
828
|
826
|
} catch (err) {
|
829
|
|
- logger.error('Failed to mute the Presenter video');
|
|
827
|
+ logger.error('Failed to remove the presenter effect', err);
|
|
828
|
+ maybeShowErrorDialog(err);
|
|
829
|
+ }
|
|
830
|
+ } else {
|
|
831
|
+ try {
|
|
832
|
+ await this.localVideo.setEffect(await this._createPresenterStreamEffect());
|
|
833
|
+ } catch (err) {
|
|
834
|
+ logger.error('Failed to apply the presenter effect', err);
|
|
835
|
+ maybeShowErrorDialog(err);
|
830
|
836
|
}
|
831
|
|
-
|
832
|
|
- return;
|
833
|
|
- }
|
834
|
|
- const { height } = this.localVideo.track.getSettings();
|
835
|
|
- const defaultCamera
|
836
|
|
- = getUserSelectedCameraDeviceId(APP.store.getState());
|
837
|
|
- let effect;
|
838
|
|
-
|
839
|
|
- try {
|
840
|
|
- effect = await this._createPresenterStreamEffect(height,
|
841
|
|
- defaultCamera);
|
842
|
|
- } catch (err) {
|
843
|
|
- logger.error('Failed to unmute Presenter Video');
|
844
|
|
- maybeShowErrorDialog(err);
|
845
|
|
-
|
846
|
|
- return;
|
847
|
|
- }
|
848
|
|
- try {
|
849
|
|
- await this.localVideo.setEffect(effect);
|
850
|
|
- APP.store.dispatch(setVideoMuted(mute, MEDIA_TYPE.PRESENTER));
|
851
|
|
- } catch (err) {
|
852
|
|
- logger.error('Failed to apply the Presenter effect', err);
|
853
|
837
|
}
|
854
|
838
|
},
|
855
|
839
|
|
|
@@ -868,7 +852,7 @@ export default {
|
868
|
852
|
}
|
869
|
853
|
|
870
|
854
|
if (this.isSharingScreen) {
|
871
|
|
- return this.mutePresenterVideo(mute);
|
|
855
|
+ return this._mutePresenterVideo(mute);
|
872
|
856
|
}
|
873
|
857
|
|
874
|
858
|
// If not ready to modify track's state yet adjust the base/media
|
|
@@ -1612,31 +1596,63 @@ export default {
|
1612
|
1596
|
* @return {Promise<JitsiStreamPresenterEffect>} - A promise resolved with
|
1613
|
1597
|
* {@link JitsiStreamPresenterEffect} if it succeeds.
|
1614
|
1598
|
*/
|
1615
|
|
- async _createPresenterStreamEffect(height, cameraDeviceId = null) {
|
1616
|
|
- let presenterTrack;
|
1617
|
|
-
|
1618
|
|
- try {
|
1619
|
|
- presenterTrack = await createLocalPresenterTrack({
|
1620
|
|
- cameraDeviceId
|
1621
|
|
- },
|
1622
|
|
- height);
|
1623
|
|
- } catch (err) {
|
1624
|
|
- logger.error('Failed to create a camera track for presenter', err);
|
|
1599
|
+ async _createPresenterStreamEffect(height = null, cameraDeviceId = null) {
|
|
1600
|
+ if (!this.localPresenterVideo) {
|
|
1601
|
+ try {
|
|
1602
|
+ this.localPresenterVideo = await createLocalPresenterTrack({ cameraDeviceId }, height);
|
|
1603
|
+ } catch (err) {
|
|
1604
|
+ logger.error('Failed to create a camera track for presenter', err);
|
1625
|
1605
|
|
1626
|
|
- return;
|
|
1606
|
+ return;
|
|
1607
|
+ }
|
|
1608
|
+ APP.store.dispatch(trackAdded(this.localPresenterVideo));
|
1627
|
1609
|
}
|
1628
|
|
- this.localPresenterVideo = presenterTrack;
|
1629
|
1610
|
try {
|
1630
|
|
- const effect = await createPresenterEffect(presenterTrack.stream);
|
1631
|
|
-
|
1632
|
|
- APP.store.dispatch(trackAdded(this.localPresenterVideo));
|
|
1611
|
+ const effect = await createPresenterEffect(this.localPresenterVideo.stream);
|
1633
|
1612
|
|
1634
|
1613
|
return effect;
|
1635
|
1614
|
} catch (err) {
|
1636
|
1615
|
logger.error('Failed to create the presenter effect', err);
|
1637
|
|
- APP.store.dispatch(
|
1638
|
|
- setVideoMuted(true, MEDIA_TYPE.PRESENTER));
|
1639
|
|
- APP.store.dispatch(notifyCameraError(err));
|
|
1616
|
+ }
|
|
1617
|
+ },
|
|
1618
|
+
|
|
1619
|
+ /**
|
|
1620
|
+ * Tries to turn the presenter video track on or off. If a presenter track
|
|
1621
|
+ * doesn't exist, a new video track is created.
|
|
1622
|
+ *
|
|
1623
|
+ * @param mute - true for mute and false for unmute.
|
|
1624
|
+ *
|
|
1625
|
+ * @private
|
|
1626
|
+ */
|
|
1627
|
+ async _mutePresenterVideo(mute) {
|
|
1628
|
+ const maybeShowErrorDialog = error => {
|
|
1629
|
+ APP.store.dispatch(notifyCameraError(error));
|
|
1630
|
+ };
|
|
1631
|
+
|
|
1632
|
+ if (!this.localPresenterVideo && !mute) {
|
|
1633
|
+ // create a new presenter track and apply the presenter effect.
|
|
1634
|
+ const { height } = this.localVideo.track.getSettings();
|
|
1635
|
+ const defaultCamera
|
|
1636
|
+ = getUserSelectedCameraDeviceId(APP.store.getState());
|
|
1637
|
+ let effect;
|
|
1638
|
+
|
|
1639
|
+ try {
|
|
1640
|
+ effect = await this._createPresenterStreamEffect(height,
|
|
1641
|
+ defaultCamera);
|
|
1642
|
+ } catch (err) {
|
|
1643
|
+ logger.error('Failed to unmute Presenter Video');
|
|
1644
|
+ maybeShowErrorDialog(err);
|
|
1645
|
+
|
|
1646
|
+ return;
|
|
1647
|
+ }
|
|
1648
|
+ try {
|
|
1649
|
+ await this.localVideo.setEffect(effect);
|
|
1650
|
+ APP.store.dispatch(setVideoMuted(mute, MEDIA_TYPE.PRESENTER));
|
|
1651
|
+ } catch (err) {
|
|
1652
|
+ logger.error('Failed to apply the Presenter effect', err);
|
|
1653
|
+ }
|
|
1654
|
+ } else {
|
|
1655
|
+ APP.store.dispatch(setVideoMuted(mute, MEDIA_TYPE.PRESENTER));
|
1640
|
1656
|
}
|
1641
|
1657
|
},
|
1642
|
1658
|
|
|
@@ -2108,23 +2124,29 @@ export default {
|
2108
|
2124
|
|
2109
|
2125
|
// dispose the existing presenter track and create a new
|
2110
|
2126
|
// camera track.
|
2111
|
|
- APP.store.dispatch(setVideoMuted(true, MEDIA_TYPE.PRESENTER));
|
|
2127
|
+ this.localPresenterVideo.dispose();
|
|
2128
|
+ this.localPresenterVideo = null;
|
2112
|
2129
|
|
2113
|
2130
|
return this._createPresenterStreamEffect(height, cameraDeviceId)
|
2114
|
2131
|
.then(effect => this.localVideo.setEffect(effect))
|
2115
|
2132
|
.then(() => {
|
2116
|
|
- muteLocalVideo(false);
|
2117
|
2133
|
this.setVideoMuteStatus(false);
|
2118
|
2134
|
logger.log('switched local video device');
|
2119
|
2135
|
this._updateVideoDeviceId();
|
2120
|
2136
|
})
|
2121
|
2137
|
.catch(err => APP.store.dispatch(notifyCameraError(err)));
|
2122
|
2138
|
|
2123
|
|
- // If screenshare is in progress but video is muted,
|
2124
|
|
- // update the default device id for video.
|
|
2139
|
+ // If screenshare is in progress but video is muted, update the default device
|
|
2140
|
+ // id for video, dispose the existing presenter track and create a new effect
|
|
2141
|
+ // that can be applied on un-mute.
|
2125
|
2142
|
} else if (this.isSharingScreen && videoWasMuted) {
|
2126
|
2143
|
logger.log('switched local video device');
|
|
2144
|
+ const { height } = this.localVideo.track.getSettings();
|
|
2145
|
+
|
2127
|
2146
|
this._updateVideoDeviceId();
|
|
2147
|
+ this.localPresenterVideo.dispose();
|
|
2148
|
+ this.localPresenterVideo = null;
|
|
2149
|
+ this._createPresenterStreamEffect(height, cameraDeviceId);
|
2128
|
2150
|
|
2129
|
2151
|
// if there is only video, switch to the new camera stream.
|
2130
|
2152
|
} else {
|
|
@@ -2379,6 +2401,13 @@ export default {
|
2379
|
2401
|
cameraDeviceId: this.localVideo.getDeviceId()
|
2380
|
2402
|
}));
|
2381
|
2403
|
}
|
|
2404
|
+
|
|
2405
|
+ // If screenshare is in progress, get the device id from the presenter track.
|
|
2406
|
+ if (this.localPresenterVideo) {
|
|
2407
|
+ APP.store.dispatch(updateSettings({
|
|
2408
|
+ cameraDeviceId: this.localPresenterVideo.getDeviceId()
|
|
2409
|
+ }));
|
|
2410
|
+ }
|
2382
|
2411
|
},
|
2383
|
2412
|
|
2384
|
2413
|
/**
|