Browse Source

fix(filmstrip) Add handlers for track streaming status on RN. (#11584)

* fix(filmstrip) Add handlers for track streaming status on RN.
This is needed for switching between video and avatar when the track's streaming status changes in source-name signaling mode.

* squash: Add comment.
master
Jaya Allamsetty 3 years ago
parent
commit
ad70f12cb4
No account linked to committer's email address

+ 15
- 5
react/features/base/participants/functions.js View File

7
 import { isStageFilmstripAvailable } from '../../filmstrip/functions';
7
 import { isStageFilmstripAvailable } from '../../filmstrip/functions';
8
 import { GRAVATAR_BASE_URL, isCORSAvatarURL } from '../avatar';
8
 import { GRAVATAR_BASE_URL, isCORSAvatarURL } from '../avatar';
9
 import { getMultipleVideoSupportFeatureFlag, getSourceNameSignalingFeatureFlag } from '../config';
9
 import { getMultipleVideoSupportFeatureFlag, getSourceNameSignalingFeatureFlag } from '../config';
10
-import { JitsiParticipantConnectionStatus } from '../lib-jitsi-meet';
10
+import { JitsiParticipantConnectionStatus, JitsiTrackStreamingStatus } from '../lib-jitsi-meet';
11
 import { shouldRenderVideoTrack } from '../media';
11
 import { shouldRenderVideoTrack } from '../media';
12
 import { toState } from '../redux';
12
 import { toState } from '../redux';
13
 import { getScreenShareTrack, getVideoTrackByParticipant } from '../tracks';
13
 import { getScreenShareTrack, getVideoTrackByParticipant } from '../tracks';
484
         return false;
484
         return false;
485
     }
485
     }
486
 
486
 
487
-    /* Then check if the participant connection is active. */
488
-    const connectionStatus = participant.connectionStatus || JitsiParticipantConnectionStatus.ACTIVE;
487
+    /* Then check if the participant connection or track streaming status is active. */
488
+    if (getSourceNameSignalingFeatureFlag(state)) {
489
+        // Note that this will work only if a listener is registered for the track's TrackStreamingStatus.
490
+        // The associated TrackStreamingStatusImpl instance is not created or disposed when there are zero listeners.
491
+        if (videoTrack
492
+            && !videoTrack.local
493
+            && videoTrack.jitsiTrack?.getTrackStreamingStatus() !== JitsiTrackStreamingStatus.ACTIVE) {
494
+            return false;
495
+        }
496
+    } else {
497
+        const connectionStatus = participant.connectionStatus || JitsiParticipantConnectionStatus.ACTIVE;
489
 
498
 
490
-    if (connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE) {
491
-        return false;
499
+        if (connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE) {
500
+            return false;
501
+        }
492
     }
502
     }
493
 
503
 
494
     /* Then check if audio-only mode is not active. */
504
     /* Then check if audio-only mode is not active. */

+ 103
- 5
react/features/filmstrip/components/native/Thumbnail.js View File

4
 import { Image, View } from 'react-native';
4
 import { Image, View } from 'react-native';
5
 import type { Dispatch } from 'redux';
5
 import type { Dispatch } from 'redux';
6
 
6
 
7
-import { getMultipleVideoSupportFeatureFlag } from '../../../base/config';
7
+import { getMultipleVideoSupportFeatureFlag, getSourceNameSignalingFeatureFlag } from '../../../base/config';
8
+import { JitsiTrackEvents } from '../../../base/lib-jitsi-meet';
8
 import { MEDIA_TYPE, VIDEO_TYPE } from '../../../base/media';
9
 import { MEDIA_TYPE, VIDEO_TYPE } from '../../../base/media';
9
 import {
10
 import {
10
     PARTICIPANT_ROLE,
11
     PARTICIPANT_ROLE,
18
 } from '../../../base/participants';
19
 } from '../../../base/participants';
19
 import { Container } from '../../../base/react';
20
 import { Container } from '../../../base/react';
20
 import { connect } from '../../../base/redux';
21
 import { connect } from '../../../base/redux';
21
-import { getTrackByMediaTypeAndParticipant } from '../../../base/tracks';
22
+import {
23
+    getTrackByMediaTypeAndParticipant,
24
+    getVideoTrackByParticipant,
25
+    trackStreamingStatusChanged
26
+} from '../../../base/tracks';
22
 import { ConnectionIndicator } from '../../../connection-indicator';
27
 import { ConnectionIndicator } from '../../../connection-indicator';
23
 import { DisplayNameLabel } from '../../../display-name';
28
 import { DisplayNameLabel } from '../../../display-name';
24
 import { getGifDisplayMode, getGifForParticipant } from '../../../gifs/functions';
29
 import { getGifDisplayMode, getGifForParticipant } from '../../../gifs/functions';
109
      */
114
      */
110
     _renderModeratorIndicator: boolean,
115
     _renderModeratorIndicator: boolean,
111
 
116
 
117
+    /**
118
+     * Whether source name signaling is enabled.
119
+     */
120
+    _sourceNameSignalingEnabled: boolean,
121
+
122
+    /**
123
+     * The video track that will be displayed in the thumbnail.
124
+     */
125
+    _videoTrack: ?Object,
126
+
112
     /**
127
     /**
113
      * Invoked to trigger state changes in Redux.
128
      * Invoked to trigger state changes in Redux.
114
      */
129
      */
151
 
166
 
152
         this._onClick = this._onClick.bind(this);
167
         this._onClick = this._onClick.bind(this);
153
         this._onThumbnailLongPress = this._onThumbnailLongPress.bind(this);
168
         this._onThumbnailLongPress = this._onThumbnailLongPress.bind(this);
169
+        this.handleTrackStreamingStatusChanged = this.handleTrackStreamingStatusChanged.bind(this);
154
     }
170
     }
155
 
171
 
156
     _onClick: () => void;
172
     _onClick: () => void;
245
         return indicators;
261
         return indicators;
246
     }
262
     }
247
 
263
 
264
+    /**
265
+     * Starts listening for track streaming status updates after the initial render.
266
+     *
267
+     * @inheritdoc
268
+     * @returns {void}
269
+     */
270
+    componentDidMount() {
271
+        // Listen to track streaming status changed event to keep it updated.
272
+        // TODO: after converting this component to a react function component,
273
+        // use a custom hook to update local track streaming status.
274
+        const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
275
+
276
+        if (_sourceNameSignalingEnabled && _videoTrack && !_videoTrack.local) {
277
+            _videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
278
+                this.handleTrackStreamingStatusChanged);
279
+            dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
280
+                _videoTrack.jitsiTrack.getTrackStreamingStatus()));
281
+        }
282
+    }
283
+
284
+    /**
285
+     * Stops listening for track streaming status updates on the old track and starts listening instead on the new
286
+     * track.
287
+     *
288
+     * @inheritdoc
289
+     * @returns {void}
290
+     */
291
+    componentDidUpdate(prevProps: Props) {
292
+        // TODO: after converting this component to a react function component,
293
+        // use a custom hook to update local track streaming status.
294
+        const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
295
+
296
+        if (_sourceNameSignalingEnabled
297
+            && prevProps._videoTrack?.jitsiTrack?.getSourceName() !== _videoTrack?.jitsiTrack?.getSourceName()) {
298
+            if (prevProps._videoTrack && !prevProps._videoTrack.local) {
299
+                prevProps._videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
300
+                    this.handleTrackStreamingStatusChanged);
301
+                dispatch(trackStreamingStatusChanged(prevProps._videoTrack.jitsiTrack,
302
+                    prevProps._videoTrack.jitsiTrack.getTrackStreamingStatus()));
303
+            }
304
+            if (_videoTrack && !_videoTrack.local) {
305
+                _videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
306
+                    this.handleTrackStreamingStatusChanged);
307
+                dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
308
+                    _videoTrack.jitsiTrack.getTrackStreamingStatus()));
309
+            }
310
+        }
311
+    }
312
+
313
+    /**
314
+     * Remove listeners for track streaming status update.
315
+     *
316
+     * @inheritdoc
317
+     * @returns {void}
318
+     */
319
+    componentWillUnmount() {
320
+        // TODO: after converting this component to a react function component,
321
+        // use a custom hook to update local track streaming status.
322
+        const { _videoTrack, dispatch, _sourceNameSignalingEnabled } = this.props;
323
+
324
+        if (_sourceNameSignalingEnabled && _videoTrack && !_videoTrack.local) {
325
+            _videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
326
+                this.handleTrackStreamingStatusChanged);
327
+            dispatch(trackStreamingStatusChanged(_videoTrack.jitsiTrack,
328
+                _videoTrack.jitsiTrack.getTrackStreamingStatus()));
329
+        }
330
+    }
331
+
332
+    /**
333
+     * Handle track streaming status change event by by dispatching an action to update track streaming status for the
334
+     * given track in app state.
335
+     *
336
+     * @param {JitsiTrack} jitsiTrack - The track with streaming status updated.
337
+     * @param {JitsiTrackStreamingStatus} streamingStatus - The updated track streaming status.
338
+     * @returns {void}
339
+     */
340
+    handleTrackStreamingStatusChanged(jitsiTrack, streamingStatus) {
341
+        this.props.dispatch(trackStreamingStatusChanged(jitsiTrack, streamingStatus));
342
+    }
343
+
248
     /**
344
     /**
249
      * Implements React's {@link Component#render()}.
345
      * Implements React's {@link Component#render()}.
250
      *
346
      *
289
                     : <>
385
                     : <>
290
                         <ParticipantView
386
                         <ParticipantView
291
                             avatarSize = { tileView ? AVATAR_SIZE * 1.5 : AVATAR_SIZE }
387
                             avatarSize = { tileView ? AVATAR_SIZE * 1.5 : AVATAR_SIZE }
292
-                            disableVideo = { isScreenShare || _isFakeParticipant }
388
+                            disableVideo = { (isScreenShare && !_isVirtualScreenshare) || _isFakeParticipant }
293
                             participantId = { participantId }
389
                             participantId = { participantId }
294
                             zOrder = { 1 } />
390
                             zOrder = { 1 } />
295
                         {
391
                         {
317
     const localParticipantId = getLocalParticipant(state).id;
413
     const localParticipantId = getLocalParticipant(state).id;
318
     const id = participant?.id;
414
     const id = participant?.id;
319
     const audioTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.AUDIO, id);
415
     const audioTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.AUDIO, id);
320
-    const videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, id);
416
+    const videoTrack = getVideoTrackByParticipant(tracks, participant);
321
     const isMultiStreamSupportEnabled = getMultipleVideoSupportFeatureFlag(state);
417
     const isMultiStreamSupportEnabled = getMultipleVideoSupportFeatureFlag(state);
322
     const isScreenShare = videoTrack?.videoType === VIDEO_TYPE.DESKTOP;
418
     const isScreenShare = videoTrack?.videoType === VIDEO_TYPE.DESKTOP;
323
     const participantCount = getParticipantCount(state);
419
     const participantCount = getParticipantCount(state);
341
         _pinned: participant?.pinned,
437
         _pinned: participant?.pinned,
342
         _raisedHand: hasRaisedHand(participant),
438
         _raisedHand: hasRaisedHand(participant),
343
         _renderDominantSpeakerIndicator: renderDominantSpeakerIndicator,
439
         _renderDominantSpeakerIndicator: renderDominantSpeakerIndicator,
344
-        _renderModeratorIndicator: renderModeratorIndicator
440
+        _renderModeratorIndicator: renderModeratorIndicator,
441
+        _sourceNameSignalingEnabled: getSourceNameSignalingFeatureFlag(state),
442
+        _videoTrack: videoTrack
345
     };
443
     };
346
 }
444
 }
347
 
445
 

+ 2
- 2
react/features/filmstrip/components/web/Thumbnail.js View File

422
     }
422
     }
423
 
423
 
424
     /**
424
     /**
425
-     * Starts listening for audio level updates after the initial render.
425
+     * Starts listening for track streaming status updates after the initial render.
426
      *
426
      *
427
      * @inheritdoc
427
      * @inheritdoc
428
      * @returns {void}
428
      * @returns {void}
464
     }
464
     }
465
 
465
 
466
     /**
466
     /**
467
-     * Stops listening for audio level updates on the old track and starts
467
+     * Stops listening for track streaming status updates on the old track and starts
468
      * listening instead on the new track.
468
      * listening instead on the new track.
469
      *
469
      *
470
      * @inheritdoc
470
      * @inheritdoc

Loading…
Cancel
Save