|
@@ -400,6 +400,11 @@ JitsiConference.prototype._init = function(options = {}) {
|
400
|
400
|
this._sendConferenceJoinAnalyticsEvent = this._sendConferenceJoinAnalyticsEvent.bind(this);
|
401
|
401
|
this.room.addListener(XMPPEvents.MEETING_ID_SET, this._sendConferenceJoinAnalyticsEvent);
|
402
|
402
|
|
|
403
|
+ this._updateRoomPresence = this._updateRoomPresence.bind(this);
|
|
404
|
+ this.room.addListener(XMPPEvents.SESSION_ACCEPT, this._updateRoomPresence);
|
|
405
|
+ this.room.addListener(XMPPEvents.SOURCE_ADD, this._updateRoomPresence);
|
|
406
|
+ this.room.addListener(XMPPEvents.SOURCE_REMOVE, this._updateRoomPresence);
|
|
407
|
+
|
403
|
408
|
this.e2eping = new E2ePing(
|
404
|
409
|
this,
|
405
|
410
|
config,
|
|
@@ -685,6 +690,9 @@ JitsiConference.prototype.leave = async function() {
|
685
|
690
|
this._updateProperties);
|
686
|
691
|
|
687
|
692
|
room.removeListener(XMPPEvents.MEETING_ID_SET, this._sendConferenceJoinAnalyticsEvent);
|
|
693
|
+ room.removeListener(XMPPEvents.SESSION_ACCEPT, this._updateRoomPresence);
|
|
694
|
+ room.removeListener(XMPPEvents.SOURCE_ADD, this._updateRoomPresence);
|
|
695
|
+ room.removeListener(XMPPEvents.SOURCE_REMOVE, this._updateRoomPresence);
|
688
|
696
|
|
689
|
697
|
this.eventManager.removeXMPPListeners();
|
690
|
698
|
|
|
@@ -1253,6 +1261,11 @@ JitsiConference.prototype.replaceTrack = function(oldTrack, newTrack) {
|
1253
|
1261
|
this._sendBridgeVideoTypeMessage(newTrack);
|
1254
|
1262
|
}
|
1255
|
1263
|
|
|
1264
|
+ // updates presence when we replace the video tracks desktop with screen and screen with desktop
|
|
1265
|
+ if (oldTrackBelongsToConference && oldTrack?.isVideoTrack()) {
|
|
1266
|
+ this._updateRoomPresence(this.p2pJingleSession ? this.p2pJingleSession : this.jvbJingleSession);
|
|
1267
|
+ }
|
|
1268
|
+
|
1256
|
1269
|
if (newTrack !== null && (this.isMutedByFocus || this.isVideoMutedByFocus)) {
|
1257
|
1270
|
this._fireMuteChangeEvent(newTrack);
|
1258
|
1271
|
}
|
|
@@ -1319,19 +1332,8 @@ JitsiConference.prototype._setupNewTrack = function(newTrack) {
|
1319
|
1332
|
}
|
1320
|
1333
|
}
|
1321
|
1334
|
|
1322
|
|
- let videoTypeChanged = false;
|
1323
|
|
-
|
1324
|
|
- if (newTrack.isVideoTrack()) {
|
1325
|
|
- videoTypeChanged = this._setNewVideoType(newTrack);
|
1326
|
|
- }
|
1327
|
1335
|
this.rtc.addLocalTrack(newTrack);
|
1328
|
1336
|
|
1329
|
|
- // ensure that we're sharing proper "is muted" state
|
1330
|
|
- if (this._setTrackMuteStatus(newTrack, newTrack.isMuted()) || videoTypeChanged) {
|
1331
|
|
- // send presence if it was changed with vide type or mute status
|
1332
|
|
- this.room.sendPresence();
|
1333
|
|
- }
|
1334
|
|
-
|
1335
|
1337
|
newTrack.muteHandler = this._fireMuteChangeEvent.bind(this, newTrack);
|
1336
|
1338
|
newTrack.audioLevelHandler = this._fireAudioLevelChangeEvent.bind(this);
|
1337
|
1339
|
newTrack.addEventListener(
|
|
@@ -1353,7 +1355,7 @@ JitsiConference.prototype._setupNewTrack = function(newTrack) {
|
1353
|
1355
|
* @private
|
1354
|
1356
|
*/
|
1355
|
1357
|
JitsiConference.prototype._setNewVideoType = function(track) {
|
1356
|
|
- if (FeatureFlags.isSourceNameSignalingEnabled()) {
|
|
1358
|
+ if (FeatureFlags.isSourceNameSignalingEnabled() && track) {
|
1357
|
1359
|
// FIXME once legacy signaling using 'sendCommand' is removed, signalingLayer.setTrackVideoType must be adjusted
|
1358
|
1360
|
// to send the presence (not just modify it).
|
1359
|
1361
|
this._signalingLayer.setTrackVideoType(
|
|
@@ -1370,11 +1372,15 @@ JitsiConference.prototype._setNewVideoType = function(track) {
|
1370
|
1372
|
|
1371
|
1373
|
const videoTypeTagName = 'videoType';
|
1372
|
1374
|
|
|
1375
|
+ // if track is missing we revert to default type Camera, the case where we screenshare and
|
|
1376
|
+ // we return to be video muted
|
|
1377
|
+ const trackVideoType = track ? track.videoType : VideoType.CAMERA;
|
|
1378
|
+
|
1373
|
1379
|
// if video type is camera and there is no videoType in presence, we skip adding it, as this is the default one
|
1374
|
|
- if (track.videoType !== VideoType.CAMERA || this.room.getFromPresence(videoTypeTagName)) {
|
|
1380
|
+ if (trackVideoType !== VideoType.CAMERA || this.room.getFromPresence(videoTypeTagName)) {
|
1375
|
1381
|
// we will not use this.sendCommand here to avoid sending the presence immediately, as later we may also set
|
1376
|
1382
|
// and the mute status
|
1377
|
|
- return this.room.addOrReplaceInPresence(videoTypeTagName, { value: track.videoType });
|
|
1383
|
+ return this.room.addOrReplaceInPresence(videoTypeTagName, { value: trackVideoType });
|
1378
|
1384
|
}
|
1379
|
1385
|
|
1380
|
1386
|
return false;
|
|
@@ -1382,17 +1388,18 @@ JitsiConference.prototype._setNewVideoType = function(track) {
|
1382
|
1388
|
|
1383
|
1389
|
/**
|
1384
|
1390
|
* Sets mute status.
|
|
1391
|
+ * @param mediaType
|
1385
|
1392
|
* @param localTrack
|
1386
|
1393
|
* @param isMuted
|
1387
|
1394
|
* @param <tt>true</tt> when presence was changed, <tt>false</tt> otherwise.
|
1388
|
1395
|
* @private
|
1389
|
1396
|
*/
|
1390
|
|
-JitsiConference.prototype._setTrackMuteStatus = function(localTrack, isMuted) {
|
|
1397
|
+JitsiConference.prototype._setTrackMuteStatus = function(mediaType, localTrack, isMuted) {
|
1391
|
1398
|
if (FeatureFlags.isSourceNameSignalingEnabled()) {
|
1392
|
1399
|
// TODO When legacy signaling part is removed, remember to adjust signalingLayer.setTrackMuteStatus, so that
|
1393
|
1400
|
// it triggers sending the presence (it only updates it for now, because the legacy code below sends).
|
1394
|
1401
|
this._signalingLayer.setTrackMuteStatus(
|
1395
|
|
- getSourceNameForJitsiTrack(this.myUserId(), localTrack.getType(), 0),
|
|
1402
|
+ getSourceNameForJitsiTrack(this.myUserId(), mediaType, 0),
|
1396
|
1403
|
isMuted
|
1397
|
1404
|
);
|
1398
|
1405
|
}
|
|
@@ -1401,7 +1408,7 @@ JitsiConference.prototype._setTrackMuteStatus = function(localTrack, isMuted) {
|
1401
|
1408
|
return false;
|
1402
|
1409
|
}
|
1403
|
1410
|
|
1404
|
|
- if (localTrack.isAudioTrack()) {
|
|
1411
|
+ if (mediaType === MediaType.AUDIO) {
|
1405
|
1412
|
return this.room.addAudioInfoToPresence(isMuted);
|
1406
|
1413
|
}
|
1407
|
1414
|
|
|
@@ -3596,6 +3603,47 @@ JitsiConference.prototype._stopP2PSession = function(options = {}) {
|
3596
|
3603
|
}
|
3597
|
3604
|
};
|
3598
|
3605
|
|
|
3606
|
+/**
|
|
3607
|
+ * Updates room presence if needed and send the packet in case of a modification.
|
|
3608
|
+ * @param {JingleSessionPC} jingleSession the session firing the event, contains the peer connection which
|
|
3609
|
+ * tracks we will check.
|
|
3610
|
+ * @param {Object|null} ctx a context object we can distinguish multiple calls of the same pass of updating tracks.
|
|
3611
|
+ */
|
|
3612
|
+JitsiConference.prototype._updateRoomPresence = function(jingleSession, ctx) {
|
|
3613
|
+ // skips sending presence twice for the same pass of updating ssrcs
|
|
3614
|
+ if (ctx) {
|
|
3615
|
+ if (ctx.skip) {
|
|
3616
|
+ return;
|
|
3617
|
+ }
|
|
3618
|
+ ctx.skip = true;
|
|
3619
|
+ }
|
|
3620
|
+
|
|
3621
|
+ const localAudioTracks = jingleSession.peerconnection.getLocalTracks(MediaType.AUDIO);
|
|
3622
|
+ const localVideoTracks = jingleSession.peerconnection.getLocalTracks(MediaType.VIDEO);
|
|
3623
|
+ let presenceChanged = false;
|
|
3624
|
+
|
|
3625
|
+ if (localAudioTracks && localAudioTracks.length) {
|
|
3626
|
+ presenceChanged = this._setTrackMuteStatus(MediaType.AUDIO, localAudioTracks[0], localAudioTracks[0].isMuted());
|
|
3627
|
+ } else if (this._setTrackMuteStatus(MediaType.AUDIO, undefined, true)) {
|
|
3628
|
+ presenceChanged = true;
|
|
3629
|
+ }
|
|
3630
|
+
|
|
3631
|
+ if (localVideoTracks && localVideoTracks.length) {
|
|
3632
|
+ const muteStatusChanged = this._setTrackMuteStatus(
|
|
3633
|
+ MediaType.VIDEO, localVideoTracks[0], localVideoTracks[0].isMuted());
|
|
3634
|
+ const videoTypeChanged = this._setNewVideoType(localVideoTracks[0]);
|
|
3635
|
+
|
|
3636
|
+ presenceChanged = presenceChanged || muteStatusChanged || videoTypeChanged;
|
|
3637
|
+ } else {
|
|
3638
|
+ const muteStatusChanged = this._setTrackMuteStatus(MediaType.VIDEO, undefined, true);
|
|
3639
|
+ const videoTypeChanged = this._setNewVideoType(); // set back to default video type
|
|
3640
|
+
|
|
3641
|
+ presenceChanged = presenceChanged || muteStatusChanged || videoTypeChanged;
|
|
3642
|
+ }
|
|
3643
|
+
|
|
3644
|
+ presenceChanged && this.room.sendPresence();
|
|
3645
|
+};
|
|
3646
|
+
|
3599
|
3647
|
/**
|
3600
|
3648
|
* Checks whether or not the conference is currently in the peer to peer mode.
|
3601
|
3649
|
* Being in peer to peer mode means that the direct connection has been
|