Ver código fonte

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.

j8
paweldomas 11 anos atrás
pai
commit
cc03ace1b4
1 arquivos alterados com 125 adições e 42 exclusões
  1. 125
    42
      app.js

+ 125
- 42
app.js Ver arquivo

@@ -8,12 +8,25 @@ var nickname = null;
8 8
 var sharedKey = '';
9 9
 var roomUrl = null;
10 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 19
 var localVideoSrc = null;
12 20
 var flipXLocalVideo = true;
13 21
 var isFullScreen = false;
14 22
 var toolbarTimeout = null;
15 23
 var currentVideoWidth = null;
16 24
 var currentVideoHeight = null;
25
+/**
26
+ * Method used to calculate large video size.
27
+ * @type {function()}
28
+ */
29
+var getVideoSize;
17 30
 
18 31
 /* window.onbeforeunload = closePageWarning; */
19 32
 
@@ -173,10 +186,6 @@ function change_local_video(stream, flipX) {
173 186
     localVideo.volume = 0; // is it required if audio is separated ?
174 187
     localVideo.oncontextmenu = function () { return false; };
175 188
 
176
-    localVideo.addEventListener('loadedmetadata', function(e){
177
-        positionLarge(this.videoWidth, this.videoHeight);
178
-    });
179
-
180 189
     var localVideoContainer = document.getElementById('localVideoWrapper');
181 190
     localVideoContainer.appendChild(localVideo);
182 191
 
@@ -201,25 +210,35 @@ function change_local_video(stream, flipX) {
201 210
 }
202 211
 
203 212
 $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
204
-    function waitForRemoteVideo(selector, sid) {
213
+    function waitForRemoteVideo(selector, sid, ssrc) {
205 214
         if(selector.removed) {
206 215
             console.warn("media removed before had started", selector);
207 216
             return;
208 217
         }
209 218
         var sess = connection.jingle.sessions[sid];
210 219
         if (data.stream.id === 'mixedmslabel') return;
211
-        videoTracks = data.stream.getVideoTracks();
220
+        var videoTracks = data.stream.getVideoTracks();
212 221
         console.log("waiting..", videoTracks, selector[0]);
213 222
         if (videoTracks.length === 0 || selector[0].currentTime > 0) {
214 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 233
             $(document).trigger('callactive.jingle', [selector, sid]);
216 234
             console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
217 235
         } else {
218
-            setTimeout(function () { waitForRemoteVideo(selector, sid); }, 250);
236
+            setTimeout(function () { waitForRemoteVideo(selector, sid, ssrc); }, 250);
219 237
         }
220 238
     }
221 239
     var sess = connection.jingle.sessions[sid];
222 240
 
241
+    var thessrc;
223 242
     // look up an associated JID for a stream id
224 243
     if (data.stream.id.indexOf('mixedmslabel') === -1) {
225 244
         var ssrclines = SDPUtil.find_lines(sess.peerconnection.remoteDescription.sdp, 'a=ssrc');
@@ -272,15 +291,7 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
272 291
     vid.autoplay = true;
273 292
     vid.oncontextmenu = function () { return false; };
274 293
 
275
-    vid.addEventListener('loadedmetadata', function(e){
276
-        positionLarge(this.videoWidth, this.videoHeight);
277
-    });
278
-
279 294
     container.appendChild(vid);
280
-    var sel = $('#' + id);
281
-    sel.hide();
282
-    RTC.attachMediaStream(sel, data.stream);
283
-    waitForRemoteVideo(sel, sid);
284 295
 
285 296
     // TODO: make mixedstream display:none via css?
286 297
     if (id.indexOf('mixedmslabel') !== -1) {
@@ -293,7 +304,7 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
293 304
     RTC.attachMediaStream(sel, data.stream);
294 305
 
295 306
     if(isVideo) {
296
-        waitForRemoteVideo(sel, sid);
307
+        waitForRemoteVideo(sel, sid, thessrc);
297 308
     }
298 309
 
299 310
     data.stream.onended = function () {
@@ -592,6 +603,7 @@ $(document).bind('entered.muc', function (event, jid, info, pres) {
592 603
 
593 604
     $(pres).find('>media[xmlns="http://estos.de/ns/mjs"]>source').each(function (idx, ssrc) {
594 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 607
         ssrc2jid[ssrc.getAttribute('ssrc')] = jid;
596 608
     });
597 609
 });
@@ -632,13 +644,19 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
632 644
        if(ssrc2jid[ssrc] == jid){
633 645
            delete ssrc2jid[ssrc];
634 646
        }
647
+       if(ssrc2videoType == jid){
648
+           delete  ssrc2videoType[ssrc];
649
+       }
635 650
     });
636 651
 
637 652
     $(pres).find('>media[xmlns="http://estos.de/ns/mjs"]>source').each(function (idx, ssrc) {
638 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 657
         var type = ssrc.getAttribute('type');
658
+        ssrc2videoType[ssrcV] = type;
659
+
642 660
         // might need to update the direction if participant just went from sendrecv to recvonly
643 661
         if (type === 'video' || type === 'screen') {
644 662
             var el = $('#participant_'  + Strophe.getResourceFromJid(jid) + '>video');
@@ -652,14 +670,6 @@ $(document).bind('presence.muc', function (event, jid, info, pres) {
652 670
                 //checkChangeLargeVideo(el);
653 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,11 +715,6 @@ function updateLargeVideo(newSrc, vol) {
705 715
     console.log('hover in', newSrc);
706 716
 
707 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 719
         var isVisible = $('#largeVideo').is(':visible');
715 720
 
@@ -727,12 +732,45 @@ function updateLargeVideo(newSrc, vol) {
727 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 738
             if (isVisible)
731 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 775
  * Shows/hides the large video.
738 776
  */
@@ -799,11 +837,11 @@ var positionLarge = function(videoWidth, videoHeight) {
799 837
                                     videoSpaceWidth,
800 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 845
                                             videoSpaceWidth,
808 846
                                             videoSpaceHeight);
809 847
 
@@ -811,8 +849,8 @@ var positionLarge = function(videoWidth, videoHeight) {
811 849
     var verticalIndent = videoPosition[1];
812 850
 
813 851
     positionVideo(  $('#largeVideo'),
814
-                    availableWidth,
815
-                    availableHeight,
852
+                    largeVideoWidth,
853
+                    largeVideoHeight,
816 854
                     horizontalIndent, verticalIndent);
817 855
 };
818 856
 
@@ -843,14 +881,15 @@ var getVideoPosition = function (   videoWidth,
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 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 893
     if (!videoWidth)
855 894
         videoWidth = currentVideoWidth;
856 895
     if (!videoHeight)
@@ -872,7 +911,40 @@ var getVideoSize = function(videoWidth,
872 911
     }
873 912
 
874 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 950
  * Sets the size and position of the given video element.
@@ -945,11 +1017,22 @@ $(document).ready(function () {
945 1017
     // Set default desktop sharing method
946 1018
     setDesktopSharing(config.desktopSharing);
947 1019
 
1020
+    // By default we cover the whole screen with video
1021
+    getVideoSize = getVideoSizeCover;
1022
+
948 1023
     resizeLargeVideoContainer();
949 1024
     $(window).resize(function () {
950 1025
         resizeLargeVideoContainer();
951 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 1036
     if (!$('#settings').is(':visible')) {
954 1037
         console.log('init');
955 1038
         init();

Carregando…
Cancelar
Salvar