ソースを参照

abstract out remoteVideos management

j8
isymchych 9年前
コミット
b375b14696

+ 4
- 3
modules/UI/UI.js ファイルの表示

88
 function setupToolbars() {
88
 function setupToolbars() {
89
     Toolbar.init(eventEmitter);
89
     Toolbar.init(eventEmitter);
90
     Toolbar.setupButtonsFromConfig();
90
     Toolbar.setupButtonsFromConfig();
91
-    BottomToolbar.init(eventEmitter);
91
+    BottomToolbar.setupListeners(eventEmitter);
92
 }
92
 }
93
 
93
 
94
 /**
94
 /**
246
 
246
 
247
     registerListeners();
247
     registerListeners();
248
 
248
 
249
+    BottomToolbar.init();
250
+
249
     VideoLayout.init(eventEmitter);
251
     VideoLayout.init(eventEmitter);
250
     if (!interfaceConfig.filmStripOnly) {
252
     if (!interfaceConfig.filmStripOnly) {
251
         VideoLayout.initLargeVideo(PanelToggler.isVisible());
253
         VideoLayout.initLargeVideo(PanelToggler.isVisible());
277
         $("#header").css("display", "none");
279
         $("#header").css("display", "none");
278
         $("#bottomToolbar").css("display", "none");
280
         $("#bottomToolbar").css("display", "none");
279
         $("#downloadlog").css("display", "none");
281
         $("#downloadlog").css("display", "none");
280
-        $("#remoteVideos").css("padding", "0px 0px 18px 0px");
281
-        $("#remoteVideos").css("right", "0px");
282
+        BottomToolbar.setupFilmStripOnly();
282
         messageHandler.disableNotifications();
283
         messageHandler.disableNotifications();
283
         $('body').popover("disable");
284
         $('body').popover("disable");
284
         JitsiPopover.enabled = false;
285
         JitsiPopover.enabled = false;

+ 12
- 31
modules/UI/audio_levels/AudioLevels.js ファイルの表示

2
 /* jshint -W101 */
2
 /* jshint -W101 */
3
 
3
 
4
 import CanvasUtil from './CanvasUtils';
4
 import CanvasUtil from './CanvasUtils';
5
+import BottomToolbar from '../toolbars/BottomToolbar';
5
 
6
 
6
 const LOCAL_LEVEL = 'local';
7
 const LOCAL_LEVEL = 'local';
7
 
8
 
126
      * Updates the audio level canvas for the given id. If the canvas
127
      * Updates the audio level canvas for the given id. If the canvas
127
      * didn't exist we create it.
128
      * didn't exist we create it.
128
      */
129
      */
129
-    updateAudioLevelCanvas (id, VideoLayout) {
130
+    updateAudioLevelCanvas (id, thumbWidth, thumbHeight) {
130
         let videoSpanId = 'localVideoContainer';
131
         let videoSpanId = 'localVideoContainer';
131
         if (id) {
132
         if (id) {
132
             videoSpanId = `participant_${id}`;
133
             videoSpanId = `participant_${id}`;
145
 
146
 
146
         let audioLevelCanvas = $(`#${videoSpanId}>canvas`);
147
         let audioLevelCanvas = $(`#${videoSpanId}>canvas`);
147
 
148
 
148
-        let videoSpaceWidth = $('#remoteVideos').width();
149
-        let thumbnailSize = VideoLayout.calculateThumbnailSize(videoSpaceWidth);
150
-        let thumbnailWidth = thumbnailSize[0];
151
-        let thumbnailHeight = thumbnailSize[1];
152
-
153
         if (!audioLevelCanvas || audioLevelCanvas.length === 0) {
149
         if (!audioLevelCanvas || audioLevelCanvas.length === 0) {
154
 
150
 
155
             audioLevelCanvas = document.createElement('canvas');
151
             audioLevelCanvas = document.createElement('canvas');
156
             audioLevelCanvas.className = "audiolevel";
152
             audioLevelCanvas.className = "audiolevel";
157
             audioLevelCanvas.style.bottom = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
153
             audioLevelCanvas.style.bottom = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
158
             audioLevelCanvas.style.left = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
154
             audioLevelCanvas.style.left = `-${interfaceConfig.CANVAS_EXTRA/2}px`;
159
-            resizeAudioLevelCanvas(audioLevelCanvas, thumbnailWidth, thumbnailHeight);
155
+            resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
160
 
156
 
161
             videoSpan.appendChild(audioLevelCanvas);
157
             videoSpan.appendChild(audioLevelCanvas);
162
         } else {
158
         } else {
163
             audioLevelCanvas = audioLevelCanvas.get(0);
159
             audioLevelCanvas = audioLevelCanvas.get(0);
164
 
160
 
165
-            resizeAudioLevelCanvas(audioLevelCanvas, thumbnailWidth, thumbnailHeight);
161
+            resizeAudioLevelCanvas(audioLevelCanvas, thumbWidth, thumbHeight);
166
         }
162
         }
167
     },
163
     },
168
 
164
 
223
         ASDrawContext.fill();
219
         ASDrawContext.fill();
224
     },
220
     },
225
 
221
 
226
-    /**
227
-     * Indicates that the remote video has been resized.
228
-     */
229
-    onRemoteVideoResized (width, height) {
230
-        let resized = false;
231
-
232
-        $('#remoteVideos>span>canvas').each(function() {
233
-            let canvas = $(this).get(0);
234
-            if (canvas.width !== width + interfaceConfig.CANVAS_EXTRA) {
235
-                canvas.width = width + interfaceConfig.CANVAS_EXTRA;
236
-                resized = true;
237
-            }
222
+    updateCanvasSize (thumbWidth, thumbHeight) {
223
+        let canvasWidth = thumbWidth + interfaceConfig.CANVAS_EXTRA;
224
+        let canvasHeight = thumbHeight + interfaceConfig.CANVAS_EXTRA;
238
 
225
 
239
-            if (canvas.height !== height + interfaceConfig.CANVAS_EXTRA) {
240
-                canvas.height = height + interfaceConfig.CANVAS_EXTRA;
241
-                resized = true;
242
-            }
243
-        });
226
+        BottomToolbar.getThumbs().children('canvas').width(canvasWidth).height(canvasHeight);
244
 
227
 
245
-        if (resized) {
246
-            Object.keys(audioLevelCanvasCache).forEach(function (id) {
247
-                audioLevelCanvasCache[id].width = width + interfaceConfig.CANVAS_EXTRA;
248
-                audioLevelCanvasCache[id].height = height + interfaceConfig.CANVAS_EXTRA;
249
-            });
250
-        }
228
+        Object.keys(audioLevelCanvasCache).forEach(function (id) {
229
+            audioLevelCanvasCache[id].width = canvasWidth;
230
+            audioLevelCanvasCache[id].height = canvasHeight;
231
+        });
251
     }
232
     }
252
 };
233
 };
253
 
234
 

+ 2
- 3
modules/UI/etherpad/Etherpad.js ファイルの表示

4
 import LargeContainer from '../videolayout/LargeContainer';
4
 import LargeContainer from '../videolayout/LargeContainer';
5
 import UIUtil from "../util/UIUtil";
5
 import UIUtil from "../util/UIUtil";
6
 import SidePanelToggler from "../side_pannels/SidePanelToggler";
6
 import SidePanelToggler from "../side_pannels/SidePanelToggler";
7
+import BottomToolbar from '../toolbars/BottomToolbar';
7
 
8
 
8
 const options = $.param({
9
 const options = $.param({
9
     showControns: true,
10
     showControns: true,
88
     }
89
     }
89
 
90
 
90
     resize (containerWidth, containerHeight, animate) {
91
     resize (containerWidth, containerHeight, animate) {
91
-        let remoteVideos = $('#remoteVideos');
92
-
93
-        let height = containerHeight - remoteVideos.outerHeight();
92
+        let height = containerHeight - BottomToolbar.getFilmStripHeight();
94
         let width = containerWidth;
93
         let width = containerWidth;
95
 
94
 
96
         $(this.iframe).width(width).height(height);
95
         $(this.iframe).width(width).height(height);

+ 2
- 2
modules/UI/prezi/Prezi.js ファイルの表示

9
 import messageHandler from '../util/MessageHandler';
9
 import messageHandler from '../util/MessageHandler';
10
 import ToolbarToggler from "../toolbars/ToolbarToggler";
10
 import ToolbarToggler from "../toolbars/ToolbarToggler";
11
 import SidePanelToggler from "../side_pannels/SidePanelToggler";
11
 import SidePanelToggler from "../side_pannels/SidePanelToggler";
12
+import BottomToolbar from '../toolbars/BottomToolbar';
12
 
13
 
13
 const defaultPreziLink = "http://prezi.com/wz7vhjycl7e6/my-prezi";
14
 const defaultPreziLink = "http://prezi.com/wz7vhjycl7e6/my-prezi";
14
 const alphanumRegex = /^[a-z0-9-_\/&\?=;]+$/i;
15
 const alphanumRegex = /^[a-z0-9-_\/&\?=;]+$/i;
244
     }
245
     }
245
 
246
 
246
     resize (containerWidth, containerHeight) {
247
     resize (containerWidth, containerHeight) {
247
-        let remoteVideos = $('#remoteVideos');
248
-        let height = containerHeight - remoteVideos.outerHeight();
248
+        let height = containerHeight - BottomToolbar.getFilmStripHeight();
249
 
249
 
250
         let width = containerWidth;
250
         let width = containerWidth;
251
 
251
 

+ 66
- 6
modules/UI/toolbars/BottomToolbar.js ファイルの表示

10
 };
10
 };
11
 
11
 
12
 const BottomToolbar = {
12
 const BottomToolbar = {
13
-    init (emitter) {
13
+    init () {
14
+        this.filmStrip = $('#remoteVideos');
15
+        this.toolbar = $('#bottomToolbar');
16
+    },
17
+
18
+    setupListeners (emitter) {
14
         UIUtil.hideDisabledButtons(defaultBottomToolbarButtons);
19
         UIUtil.hideDisabledButtons(defaultBottomToolbarButtons);
15
 
20
 
16
         const buttonHandlers = {
21
         const buttonHandlers = {
34
     },
39
     },
35
 
40
 
36
     toggleFilmStrip () {
41
     toggleFilmStrip () {
37
-        $("#remoteVideos").toggleClass("hidden");
42
+        this.filmStrip.toggleClass("hidden");
43
+    },
44
+
45
+    isFilmStripVisible () {
46
+        return !this.filmStrip.hasClass('hidden');
47
+    },
48
+
49
+    setupFilmStripOnly () {
50
+        this.filmStrip.css({
51
+            padding: "0px 0px 18px 0px",
52
+            right: 0
53
+        });
54
+    },
55
+
56
+    getFilmStripHeight () {
57
+        if (this.isFilmStripVisible()) {
58
+            return this.filmStrip.outerHeight();
59
+        } else {
60
+            return 0;
61
+        }
62
+    },
63
+
64
+    getFilmStripWidth () {
65
+        return this.filmStrip.width();
66
+    },
67
+
68
+    resizeThumbnails (thumbWidth, thumbHeight, animate = false) {
69
+        return new Promise(resolve => {
70
+            this.filmStrip.animate({
71
+                // adds 2 px because of small video 1px border
72
+                height: thumbHeight + 2
73
+            }, {
74
+                queue: false,
75
+                duration: animate ? 500 : 0
76
+            });
77
+
78
+            this.getThumbs().animate({
79
+                height: thumbHeight,
80
+                width: thumbWidth
81
+            }, {
82
+                queue: false,
83
+                duration: animate ? 500 : 0,
84
+                complete:  resolve
85
+            });
86
+
87
+            if (!animate) {
88
+                resolve();
89
+            }
90
+        });
91
+    },
92
+
93
+    resizeToolbar (thumbWidth, thumbHeight) {
94
+        let bottom = (thumbHeight - this.toolbar.outerHeight())/2 + 18;
95
+        this.toolbar.css({bottom});
38
     },
96
     },
39
 
97
 
40
-    onRemoteVideoResized (width, height) {
41
-        let toolbar = $('#bottomToolbar');
42
-        let bottom = (height - toolbar.outerHeight())/2 + 18;
98
+    getThumbs (visible = false) {
99
+        let selector = 'span';
100
+        if (visible) {
101
+            selector += ':visible';
102
+        }
43
 
103
 
44
-        toolbar.css({bottom});
104
+        return this.filmStrip.children(selector);
45
     }
105
     }
46
 };
106
 };
47
 
107
 

+ 2
- 1
modules/UI/toolbars/ToolbarToggler.js ファイルの表示

1
 /* global APP, config, $, interfaceConfig */
1
 /* global APP, config, $, interfaceConfig */
2
 
2
 
3
 import UIUtil from '../util/UIUtil';
3
 import UIUtil from '../util/UIUtil';
4
+import BottomToolbar from './BottomToolbar';
4
 
5
 
5
 let toolbarTimeoutObject;
6
 let toolbarTimeoutObject;
6
 let toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
7
 let toolbarTimeout = interfaceConfig.INITIAL_TOOLBAR_TIMEOUT;
47
     } else {
48
     } else {
48
         header.hide("slide", { direction: "up", duration: 300});
49
         header.hide("slide", { direction: "up", duration: 300});
49
         $('#subject').animate({top: "-=40"}, 300);
50
         $('#subject').animate({top: "-=40"}, 300);
50
-        if ($("#remoteVideos").hasClass("hidden")) {
51
+        if (!BottomToolbar.isFilmStripVisible()) {
51
             bottomToolbar.hide(
52
             bottomToolbar.hide(
52
                 "slide", {direction: "right", duration: 300}
53
                 "slide", {direction: "right", duration: 300}
53
             );
54
             );

+ 2
- 4
modules/UI/videolayout/LargeVideo.js ファイルの表示

4
 import UIUtil from "../util/UIUtil";
4
 import UIUtil from "../util/UIUtil";
5
 import UIEvents from "../../../service/UI/UIEvents";
5
 import UIEvents from "../../../service/UI/UIEvents";
6
 import LargeContainer from './LargeContainer';
6
 import LargeContainer from './LargeContainer';
7
+import BottomToolbar from '../toolbars/BottomToolbar';
7
 
8
 
8
 const RTCBrowserType = require("../../RTC/RTCBrowserType");
9
 const RTCBrowserType = require("../../RTC/RTCBrowserType");
9
 
10
 
34
     let availableWidth = Math.max(videoWidth, videoSpaceWidth);
35
     let availableWidth = Math.max(videoWidth, videoSpaceWidth);
35
     let availableHeight = Math.max(videoHeight, videoSpaceHeight);
36
     let availableHeight = Math.max(videoHeight, videoSpaceHeight);
36
 
37
 
37
-    let filmstrip = $("#remoteVideos");
38
-
39
-    if (!filmstrip.hasClass("hidden"))
40
-        videoSpaceHeight -= filmstrip.outerHeight();
38
+    videoSpaceHeight -= BottomToolbar.getFilmStripHeight();
41
 
39
 
42
     if (availableWidth / aspectRatio >= videoSpaceHeight) {
40
     if (availableWidth / aspectRatio >= videoSpaceHeight) {
43
         availableHeight = videoSpaceHeight;
41
         availableHeight = videoSpaceHeight;

+ 2
- 1
modules/UI/videolayout/RemoteVideo.js ファイルの表示

34
     if (APP.conference.isModerator) {
34
     if (APP.conference.isModerator) {
35
         this.addRemoteVideoMenu();
35
         this.addRemoteVideoMenu();
36
     }
36
     }
37
-    AudioLevels.updateAudioLevelCanvas(this.id, this.VideoLayout);
37
+    let {thumbWidth, thumbHeight} = this.VideoLayout.calculateThumbnailSize();
38
+    AudioLevels.updateAudioLevelCanvas(this.id, thumbWidth, thumbHeight);
38
 
39
 
39
     return this.container;
40
     return this.container;
40
 };
41
 };

+ 40
- 49
modules/UI/videolayout/VideoLayout.js ファイルの表示

34
  */
34
  */
35
 var focusedVideoResourceJid = null;
35
 var focusedVideoResourceJid = null;
36
 
36
 
37
+const thumbAspectRatio = 16.0 / 9.0;
38
+
37
 /**
39
 /**
38
  * On contact list item clicked.
40
  * On contact list item clicked.
39
  */
41
  */
153
         let localId = APP.conference.localId;
155
         let localId = APP.conference.localId;
154
         this.onVideoTypeChanged(localId, stream.getType());
156
         this.onVideoTypeChanged(localId, stream.getType());
155
 
157
 
156
-        AudioLevels.updateAudioLevelCanvas(null, VideoLayout);
158
+        let {thumbWidth, thumbHeight} = this.calculateThumbnailSize();
159
+        AudioLevels.updateAudioLevelCanvas(null, thumbWidth, thumbHeight);
157
 
160
 
158
         localVideoThumbnail.changeVideo(stream);
161
         localVideoThumbnail.changeVideo(stream);
159
 
162
 
215
     electLastVisibleVideo () {
218
     electLastVisibleVideo () {
216
         // pick the last visible video in the row
219
         // pick the last visible video in the row
217
         // if nobody else is left, this picks the local video
220
         // if nobody else is left, this picks the local video
218
-        let pick = $('#remoteVideos>span[id!="mixedstream"]:visible:last');
219
-        if (pick.length) {
220
-            let id = getPeerContainerResourceId(pick[0]);
221
+        let thumbs = BottomToolbar.getThumbs(true).filter('id!="mixedstream"');
222
+
223
+        let lastVisible = thumbs.filter(':visible:last');
224
+        if (lastVisible.length) {
225
+            let id = getPeerContainerResourceId(lastVisible[0]);
221
             if (remoteVideos[id]) {
226
             if (remoteVideos[id]) {
222
                 console.info("electLastVisibleVideo: " + id);
227
                 console.info("electLastVisibleVideo: " + id);
223
                 return id;
228
                 return id;
227
         }
232
         }
228
 
233
 
229
         console.info("Last visible video no longer exists");
234
         console.info("Last visible video no longer exists");
230
-        pick = $('#remoteVideos>span[id!="mixedstream"]');
231
-        if (pick.length) {
232
-            let id = getPeerContainerResourceId(pick[0]);
235
+        thumbs = BottomToolbar.getThumbs();
236
+        if (thumbs.length) {
237
+            let id = getPeerContainerResourceId(thumbs[0]);
233
             if (remoteVideos[id]) {
238
             if (remoteVideos[id]) {
234
                 console.info("electLastVisibleVideo: " + id);
239
                 console.info("electLastVisibleVideo: " + id);
235
                 return id;
240
                 return id;
332
 
337
 
333
         // In case this is not currently in the last n we don't show it.
338
         // In case this is not currently in the last n we don't show it.
334
         if (localLastNCount && localLastNCount > 0 &&
339
         if (localLastNCount && localLastNCount > 0 &&
335
-            $('#remoteVideos>span').length >= localLastNCount + 2) {
340
+            BottomToolbar.getThumbs().length >= localLastNCount + 2) {
336
             remoteVideo.showPeerContainer('hide');
341
             remoteVideo.showPeerContainer('hide');
337
         } else {
342
         } else {
338
             VideoLayout.resizeThumbnails();
343
             VideoLayout.resizeThumbnails();
419
      * Resizes thumbnails.
424
      * Resizes thumbnails.
420
      */
425
      */
421
     resizeThumbnails (animate = false) {
426
     resizeThumbnails (animate = false) {
422
-        let videoSpaceWidth = $('#remoteVideos').width();
427
+        let {thumbWidth, thumbHeight} = this.calculateThumbnailSize();
423
 
428
 
424
-        let [width, height] = this.calculateThumbnailSize(videoSpaceWidth);
429
+        $('.userAvatar').css('left', (thumbWidth - thumbHeight) / 2);
425
 
430
 
426
-        $('.userAvatar').css('left', (width - height) / 2);
427
-
428
-        $('#remoteVideos').animate({
429
-            // adds 2 px because of small video 1px border
430
-            height: height + 2
431
-        }, {
432
-            queue: false,
433
-            duration: animate ? 500 : 0
434
-        });
435
-
436
-        $('#remoteVideos>span').animate({
437
-            height, width
438
-        }, {
439
-            queue: false,
440
-            duration: animate ? 500 : 0,
441
-            complete: function () {
442
-                BottomToolbar.onRemoteVideoResized(width, height);
443
-                AudioLevels.onRemoteVideoResized(width, height);
444
-            }
431
+        BottomToolbar.resizeThumbnails(thumbWidth, thumbHeight, animate).then(function () {
432
+            BottomToolbar.resizeToolbar(thumbWidth, thumbHeight);
433
+            AudioLevels.updateCanvasSize(thumbWidth, thumbHeight);
445
         });
434
         });
446
     },
435
     },
447
 
436
 
448
     /**
437
     /**
449
      * Calculates the thumbnail size.
438
      * Calculates the thumbnail size.
450
      *
439
      *
451
-     * @param videoSpaceWidth the width of the video space
452
      */
440
      */
453
-    calculateThumbnailSize (videoSpaceWidth) {
441
+    calculateThumbnailSize () {
442
+        let videoSpaceWidth = BottomToolbar.getFilmStripWidth();
454
         // Calculate the available height, which is the inner window height
443
         // Calculate the available height, which is the inner window height
455
         // minus 39px for the header minus 2px for the delimiter lines on the
444
         // minus 39px for the header minus 2px for the delimiter lines on the
456
         // top and bottom of the large video, minus the 36px space inside the
445
         // top and bottom of the large video, minus the 36px space inside the
457
         // remoteVideos container used for highlighting shadow.
446
         // remoteVideos container used for highlighting shadow.
458
-       var availableHeight = 100;
447
+        let availableHeight = 100;
459
 
448
 
460
-        var numvids = $('#remoteVideos>span:visible').length;
449
+        let numvids = BottomToolbar.getThumbs().length;
461
         if (localLastNCount && localLastNCount > 0) {
450
         if (localLastNCount && localLastNCount > 0) {
462
             numvids = Math.min(localLastNCount + 1, numvids);
451
             numvids = Math.min(localLastNCount + 1, numvids);
463
         }
452
         }
464
 
453
 
465
-       // Remove the 3px borders arround videos and border around the remote
466
-       // videos area and the 4 pixels between the local video and the others
467
-       //TODO: Find out where the 4 pixels come from and remove them
468
-       var availableWinWidth = videoSpaceWidth - 2 * 3 * numvids - 70 - 4;
454
+        // Remove the 3px borders arround videos and border around the remote
455
+        // videos area and the 4 pixels between the local video and the others
456
+        //TODO: Find out where the 4 pixels come from and remove them
457
+        let availableWinWidth = videoSpaceWidth - 2 * 3 * numvids - 70 - 4;
469
 
458
 
470
-       var availableWidth = availableWinWidth / numvids;
471
-       var aspectRatio = 16.0 / 9.0;
472
-       var maxHeight = Math.min(160, availableHeight);
473
-       availableHeight
474
-           = Math.min(  maxHeight,
475
-                        availableWidth / aspectRatio,
476
-                        window.innerHeight - 18);
459
+        let availableWidth = availableWinWidth / numvids;
460
+        let maxHeight = Math.min(160, availableHeight);
461
+        availableHeight
462
+            = Math.min(  maxHeight,
463
+                         availableWidth / thumbAspectRatio,
464
+                         window.innerHeight - 18);
477
 
465
 
478
-       if (availableHeight < availableWidth / aspectRatio) {
479
-           availableWidth = Math.floor(availableHeight * aspectRatio);
480
-       }
466
+        if (availableHeight < availableWidth / thumbAspectRatio) {
467
+            availableWidth = Math.floor(availableHeight * thumbAspectRatio);
468
+        }
481
 
469
 
482
-       return [availableWidth, availableHeight];
470
+        return {
471
+            thumbWidth: availableWidth,
472
+            thumbHeight: availableHeight
473
+        };
483
    },
474
    },
484
 
475
 
485
     /**
476
     /**
623
         var updateLargeVideo = false;
614
         var updateLargeVideo = false;
624
 
615
 
625
         // Handle LastN/local LastN changes.
616
         // Handle LastN/local LastN changes.
626
-        $('#remoteVideos>span').each(function( index, element ) {
617
+        BottomToolbar.getThumbs().each(function( index, element ) {
627
             var resourceJid = getPeerContainerResourceId(element);
618
             var resourceJid = getPeerContainerResourceId(element);
628
 
619
 
629
             // We do not want to process any logic for our own(local) video
620
             // We do not want to process any logic for our own(local) video

読み込み中…
キャンセル
保存