浏览代码

synchronize Large video fadeIn/fadeOut animations

master
isymchych 10 年前
父节点
当前提交
6cda300861
共有 3 个文件被更改,包括 78 次插入36 次删除
  1. 55
    28
      modules/UI/videolayout/LargeVideo.js
  2. 9
    8
      modules/UI/videolayout/VideoLayout.js
  3. 14
    0
      modules/util/helpers.js

+ 55
- 28
modules/UI/videolayout/LargeVideo.js 查看文件

6
 import LargeContainer from './LargeContainer';
6
 import LargeContainer from './LargeContainer';
7
 import BottomToolbar from '../toolbars/BottomToolbar';
7
 import BottomToolbar from '../toolbars/BottomToolbar';
8
 import Avatar from "../avatar/Avatar";
8
 import Avatar from "../avatar/Avatar";
9
+import {createDeferred} from '../../util/helpers';
9
 
10
 
10
 const RTCBrowserType = require("../../RTC/RTCBrowserType");
11
 const RTCBrowserType = require("../../RTC/RTCBrowserType");
11
 
12
 
12
 const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
13
 const avatarSize = interfaceConfig.DOMINANT_SPEAKER_AVATAR_SIZE;
14
+const FADE_DURATION_MS = 300;
13
 
15
 
14
-function getStreamId(stream) {
15
-    if(!stream)
16
+function getStreamOwnerId(stream) {
17
+    if (!stream) {
16
         return;
18
         return;
17
-    if (stream.isLocal()) {
19
+    }
20
+    if (stream.isLocal()) { // local stream doesn't have method "getParticipantId"
18
         return APP.conference.localId;
21
         return APP.conference.localId;
19
     } else {
22
     } else {
20
         return stream.getParticipantId();
23
         return stream.getParticipantId();
154
     }
157
     }
155
 
158
 
156
     get id () {
159
     get id () {
157
-        if (this.stream) {
158
-            return getStreamId(this.stream);
159
-        }
160
+        return getStreamOwnerId(this.stream);
160
     }
161
     }
161
 
162
 
162
     constructor (onPlay) {
163
     constructor (onPlay) {
267
     show () {
268
     show () {
268
         let $wrapper = this.$wrapper;
269
         let $wrapper = this.$wrapper;
269
         return new Promise(function(resolve) {
270
         return new Promise(function(resolve) {
270
-            $wrapper.fadeIn(300, function () {
271
-                $wrapper.css({visibility: 'visible'});
271
+            $wrapper.css({visibility: 'visible'});
272
+            $wrapper.fadeIn(FADE_DURATION_MS, function () {
272
                 $('.watermark').css({visibility: 'visible'});
273
                 $('.watermark').css({visibility: 'visible'});
274
+                resolve();
273
             });
275
             });
274
-            resolve();
275
         });
276
         });
276
     }
277
     }
277
 
278
 
278
     hide () {
279
     hide () {
279
-
280
         let $wrapper = this.$wrapper;
280
         let $wrapper = this.$wrapper;
281
 
281
 
282
+        let id = this.id;
282
         return new Promise(function(resolve) {
283
         return new Promise(function(resolve) {
283
-            $wrapper.fadeOut(300, function () {
284
+            $wrapper.fadeOut(id ? FADE_DURATION_MS : 1, function () {
284
                 $wrapper.css({visibility: 'hidden'});
285
                 $wrapper.css({visibility: 'hidden'});
285
                 $('.watermark').css({visibility: 'hidden'});
286
                 $('.watermark').css({visibility: 'hidden'});
286
                 resolve();
287
                 resolve();
356
         return this.videoContainer.id;
357
         return this.videoContainer.id;
357
     }
358
     }
358
 
359
 
359
-    updateLargeVideo (smallVideo, videoType, largeVideoUpdatedCallBack) {
360
-        let id = getStreamId(smallVideo.stream);
360
+    scheduleLargeVideoUpdate () {
361
+        if (this.updateInProcess || !this.newStreamData) {
362
+            return;
363
+        }
364
+
365
+        this.updateInProcess = true;
361
 
366
 
362
         let container = this.getContainer(this.state);
367
         let container = this.getContainer(this.state);
363
 
368
 
364
         container.hide().then(() => {
369
         container.hide().then(() => {
370
+            let {id, stream, videoType, resolve} = this.newStreamData;
371
+            this.newStreamData = null;
372
+
365
             console.info("hover in %s", id);
373
             console.info("hover in %s", id);
366
             this.state = VideoContainerType;
374
             this.state = VideoContainerType;
367
-            this.videoContainer.setStream(smallVideo.stream, videoType);
375
+            this.videoContainer.setStream(stream, videoType);
368
 
376
 
369
             // change the avatar url on large
377
             // change the avatar url on large
370
-            this.updateAvatar(Avatar.getAvatarUrl(smallVideo.id));
378
+            this.updateAvatar(Avatar.getAvatarUrl(id));
379
+
380
+            let isVideoMuted = stream.isMuted();
371
 
381
 
372
-            var isVideoMuted = smallVideo.stream.isMuted()
373
             // show the avatar on large if needed
382
             // show the avatar on large if needed
374
             this.videoContainer.showAvatar(isVideoMuted);
383
             this.videoContainer.showAvatar(isVideoMuted);
375
 
384
 
376
-            if (!isVideoMuted)
377
-                this.videoContainer.show();
385
+            // do not show stream if video is muted
386
+            let promise = isVideoMuted ? Promise.resolve() : this.videoContainer.show();
378
 
387
 
379
-            largeVideoUpdatedCallBack();
388
+            // resolve updateLargeVideo promise after everything is done
389
+            promise.then(resolve);
390
+
391
+            return promise;
392
+        }).then(() => {
393
+            // after everything is done check again if there are any pending new streams.
394
+            this.updateInProcess = false;
395
+            this.scheduleLargeVideoUpdate();
380
         });
396
         });
381
     }
397
     }
382
 
398
 
399
+    updateLargeVideo (stream, videoType) {
400
+        let id = getStreamOwnerId(stream);
401
+
402
+        if (this.newStreamData) {
403
+            this.newStreamData.reject();
404
+        }
405
+
406
+        this.newStreamData = createDeferred();
407
+        this.newStreamData.id = id;
408
+        this.newStreamData.stream = stream;
409
+        this.newStreamData.videoType = videoType;
410
+
411
+        this.scheduleLargeVideoUpdate();
412
+
413
+        return this.newStreamData.promise;
414
+    }
415
+
383
     updateContainerSize (isSideBarVisible) {
416
     updateContainerSize (isSideBarVisible) {
384
         this.width = UIUtil.getAvailableVideoWidth(isSideBarVisible);
417
         this.width = UIUtil.getAvailableVideoWidth(isSideBarVisible);
385
         this.height = window.innerHeight;
418
         this.height = window.innerHeight;
421
     }
454
     }
422
 
455
 
423
     showAvatar (show) {
456
     showAvatar (show) {
424
-        show ? this.videoContainer.hide() : this.videoContainer.show();
425
         this.videoContainer.showAvatar(show);
457
         this.videoContainer.showAvatar(show);
426
     }
458
     }
427
 
459
 
457
             return Promise.resolve();
489
             return Promise.resolve();
458
         }
490
         }
459
 
491
 
460
-        let container = this.getContainer(type);
461
-
462
-        if (this.state) {
463
-            let oldContainer = this.containers[this.state];
464
-            if (oldContainer) {
465
-                oldContainer.hide();
466
-            }
467
-        }
492
+        let oldContainer = this.containers[this.state];
493
+        oldContainer.hide();
468
 
494
 
469
         this.state = type;
495
         this.state = type;
496
+        let container = this.getContainer(type);
470
 
497
 
471
         return container.show();
498
         return container.show();
472
     }
499
     }

+ 9
- 8
modules/UI/videolayout/VideoLayout.js 查看文件

990
 
990
 
991
             let videoType = this.getRemoteVideoType(id);
991
             let videoType = this.getRemoteVideoType(id);
992
             largeVideo.updateLargeVideo(
992
             largeVideo.updateLargeVideo(
993
-                smallVideo,
994
-                videoType,
995
-                // LargeVideoUpdatedCallBack
996
-                function() {
997
-                    // update current small video and the old one
998
-                    smallVideo.updateView();
999
-                    oldSmallVideo && oldSmallVideo.updateView();
1000
-                });
993
+                smallVideo.stream,
994
+                videoType
995
+            ).then(function() {
996
+                // update current small video and the old one
997
+                smallVideo.updateView();
998
+                oldSmallVideo && oldSmallVideo.updateView();
999
+            }, function () {
1000
+                // use clicked other video during update, nothing to do.
1001
+            });
1001
 
1002
 
1002
         } else if (currentId) {
1003
         } else if (currentId) {
1003
             let currentSmallVideo = this.getSmallVideo(currentId);
1004
             let currentSmallVideo = this.getSmallVideo(currentId);

+ 14
- 0
modules/util/helpers.js 查看文件

1
+/**
2
+ * Create deferred object.
3
+ * @returns {{promise, resolve, reject}}
4
+ */
5
+export function createDeferred () {
6
+    let deferred = {};
7
+
8
+    deferred.promise = new Promise(function (resolve, reject) {
9
+        deferred.resolve = resolve;
10
+        deferred.reject = reject;
11
+    });
12
+
13
+    return deferred;
14
+}

正在加载...
取消
保存