浏览代码

Selects the way how large video is measured based on current video type(camera or desktop). Makes sure that whole desktop video will be displayed. Removes redundant event handlers.

master
paweldomas 11 年前
父节点
当前提交
cc03ace1b4
共有 1 个文件被更改,包括 125 次插入42 次删除
  1. 125
    42
      app.js

+ 125
- 42
app.js 查看文件

8
 var sharedKey = '';
8
 var sharedKey = '';
9
 var roomUrl = null;
9
 var roomUrl = null;
10
 var ssrc2jid = {};
10
 var ssrc2jid = {};
11
+
12
+/**
13
+ * Indicates whether ssrc is camera video or desktop stream.
14
+ * FIXME: remove those maps
15
+ */
16
+var ssrc2videoType = {};
17
+var videoSrcToSsrc = {};
18
+
11
 var localVideoSrc = null;
19
 var localVideoSrc = null;
12
 var flipXLocalVideo = true;
20
 var flipXLocalVideo = true;
13
 var isFullScreen = false;
21
 var isFullScreen = false;
14
 var toolbarTimeout = null;
22
 var toolbarTimeout = null;
15
 var currentVideoWidth = null;
23
 var currentVideoWidth = null;
16
 var currentVideoHeight = null;
24
 var currentVideoHeight = null;
25
+/**
26
+ * Method used to calculate large video size.
27
+ * @type {function()}
28
+ */
29
+var getVideoSize;
17
 
30
 
18
 /* window.onbeforeunload = closePageWarning; */
31
 /* window.onbeforeunload = closePageWarning; */
19
 
32
 
173
     localVideo.volume = 0; // is it required if audio is separated ?
186
     localVideo.volume = 0; // is it required if audio is separated ?
174
     localVideo.oncontextmenu = function () { return false; };
187
     localVideo.oncontextmenu = function () { return false; };
175
 
188
 
176
-    localVideo.addEventListener('loadedmetadata', function(e){
177
-        positionLarge(this.videoWidth, this.videoHeight);
178
-    });
179
-
180
     var localVideoContainer = document.getElementById('localVideoWrapper');
189
     var localVideoContainer = document.getElementById('localVideoWrapper');
181
     localVideoContainer.appendChild(localVideo);
190
     localVideoContainer.appendChild(localVideo);
182
 
191
 
201
 }
210
 }
202
 
211
 
203
 $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
212
 $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
204
-    function waitForRemoteVideo(selector, sid) {
213
+    function waitForRemoteVideo(selector, sid, ssrc) {
205
         if(selector.removed) {
214
         if(selector.removed) {
206
             console.warn("media removed before had started", selector);
215
             console.warn("media removed before had started", selector);
207
             return;
216
             return;
208
         }
217
         }
209
         var sess = connection.jingle.sessions[sid];
218
         var sess = connection.jingle.sessions[sid];
210
         if (data.stream.id === 'mixedmslabel') return;
219
         if (data.stream.id === 'mixedmslabel') return;
211
-        videoTracks = data.stream.getVideoTracks();
220
+        var videoTracks = data.stream.getVideoTracks();
212
         console.log("waiting..", videoTracks, selector[0]);
221
         console.log("waiting..", videoTracks, selector[0]);
213
         if (videoTracks.length === 0 || selector[0].currentTime > 0) {
222
         if (videoTracks.length === 0 || selector[0].currentTime > 0) {
214
             RTC.attachMediaStream(selector, data.stream); // FIXME: why do i have to do this for FF?
223
             RTC.attachMediaStream(selector, data.stream); // FIXME: why do i have to do this for FF?
224
+
225
+            // FIXME: add a class that will associate peer Jid, video.src, it's ssrc and video type
226
+            //        in order to get rid of too many maps
227
+            if(ssrc) {
228
+                videoSrcToSsrc[sel.attr('src')] = ssrc;
229
+            } else {
230
+                console.warn("No ssrc given for video", sel);
231
+            }
232
+
215
             $(document).trigger('callactive.jingle', [selector, sid]);
233
             $(document).trigger('callactive.jingle', [selector, sid]);
216
             console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
234
             console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
217
         } else {
235
         } else {
218
-            setTimeout(function () { waitForRemoteVideo(selector, sid); }, 250);
236
+            setTimeout(function () { waitForRemoteVideo(selector, sid, ssrc); }, 250);
219
         }
237
         }
220
     }
238
     }
221
     var sess = connection.jingle.sessions[sid];
239
     var sess = connection.jingle.sessions[sid];
222
 
240
 
241
+    var thessrc;
223
     // look up an associated JID for a stream id
242
     // look up an associated JID for a stream id
224
     if (data.stream.id.indexOf('mixedmslabel') === -1) {
243
     if (data.stream.id.indexOf('mixedmslabel') === -1) {
225
         var ssrclines = SDPUtil.find_lines(sess.peerconnection.remoteDescription.sdp, 'a=ssrc');
244
         var ssrclines = SDPUtil.find_lines(sess.peerconnection.remoteDescription.sdp, 'a=ssrc');
272
     vid.autoplay = true;
291
     vid.autoplay = true;
273
     vid.oncontextmenu = function () { return false; };
292
     vid.oncontextmenu = function () { return false; };
274
 
293
 
275
-    vid.addEventListener('loadedmetadata', function(e){
276
-        positionLarge(this.videoWidth, this.videoHeight);
277
-    });
278
-
279
     container.appendChild(vid);
294
     container.appendChild(vid);
280
-    var sel = $('#' + id);
281
-    sel.hide();
282
-    RTC.attachMediaStream(sel, data.stream);
283
-    waitForRemoteVideo(sel, sid);
284
 
295
 
285
     // TODO: make mixedstream display:none via css?
296
     // TODO: make mixedstream display:none via css?
286
     if (id.indexOf('mixedmslabel') !== -1) {
297
     if (id.indexOf('mixedmslabel') !== -1) {
293
     RTC.attachMediaStream(sel, data.stream);
304
     RTC.attachMediaStream(sel, data.stream);
294
 
305
 
295
     if(isVideo) {
306
     if(isVideo) {
296
-        waitForRemoteVideo(sel, sid);
307
+        waitForRemoteVideo(sel, sid, thessrc);
297
     }
308
     }
298
 
309
 
299
     data.stream.onended = function () {
310
     data.stream.onended = function () {
592
 
603
 
593
     $(pres).find('>media[xmlns="http://estos.de/ns/mjs"]>source').each(function (idx, ssrc) {
604
     $(pres).find('>media[xmlns="http://estos.de/ns/mjs"]>source').each(function (idx, ssrc) {
594
         //console.log(jid, 'assoc ssrc', ssrc.getAttribute('type'), ssrc.getAttribute('ssrc'));
605
         //console.log(jid, 'assoc ssrc', ssrc.getAttribute('type'), ssrc.getAttribute('ssrc'));
606
+        // Fixme: direction and video types are unhandled here(maybe something more)
595
         ssrc2jid[ssrc.getAttribute('ssrc')] = jid;
607
         ssrc2jid[ssrc.getAttribute('ssrc')] = jid;
596
     });
608
     });
597
 });
609
 });
632
        if(ssrc2jid[ssrc] == jid){
644
        if(ssrc2jid[ssrc] == jid){
633
            delete ssrc2jid[ssrc];
645
            delete ssrc2jid[ssrc];
634
        }
646
        }
647
+       if(ssrc2videoType == jid){
648
+           delete  ssrc2videoType[ssrc];
649
+       }
635
     });
650
     });
636
 
651
 
637
     $(pres).find('>media[xmlns="http://estos.de/ns/mjs"]>source').each(function (idx, ssrc) {
652
     $(pres).find('>media[xmlns="http://estos.de/ns/mjs"]>source').each(function (idx, ssrc) {
638
         //console.log(jid, 'assoc ssrc', ssrc.getAttribute('type'), ssrc.getAttribute('ssrc'));
653
         //console.log(jid, 'assoc ssrc', ssrc.getAttribute('type'), ssrc.getAttribute('ssrc'));
639
-        ssrc2jid[ssrc.getAttribute('ssrc')] = jid;
654
+        var ssrcV = ssrc.getAttribute('ssrc');
655
+        ssrc2jid[ssrcV] = jid;
640
 
656
 
641
         var type = ssrc.getAttribute('type');
657
         var type = ssrc.getAttribute('type');
658
+        ssrc2videoType[ssrcV] = type;
659
+
642
         // might need to update the direction if participant just went from sendrecv to recvonly
660
         // might need to update the direction if participant just went from sendrecv to recvonly
643
         if (type === 'video' || type === 'screen') {
661
         if (type === 'video' || type === 'screen') {
644
             var el = $('#participant_'  + Strophe.getResourceFromJid(jid) + '>video');
662
             var el = $('#participant_'  + Strophe.getResourceFromJid(jid) + '>video');
652
                 //checkChangeLargeVideo(el);
670
                 //checkChangeLargeVideo(el);
653
                 break;
671
                 break;
654
             }
672
             }
655
-            // Camera video or shared screen ?
656
-            if (type === 'screen') {
657
-                // Shared screen
658
-                //console.info("Have screen ssrc from "+jid, ssrc);
659
-            } else {
660
-                // Camera video
661
-                //console.info("Have camera ssrc from "+jid, ssrc);
662
-            }
663
         }
673
         }
664
     });
674
     });
665
 
675
 
705
     console.log('hover in', newSrc);
715
     console.log('hover in', newSrc);
706
 
716
 
707
     if ($('#largeVideo').attr('src') != newSrc) {
717
     if ($('#largeVideo').attr('src') != newSrc) {
708
-        document.getElementById('largeVideo')
709
-            .addEventListener('loadedmetadata', function(e){
710
-                currentVideoWidth = this.videoWidth;
711
-                currentVideoHeight = this.videoHeight;
712
-        });
713
 
718
 
714
         var isVisible = $('#largeVideo').is(':visible');
719
         var isVisible = $('#largeVideo').is(':visible');
715
 
720
 
727
                 document.getElementById('largeVideo').style.webkitTransform = "none";
732
                 document.getElementById('largeVideo').style.webkitTransform = "none";
728
             }
733
             }
729
 
734
 
735
+            // Change the way we'll be measuring large video
736
+            getVideoSize = isVideoSrcDesktop(newSrc) ? getVideoSizeFit : getVideoSizeCover;
737
+
730
             if (isVisible)
738
             if (isVisible)
731
                 $(this).fadeIn(300);
739
                 $(this).fadeIn(300);
732
         });
740
         });
733
     }
741
     }
734
 }
742
 }
735
 
743
 
744
+/**
745
+ * Checks if video identified by given src is desktop stream.
746
+ * @param videoSrc eg. blob:https%3A//pawel.jitsi.net/9a46e0bd-131e-4d18-9c14-a9264e8db395
747
+ * @returns {boolean}
748
+ */
749
+function isVideoSrcDesktop(videoSrc){
750
+    // FIXME: fix this mapping mess...
751
+    // figure out if large video is desktop stream or just a camera
752
+    var isDesktop = false;
753
+    if(localVideoSrc === videoSrc) {
754
+        // local video
755
+        isDesktop = isUsingScreenStream;
756
+    } else {
757
+        // Do we have associations...
758
+        var videoSsrc = videoSrcToSsrc[videoSrc];
759
+        if(videoSsrc) {
760
+            var videoType = ssrc2videoType[videoSsrc];
761
+            if(videoType) {
762
+                // Finally there...
763
+                isDesktop = videoType === 'screen';
764
+            } else {
765
+                console.error("No video type for ssrc: " + videoSsrc);
766
+            }
767
+        } else {
768
+            console.error("No ssrc for src: " + videoSrc);
769
+        }
770
+    }
771
+    return isDesktop;
772
+}
773
+
736
 /**
774
 /**
737
  * Shows/hides the large video.
775
  * Shows/hides the large video.
738
  */
776
  */
799
                                     videoSpaceWidth,
837
                                     videoSpaceWidth,
800
                                     videoSpaceHeight);
838
                                     videoSpaceHeight);
801
 
839
 
802
-    var availableWidth = videoSize[0];
803
-    var availableHeight = videoSize[1];
840
+    var largeVideoWidth = videoSize[0];
841
+    var largeVideoHeight = videoSize[1];
804
 
842
 
805
-    var videoPosition = getVideoPosition(   availableWidth,
806
-                                            availableHeight,
843
+    var videoPosition = getVideoPosition(   largeVideoWidth,
844
+                                            largeVideoHeight,
807
                                             videoSpaceWidth,
845
                                             videoSpaceWidth,
808
                                             videoSpaceHeight);
846
                                             videoSpaceHeight);
809
 
847
 
811
     var verticalIndent = videoPosition[1];
849
     var verticalIndent = videoPosition[1];
812
 
850
 
813
     positionVideo(  $('#largeVideo'),
851
     positionVideo(  $('#largeVideo'),
814
-                    availableWidth,
815
-                    availableHeight,
852
+                    largeVideoWidth,
853
+                    largeVideoHeight,
816
                     horizontalIndent, verticalIndent);
854
                     horizontalIndent, verticalIndent);
817
 };
855
 };
818
 
856
 
843
 };
881
 };
844
 
882
 
845
 /**
883
 /**
846
- * Returns an array of the video dimensions, so that if fits the screen.
884
+ * Returns an array of the video dimensions, so that it covers the screen.
885
+ * It leaves no empty areas, but some parts of the video might not be visible.
847
  *
886
  *
848
  * @return an array with 2 elements, the video width and the video height
887
  * @return an array with 2 elements, the video width and the video height
849
  */
888
  */
850
-var getVideoSize = function(videoWidth,
851
-                            videoHeight,
852
-                            videoSpaceWidth,
853
-                            videoSpaceHeight) {
889
+function getVideoSizeCover(videoWidth,
890
+                           videoHeight,
891
+                           videoSpaceWidth,
892
+                           videoSpaceHeight) {
854
     if (!videoWidth)
893
     if (!videoWidth)
855
         videoWidth = currentVideoWidth;
894
         videoWidth = currentVideoWidth;
856
     if (!videoHeight)
895
     if (!videoHeight)
872
     }
911
     }
873
 
912
 
874
     return [availableWidth, availableHeight];
913
     return [availableWidth, availableHeight];
875
-};
914
+}
915
+
916
+/**
917
+ * Returns an array of the video dimensions, so that it keeps it's aspect ratio and fits available area with it's
918
+ * larger dimension. This method ensures that whole video will be visible and can leave empty areas.
919
+ *
920
+ * @return an array with 2 elements, the video width and the video height
921
+ */
922
+function getVideoSizeFit(videoWidth,
923
+                                   videoHeight,
924
+                                   videoSpaceWidth,
925
+                                   videoSpaceHeight) {
926
+    if (!videoWidth)
927
+        videoWidth = currentVideoWidth;
928
+    if (!videoHeight)
929
+        videoHeight = currentVideoHeight;
930
+
931
+    var aspectRatio = videoWidth / videoHeight;
932
+
933
+    var availableWidth = Math.max(videoWidth, videoSpaceWidth);
934
+    var availableHeight = Math.max(videoHeight, videoSpaceHeight);
935
+
936
+    if (availableWidth / aspectRatio >= videoSpaceHeight) {
937
+        availableHeight = videoSpaceHeight;
938
+        availableWidth = availableHeight*aspectRatio;
939
+    }
940
+
941
+    if (availableHeight*aspectRatio >= videoSpaceWidth) {
942
+        availableWidth = videoSpaceWidth;
943
+        availableHeight = availableWidth / aspectRatio;
944
+    }
945
+
946
+    return [availableWidth, availableHeight];
947
+}
876
 
948
 
877
 /**
949
 /**
878
  * Sets the size and position of the given video element.
950
  * Sets the size and position of the given video element.
945
     // Set default desktop sharing method
1017
     // Set default desktop sharing method
946
     setDesktopSharing(config.desktopSharing);
1018
     setDesktopSharing(config.desktopSharing);
947
 
1019
 
1020
+    // By default we cover the whole screen with video
1021
+    getVideoSize = getVideoSizeCover;
1022
+
948
     resizeLargeVideoContainer();
1023
     resizeLargeVideoContainer();
949
     $(window).resize(function () {
1024
     $(window).resize(function () {
950
         resizeLargeVideoContainer();
1025
         resizeLargeVideoContainer();
951
         positionLarge();
1026
         positionLarge();
952
     });
1027
     });
1028
+    // Listen for large video size updates
1029
+    document.getElementById('largeVideo')
1030
+        .addEventListener('loadedmetadata', function(e){
1031
+            currentVideoWidth = this.videoWidth;
1032
+            currentVideoHeight = this.videoHeight;
1033
+            positionLarge(currentVideoWidth, currentVideoHeight);
1034
+        });
1035
+
953
     if (!$('#settings').is(':visible')) {
1036
     if (!$('#settings').is(':visible')) {
954
         console.log('init');
1037
         console.log('init');
955
         init();
1038
         init();

正在加载...
取消
保存