瀏覽代碼

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,15 +6,18 @@ import UIEvents from "../../../service/UI/UIEvents";
6 6
 import LargeContainer from './LargeContainer';
7 7
 import BottomToolbar from '../toolbars/BottomToolbar';
8 8
 import Avatar from "../avatar/Avatar";
9
+import {createDeferred} from '../../util/helpers';
9 10
 
10 11
 const RTCBrowserType = require("../../RTC/RTCBrowserType");
11 12
 
12 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 18
         return;
17
-    if (stream.isLocal()) {
19
+    }
20
+    if (stream.isLocal()) { // local stream doesn't have method "getParticipantId"
18 21
         return APP.conference.localId;
19 22
     } else {
20 23
         return stream.getParticipantId();
@@ -154,9 +157,7 @@ class VideoContainer extends LargeContainer {
154 157
     }
155 158
 
156 159
     get id () {
157
-        if (this.stream) {
158
-            return getStreamId(this.stream);
159
-        }
160
+        return getStreamOwnerId(this.stream);
160 161
     }
161 162
 
162 163
     constructor (onPlay) {
@@ -267,20 +268,20 @@ class VideoContainer extends LargeContainer {
267 268
     show () {
268 269
         let $wrapper = this.$wrapper;
269 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 273
                 $('.watermark').css({visibility: 'visible'});
274
+                resolve();
273 275
             });
274
-            resolve();
275 276
         });
276 277
     }
277 278
 
278 279
     hide () {
279
-
280 280
         let $wrapper = this.$wrapper;
281 281
 
282
+        let id = this.id;
282 283
         return new Promise(function(resolve) {
283
-            $wrapper.fadeOut(300, function () {
284
+            $wrapper.fadeOut(id ? FADE_DURATION_MS : 1, function () {
284 285
                 $wrapper.css({visibility: 'hidden'});
285 286
                 $('.watermark').css({visibility: 'hidden'});
286 287
                 resolve();
@@ -356,30 +357,62 @@ export default class LargeVideoManager {
356 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 367
         let container = this.getContainer(this.state);
363 368
 
364 369
         container.hide().then(() => {
370
+            let {id, stream, videoType, resolve} = this.newStreamData;
371
+            this.newStreamData = null;
372
+
365 373
             console.info("hover in %s", id);
366 374
             this.state = VideoContainerType;
367
-            this.videoContainer.setStream(smallVideo.stream, videoType);
375
+            this.videoContainer.setStream(stream, videoType);
368 376
 
369 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 382
             // show the avatar on large if needed
374 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 416
     updateContainerSize (isSideBarVisible) {
384 417
         this.width = UIUtil.getAvailableVideoWidth(isSideBarVisible);
385 418
         this.height = window.innerHeight;
@@ -421,7 +454,6 @@ export default class LargeVideoManager {
421 454
     }
422 455
 
423 456
     showAvatar (show) {
424
-        show ? this.videoContainer.hide() : this.videoContainer.show();
425 457
         this.videoContainer.showAvatar(show);
426 458
     }
427 459
 
@@ -457,16 +489,11 @@ export default class LargeVideoManager {
457 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 495
         this.state = type;
496
+        let container = this.getContainer(type);
470 497
 
471 498
         return container.show();
472 499
     }

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

@@ -990,14 +990,15 @@ var VideoLayout = {
990 990
 
991 991
             let videoType = this.getRemoteVideoType(id);
992 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 1003
         } else if (currentId) {
1003 1004
             let currentSmallVideo = this.getSmallVideo(currentId);

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

@@ -0,0 +1,14 @@
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
+}

Loading…
取消
儲存