|
|
@@ -40,6 +40,13 @@ export default class ParticipantConnectionStatus {
|
|
40
|
40
|
* @type {Object.<string, number>}
|
|
41
|
41
|
*/
|
|
42
|
42
|
this.trackTimers = {};
|
|
|
43
|
+ /**
|
|
|
44
|
+ * This map holds the endpoint connection status received from the JVB
|
|
|
45
|
+ * (as it might be different than the one stored in JitsiParticipant).
|
|
|
46
|
+ * Required for getting back in sync when remote video track is removed.
|
|
|
47
|
+ * @type {Object.<string, boolean>}
|
|
|
48
|
+ */
|
|
|
49
|
+ this.rtcConnStatusCache = { };
|
|
43
|
50
|
/**
|
|
44
|
51
|
* How long we're going to wait after the RTC video track muted event
|
|
45
|
52
|
* for the corresponding signalling mute event, before the connection
|
|
|
@@ -128,6 +135,9 @@ export default class ParticipantConnectionStatus {
|
|
128
|
135
|
Object.keys(this.trackTimers).forEach(function (participantId) {
|
|
129
|
136
|
this.clearTimeout(participantId);
|
|
130
|
137
|
}.bind(this));
|
|
|
138
|
+
|
|
|
139
|
+ // Clear RTC connection status cache
|
|
|
140
|
+ this.rtcConnStatusCache = {};
|
|
131
|
141
|
}
|
|
132
|
142
|
|
|
133
|
143
|
/**
|
|
|
@@ -145,6 +155,12 @@ export default class ParticipantConnectionStatus {
|
|
145
|
155
|
|
|
146
|
156
|
// Filter out events for the local JID for now
|
|
147
|
157
|
if (endpointId !== this.conference.myUserId()) {
|
|
|
158
|
+
|
|
|
159
|
+ // Cache the status received received over the data channels, as
|
|
|
160
|
+ // it will be needed to verify for out of sync when the remote video
|
|
|
161
|
+ // track is being removed.
|
|
|
162
|
+ this.rtcConnStatusCache[endpointId] = isActive;
|
|
|
163
|
+
|
|
148
|
164
|
var participant = this.conference.getParticipantById(endpointId);
|
|
149
|
165
|
// Delay the 'active' event until the video track gets
|
|
150
|
166
|
// the RTC unmuted event
|
|
|
@@ -253,7 +269,64 @@ export default class ParticipantConnectionStatus {
|
|
253
|
269
|
remoteTrack.off(
|
|
254
|
270
|
JitsiTrackEvents.TRACK_MUTE_CHANGED,
|
|
255
|
271
|
this._onSignallingMuteChanged);
|
|
256
|
|
- this.clearTimeout(remoteTrack.getParticipantId());
|
|
|
272
|
+
|
|
|
273
|
+ this.clearTimeout(endpointId);
|
|
|
274
|
+
|
|
|
275
|
+ // Only if we're using video muted events - check if the JVB status
|
|
|
276
|
+ // should be restored from cache.
|
|
|
277
|
+ if (RTCBrowserType.isVideoMuteOnConnInterruptedSupported())
|
|
|
278
|
+ {
|
|
|
279
|
+ this.maybeRestoreCachedStatus(endpointId);
|
|
|
280
|
+ }
|
|
|
281
|
+ }
|
|
|
282
|
+ }
|
|
|
283
|
+
|
|
|
284
|
+ /**
|
|
|
285
|
+ * When RTC video track muted events are taken into account,
|
|
|
286
|
+ * at the point when the track is being removed we have to update
|
|
|
287
|
+ * to the current connectivity status according to the JVB. That's
|
|
|
288
|
+ * because if the current track is muted then the new one which
|
|
|
289
|
+ * replaces it is always added as unmuted and there may be no
|
|
|
290
|
+ * 'muted'/'unmuted' event sequence if the connection restores in
|
|
|
291
|
+ * the meantime.
|
|
|
292
|
+ *
|
|
|
293
|
+ * XXX See onEndpointConnStatusChanged method where the update is
|
|
|
294
|
+ * postponed and which is the cause for this workaround. If we
|
|
|
295
|
+ * decide to not wait for video unmuted event and accept the JVB
|
|
|
296
|
+ * status immediately then it's fine to remove the code below.
|
|
|
297
|
+ */
|
|
|
298
|
+ maybeRestoreCachedStatus(endpointId) {
|
|
|
299
|
+ var participant = this.conference.getParticipantById(endpointId);
|
|
|
300
|
+ if (!participant) {
|
|
|
301
|
+ // Probably the participant is no longer in the conference
|
|
|
302
|
+ // (at the time of writing this code, participant is
|
|
|
303
|
+ // detached from the conference and TRACK_REMOVED events are
|
|
|
304
|
+ // fired),
|
|
|
305
|
+ // so we don't care, but let's print the warning for
|
|
|
306
|
+ // debugging purpose
|
|
|
307
|
+ logger.warn(
|
|
|
308
|
+ 'maybeRestoreCachedStatus - ' +
|
|
|
309
|
+ 'no participant for endpoint: ' + endpointId);
|
|
|
310
|
+ return;
|
|
|
311
|
+ }
|
|
|
312
|
+
|
|
|
313
|
+ const isConnectionActive = participant.isConnectionActive();
|
|
|
314
|
+ const hasAnyVideoRTCMuted = participant.hasAnyVideoTrackWebRTCMuted();
|
|
|
315
|
+ const isConnActiveByJvb = this.rtcConnStatusCache[endpointId];
|
|
|
316
|
+
|
|
|
317
|
+ logger.debug(
|
|
|
318
|
+ "Remote track removed, is active: " + isConnectionActive
|
|
|
319
|
+ + " is active(jvb):" + isConnActiveByJvb
|
|
|
320
|
+ + " video RTC muted:" + hasAnyVideoRTCMuted);
|
|
|
321
|
+
|
|
|
322
|
+ if (!isConnectionActive && isConnActiveByJvb && !hasAnyVideoRTCMuted) {
|
|
|
323
|
+ // FIXME adjust the log level or remove the message completely once
|
|
|
324
|
+ // the feature gets mature enough.
|
|
|
325
|
+ logger.info(
|
|
|
326
|
+ "Remote track removed for disconnected" +
|
|
|
327
|
+ " participant, when the status according to" +
|
|
|
328
|
+ " the JVB is connected. Adjusting to the JVB value.");
|
|
|
329
|
+ this._changeConnectionStatus(endpointId, isConnActiveByJvb);
|
|
257
|
330
|
}
|
|
258
|
331
|
}
|
|
259
|
332
|
|