Browse Source

fix(largeVideo): update don't depend on thumbnails

master
Hristo Terezov 4 years ago
parent
commit
4fda428be1

+ 0
- 13
conference.js View File

19
     createDeviceChangedEvent,
19
     createDeviceChangedEvent,
20
     createStartSilentEvent,
20
     createStartSilentEvent,
21
     createScreenSharingEvent,
21
     createScreenSharingEvent,
22
-    createStreamSwitchDelayEvent,
23
     createTrackMutedEvent,
22
     createTrackMutedEvent,
24
     sendAnalytics
23
     sendAnalytics
25
 } from './react/features/analytics';
24
 } from './react/features/analytics';
2263
             });
2262
             });
2264
         });
2263
         });
2265
 
2264
 
2266
-        /* eslint-disable max-params */
2267
-        APP.UI.addListener(
2268
-            UIEvents.RESOLUTION_CHANGED,
2269
-            (id, oldResolution, newResolution, delay) => {
2270
-                sendAnalytics(createStreamSwitchDelayEvent(
2271
-                    {
2272
-                        'old_resolution': oldResolution,
2273
-                        'new_resolution': newResolution,
2274
-                        value: delay
2275
-                    }));
2276
-            });
2277
-
2278
         APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
2265
         APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
2279
             AuthHandler.authenticate(room);
2266
             AuthHandler.authenticate(room);
2280
         });
2267
         });

+ 0
- 9
modules/UI/UI.js View File

322
     eventEmitter.emit(UIEvents.NICKNAME_CHANGED, newDisplayName);
322
     eventEmitter.emit(UIEvents.NICKNAME_CHANGED, newDisplayName);
323
 };
323
 };
324
 
324
 
325
-/**
326
- * Return the type of the remote video.
327
- * @param jid the jid for the remote video
328
- * @returns the video type video or screen.
329
- */
330
-UI.getRemoteVideoType = function(jid) {
331
-    return VideoLayout.getRemoteVideoType(jid);
332
-};
333
-
334
 // FIXME check if someone user this
325
 // FIXME check if someone user this
335
 UI.showLoginPopup = function(callback) {
326
 UI.showLoginPopup = function(callback) {
336
     logger.log('password is required');
327
     logger.log('password is required');

+ 0
- 1
modules/UI/shared_video/SharedVideoThumb.js View File

19
         this.id = participant.id;
19
         this.id = participant.id;
20
         this.isLocal = false;
20
         this.isLocal = false;
21
         this.url = participant.id;
21
         this.url = participant.id;
22
-        this.setVideoType(videoType);
23
         this.videoSpanId = 'sharedVideoContainer';
22
         this.videoSpanId = 'sharedVideoContainer';
24
         this.container = this.createContainer(this.videoSpanId);
23
         this.container = this.createContainer(this.videoSpanId);
25
         this.$container = $(this.container);
24
         this.$container = $(this.container);

+ 0
- 4
modules/UI/videolayout/RemoteVideo.js View File

481
 
481
 
482
         isVideo ? this.videoStream = stream : this.audioStream = stream;
482
         isVideo ? this.videoStream = stream : this.audioStream = stream;
483
 
483
 
484
-        if (isVideo) {
485
-            this.setVideoType(stream.videoType);
486
-        }
487
-
488
         if (!stream.getOriginalStream()) {
484
         if (!stream.getOriginalStream()) {
489
             logger.debug('Remote video stream has no original stream');
485
             logger.debug('Remote video stream has no original stream');
490
 
486
 

+ 1
- 58
modules/UI/videolayout/SmallVideo.js View File

32
 
32
 
33
 const logger = require('jitsi-meet-logger').getLogger(__filename);
33
 const logger = require('jitsi-meet-logger').getLogger(__filename);
34
 
34
 
35
-import UIEvents from '../../../service/UI/UIEvents';
36
-
37
 /**
35
 /**
38
  * Display mode constant used when video is being displayed on the small video.
36
  * Display mode constant used when video is being displayed on the small video.
39
  * @type {number}
37
  * @type {number}
158
         return this.$container.is(':visible');
156
         return this.$container.is(':visible');
159
     }
157
     }
160
 
158
 
161
-    /**
162
-     * Sets the type of the video displayed by this instance.
163
-     * Note that this is a string without clearly defined or checked values, and
164
-     * it is NOT one of the strings defined in service/RTC/VideoType in
165
-     * lib-jitsi-meet.
166
-     * @param videoType 'camera' or 'desktop', or 'sharedvideo'.
167
-     */
168
-    setVideoType(videoType) {
169
-        this.videoType = videoType;
170
-    }
171
-
172
-    /**
173
-     * Returns the type of the video displayed by this instance.
174
-     * Note that this is a string without clearly defined or checked values, and
175
-     * it is NOT one of the strings defined in service/RTC/VideoType in
176
-     * lib-jitsi-meet.
177
-     * @returns {String} 'camera', 'screen', 'sharedvideo', or undefined.
178
-     */
179
-    getVideoType() {
180
-        return this.videoType;
181
-    }
182
-
183
     /**
159
     /**
184
      * Creates an audio or video element for a particular MediaStream.
160
      * Creates an audio or video element for a particular MediaStream.
185
      */
161
      */
452
      * or <tt>false</tt> otherwise.
428
      * or <tt>false</tt> otherwise.
453
      */
429
      */
454
     isCurrentlyOnLargeVideo() {
430
     isCurrentlyOnLargeVideo() {
455
-        return this.VideoLayout.isCurrentlyOnLarge(this.id);
431
+        return APP.store.getState()['features/large-video']?.participantId === this.id;
456
     }
432
     }
457
 
433
 
458
     /**
434
     /**
640
         this.updateIndicators();
616
         this.updateIndicators();
641
     }
617
     }
642
 
618
 
643
-    /**
644
-     * Adds a listener for onresize events for this video, which will monitor for
645
-     * resolution changes, will calculate the delay since the moment the listened
646
-     * is added, and will fire a RESOLUTION_CHANGED event.
647
-     */
648
-    waitForResolutionChange() {
649
-        const beforeChange = window.performance.now();
650
-        const videos = this.selectVideoElement();
651
-
652
-        if (!videos || !videos.length || videos.length <= 0) {
653
-            return;
654
-        }
655
-        const video = videos[0];
656
-        const oldWidth = video.videoWidth;
657
-        const oldHeight = video.videoHeight;
658
-
659
-        video.onresize = () => {
660
-            // eslint-disable-next-line eqeqeq
661
-            if (video.videoWidth != oldWidth || video.videoHeight != oldHeight) {
662
-                // Only run once.
663
-                video.onresize = null;
664
-
665
-                const delay = window.performance.now() - beforeChange;
666
-                const emitter = this.VideoLayout.getEventEmitter();
667
-
668
-                if (emitter) {
669
-                    emitter.emit(UIEvents.RESOLUTION_CHANGED, this.getId(), `${oldWidth}x${oldHeight}`,
670
-                        `${video.videoWidth}x${video.videoHeight}`, delay);
671
-                }
672
-            }
673
-        };
674
-    }
675
-
676
     /**
619
     /**
677
      * Initalizes any browser specific properties. Currently sets the overflow
620
      * Initalizes any browser specific properties. Currently sets the overflow
678
      * property for Qt browsers on Windows to hidden, thus fixing the following
621
      * property for Qt browsers on Windows to hidden, thus fixing the following

+ 20
- 67
modules/UI/videolayout/VideoLayout.js View File

1
 /* global APP, $, interfaceConfig  */
1
 /* global APP, $, interfaceConfig  */
2
 const logger = require('jitsi-meet-logger').getLogger(__filename);
2
 const logger = require('jitsi-meet-logger').getLogger(__filename);
3
 
3
 
4
-import { VIDEO_TYPE } from '../../../react/features/base/media';
4
+import { MEDIA_TYPE, VIDEO_TYPE } from '../../../react/features/base/media';
5
 import {
5
 import {
6
     getLocalParticipant as getLocalParticipantFromStore,
6
     getLocalParticipant as getLocalParticipantFromStore,
7
     getPinnedParticipant,
7
     getPinnedParticipant,
8
+    getParticipantById,
8
     pinParticipant
9
     pinParticipant
9
 } from '../../../react/features/base/participants';
10
 } from '../../../react/features/base/participants';
11
+import { getTrackByMediaTypeAndParticipant } from '../../../react/features/base/tracks';
10
 import { SHARED_VIDEO_CONTAINER_TYPE } from '../shared_video/SharedVideo';
12
 import { SHARED_VIDEO_CONTAINER_TYPE } from '../shared_video/SharedVideo';
11
 import SharedVideoThumb from '../shared_video/SharedVideoThumb';
13
 import SharedVideoThumb from '../shared_video/SharedVideoThumb';
12
 
14
 
73
             emitter,
75
             emitter,
74
             this._updateLargeVideoIfDisplayed.bind(this));
76
             this._updateLargeVideoIfDisplayed.bind(this));
75
 
77
 
76
-        // sets default video type of local video
77
-        // FIXME container type is totally different thing from the video type
78
-        localVideoThumbnail.setVideoType(VIDEO_CONTAINER_TYPE);
79
         this.registerListeners();
78
         this.registerListeners();
80
     },
79
     },
81
 
80
 
221
      * @returns {String} the video type video or screen.
220
      * @returns {String} the video type video or screen.
222
      */
221
      */
223
     getRemoteVideoType(id) {
222
     getRemoteVideoType(id) {
224
-        const smallVideo = VideoLayout.getSmallVideo(id);
223
+        const state = APP.store.getState();
224
+        const participant = getParticipantById(state, id);
225
+
226
+        if (participant?.isFakeParticipant) {
227
+            return SHARED_VIDEO_CONTAINER_TYPE;
228
+        }
225
 
229
 
230
+        const videoTrack = getTrackByMediaTypeAndParticipant(state['features/base/tracks'], MEDIA_TYPE.VIDEO, id);
226
 
231
 
227
-        return smallVideo ? smallVideo.getVideoType() : null;
232
+        return videoTrack?.videoType;
228
     },
233
     },
229
 
234
 
230
     isPinned(id) {
235
     isPinned(id) {
308
     addRemoteVideoContainer(id, remoteVideo) {
313
     addRemoteVideoContainer(id, remoteVideo) {
309
         remoteVideos[id] = remoteVideo;
314
         remoteVideos[id] = remoteVideo;
310
 
315
 
311
-        if (!remoteVideo.getVideoType()) {
312
-            // make video type the default one (camera)
313
-            // FIXME container type is not a video type
314
-            remoteVideo.setVideoType(VIDEO_CONTAINER_TYPE);
315
-        }
316
-
317
         // Initialize the view
316
         // Initialize the view
318
         remoteVideo.updateView();
317
         remoteVideo.updateView();
319
     },
318
     },
491
 
490
 
492
         logger.info('Peer video type changed: ', id, newVideoType);
491
         logger.info('Peer video type changed: ', id, newVideoType);
493
 
492
 
494
-        let smallVideo;
495
-
496
-        if (APP.conference.isLocalId(id)) {
497
-            if (!localVideoThumbnail) {
498
-                logger.warn('Local video not ready yet');
499
-
500
-                return;
501
-            }
502
-            smallVideo = localVideoThumbnail;
503
-        } else if (remoteVideos[id]) {
504
-            smallVideo = remoteVideos[id];
505
-        } else {
506
-            return;
507
-        }
508
-        smallVideo.setVideoType(newVideoType);
509
-
510
         this._updateLargeVideoIfDisplayed(id, true);
493
         this._updateLargeVideoIfDisplayed(id, true);
511
     },
494
     },
512
 
495
 
584
         }
567
         }
585
         const currentContainer = largeVideo.getCurrentContainer();
568
         const currentContainer = largeVideo.getCurrentContainer();
586
         const currentContainerType = largeVideo.getCurrentContainerType();
569
         const currentContainerType = largeVideo.getCurrentContainerType();
587
-        const currentId = largeVideo.id;
588
         const isOnLarge = this.isCurrentlyOnLarge(id);
570
         const isOnLarge = this.isCurrentlyOnLarge(id);
589
-        const smallVideo = this.getSmallVideo(id);
571
+        const state = APP.store.getState();
572
+        const videoTrack = getTrackByMediaTypeAndParticipant(state['features/base/tracks'], MEDIA_TYPE.VIDEO, id);
573
+        const videoStream = videoTrack?.jitsiTrack;
590
 
574
 
591
         if (isOnLarge && !forceUpdate
575
         if (isOnLarge && !forceUpdate
592
                 && LargeVideoManager.isVideoContainer(currentContainerType)
576
                 && LargeVideoManager.isVideoContainer(currentContainerType)
593
-                && smallVideo) {
577
+                && videoStream) {
594
             const currentStreamId = currentContainer.getStreamID();
578
             const currentStreamId = currentContainer.getStreamID();
595
-            const newStreamId
596
-                = smallVideo.videoStream
597
-                    ? smallVideo.videoStream.getId() : null;
579
+            const newStreamId = videoStream?.getId() || null;
598
 
580
 
599
             // FIXME it might be possible to get rid of 'forceUpdate' argument
581
             // FIXME it might be possible to get rid of 'forceUpdate' argument
600
             if (currentStreamId !== newStreamId) {
582
             if (currentStreamId !== newStreamId) {
603
             }
585
             }
604
         }
586
         }
605
 
587
 
606
-        if ((!isOnLarge || forceUpdate) && smallVideo) {
588
+        if (!isOnLarge || forceUpdate) {
607
             const videoType = this.getRemoteVideoType(id);
589
             const videoType = this.getRemoteVideoType(id);
608
 
590
 
609
-            // FIXME video type is not the same thing as container type
610
-
611
-            if (id !== currentId && videoType === VIDEO_CONTAINER_TYPE) {
612
-                APP.API.notifyOnStageParticipantChanged(id);
613
-            }
614
-
615
-            let oldSmallVideo;
616
-
617
-            if (currentId) {
618
-                oldSmallVideo = this.getSmallVideo(currentId);
619
-            }
620
-
621
-            smallVideo.waitForResolutionChange();
622
-            if (oldSmallVideo) {
623
-                oldSmallVideo.waitForResolutionChange();
624
-            }
625
 
591
 
626
             largeVideo.updateLargeVideo(
592
             largeVideo.updateLargeVideo(
627
                 id,
593
                 id,
628
-                smallVideo.videoStream,
594
+                videoStream,
629
                 videoType || VIDEO_TYPE.CAMERA
595
                 videoType || VIDEO_TYPE.CAMERA
630
-            ).then(() => {
631
-                // update current small video and the old one
632
-                smallVideo.updateView();
633
-                oldSmallVideo && oldSmallVideo.updateView();
634
-            }, () => {
635
-                // use clicked other video during update, nothing to do.
596
+            ).catch(() => {
597
+                // do nothing
636
             });
598
             });
637
-
638
-        } else if (currentId) {
639
-            const currentSmallVideo = this.getSmallVideo(currentId);
640
-
641
-            currentSmallVideo && currentSmallVideo.updateView();
642
         }
599
         }
643
     },
600
     },
644
 
601
 
723
         this.localFlipX = val;
680
         this.localFlipX = val;
724
     },
681
     },
725
 
682
 
726
-    getEventEmitter() {
727
-        return eventEmitter;
728
-    },
729
-
730
     /**
683
     /**
731
      * Handles user's features changes.
684
      * Handles user's features changes.
732
      */
685
      */

+ 0
- 15
react/features/analytics/AnalyticsEvents.js View File

688
     };
688
     };
689
 }
689
 }
690
 
690
 
691
-/**
692
- * Creates an event which indicates the delay for switching between simulcast
693
- * streams.
694
- *
695
- * @param {Object} attributes - Attributes to attach to the event.
696
- * @returns {Object} The event in a format suitable for sending via
697
- * sendAnalytics.
698
- */
699
-export function createStreamSwitchDelayEvent(attributes) {
700
-    return {
701
-        action: 'stream.switch.delay',
702
-        attributes
703
-    };
704
-}
705
-
706
 /**
691
 /**
707
  * Automatically changing the mute state of a media track in order to match
692
  * Automatically changing the mute state of a media track in order to match
708
  * the current stored state in redux.
693
  * the current stored state in redux.

+ 4
- 0
react/features/base/tracks/middleware.js View File

129
         // TODO Remove the following calls to APP.UI once components interested
129
         // TODO Remove the following calls to APP.UI once components interested
130
         // in track mute changes are moved into React and/or redux.
130
         // in track mute changes are moved into React and/or redux.
131
         if (typeof APP !== 'undefined') {
131
         if (typeof APP !== 'undefined') {
132
+            const result = next(action);
133
+
132
             const { jitsiTrack } = action.track;
134
             const { jitsiTrack } = action.track;
133
             const muted = jitsiTrack.isMuted();
135
             const muted = jitsiTrack.isMuted();
134
             const participantID = jitsiTrack.getParticipantId();
136
             const participantID = jitsiTrack.getParticipantId();
151
             } else {
153
             } else {
152
                 APP.UI.setAudioMuted(participantID, muted);
154
                 APP.UI.setAudioMuted(participantID, muted);
153
             }
155
             }
156
+
157
+            return result;
154
         }
158
         }
155
 
159
 
156
     }
160
     }

+ 17
- 0
react/features/external-api/subscriber.js View File

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { MEDIA_TYPE, VIDEO_TYPE } from '../base/media';
3
 import { getLocalParticipant } from '../base/participants';
4
 import { getLocalParticipant } from '../base/participants';
4
 import { StateListenerRegistry } from '../base/redux';
5
 import { StateListenerRegistry } from '../base/redux';
6
+import { getTrackByMediaTypeAndParticipant } from '../base/tracks';
5
 import { appendSuffix } from '../display-name';
7
 import { appendSuffix } from '../display-name';
6
 import { shouldDisplayTileView } from '../video-layout';
8
 import { shouldDisplayTileView } from '../video-layout';
7
 
9
 
37
             });
39
             });
38
         }
40
         }
39
     });
41
     });
42
+
43
+/**
44
+ * Updates the on stage participant value.
45
+ */
46
+StateListenerRegistry.register(
47
+    /* selector */ state => state['features/large-video'].participantId,
48
+    /* listener */ (participantId, store) => {
49
+        const videoTrack = getTrackByMediaTypeAndParticipant(
50
+            store.getState()['features/base/tracks'], MEDIA_TYPE.VIDEO, participantId);
51
+
52
+        if (videoTrack && videoTrack.videoType === VIDEO_TYPE.CAMERA) {
53
+            APP.API.notifyOnStageParticipantChanged(participantId);
54
+        }
55
+    }
56
+);

+ 20
- 0
react/features/filmstrip/subscriber.web.js View File

2
 
2
 
3
 import { StateListenerRegistry, equals } from '../base/redux';
3
 import { StateListenerRegistry, equals } from '../base/redux';
4
 import Filmstrip from '../../../modules/UI/videolayout/Filmstrip';
4
 import Filmstrip from '../../../modules/UI/videolayout/Filmstrip';
5
+import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
5
 import { getCurrentLayout, getTileViewGridDimensions, shouldDisplayTileView, LAYOUTS } from '../video-layout';
6
 import { getCurrentLayout, getTileViewGridDimensions, shouldDisplayTileView, LAYOUTS } from '../video-layout';
6
 
7
 
7
 import { setHorizontalViewDimensions, setTileViewDimensions } from './actions';
8
 import { setHorizontalViewDimensions, setTileViewDimensions } from './actions';
56
             break;
57
             break;
57
         }
58
         }
58
     });
59
     });
60
+
61
+/**
62
+ * Handles on stage participant updates.
63
+ */
64
+StateListenerRegistry.register(
65
+    /* selector */ state => state['features/large-video'].participantId,
66
+    /* listener */ (participantId, store, oldParticipantId) => {
67
+        const newThumbnail = VideoLayout.getSmallVideo(participantId);
68
+        const oldThumbnail = VideoLayout.getSmallVideo(oldParticipantId);
69
+
70
+        if (newThumbnail) {
71
+            newThumbnail.updateView();
72
+        }
73
+
74
+        if (oldThumbnail) {
75
+            oldThumbnail.updateView();
76
+        }
77
+    }
78
+);

+ 0
- 4
service/UI/UIEvents.js View File

53
      */
53
      */
54
     LOCAL_FLIPX_CHANGED: 'UI.local_flipx_changed',
54
     LOCAL_FLIPX_CHANGED: 'UI.local_flipx_changed',
55
 
55
 
56
-    // An event which indicates that the resolution of a remote video has
57
-    // changed.
58
-    RESOLUTION_CHANGED: 'UI.resolution_changed',
59
-
60
     /**
56
     /**
61
      * Notifies that the button "Cancel" is pressed on the dialog for
57
      * Notifies that the button "Cancel" is pressed on the dialog for
62
      * external extension installation.
58
      * external extension installation.

Loading…
Cancel
Save