瀏覽代碼

Make it possible to pin a participant from the contact list, even if he's not in the lastN set.

master
George Politis 10 年之前
父節點
當前提交
7da0fd6794
共有 4 個文件被更改,包括 128 次插入35 次删除
  1. 19
    0
      app.js
  2. 3
    7
      contact_list.js
  3. 2
    2
      index.html
  4. 104
    26
      videolayout.js

+ 19
- 0
app.js 查看文件

@@ -238,6 +238,25 @@ function doJoin() {
238 238
 }
239 239
 
240 240
 function waitForRemoteVideo(selector, ssrc, stream) {
241
+
242
+    // XXX(gp) so, every call to this function is *always* preceded by a call
243
+    // to the RTC.attachMediaStream() function but that call is *not* followed
244
+    // by an update to the videoSrcToSsrc map!
245
+    //
246
+    // The above way of doing things results in video SRCs that don't correspond
247
+    // to any SSRC for a short period of time (to be more precise, for as long
248
+    // the waitForRemoteVideo takes to complete). This causes problems (see
249
+    // bellow).
250
+    //
251
+    // I'm wondering why we need to do that; i.e. why call RTC.attachMediaStream()
252
+    // a second time in here and only then update the videoSrcToSsrc map? Why
253
+    // not simply update the videoSrcToSsrc map when the RTC.attachMediaStream()
254
+    // is called the first time? I actually do that in the lastN changed event
255
+    // handler because the "orphan" video SRC is causing troubles there. The
256
+    // purpose of this method would then be to fire the "videoactive.jingle".
257
+    //
258
+    // Food for though I guess :-)
259
+
241 260
     if (selector.removed || !selector.parent().is(":visible")) {
242 261
         console.warn("Media removed before had started", selector);
243 262
         return;

+ 3
- 7
contact_list.js 查看文件

@@ -41,17 +41,13 @@ var ContactList = (function (my) {
41 41
         var contactlist = $('#contactlist>ul');
42 42
 
43 43
         var newContact = document.createElement('li');
44
+        // XXX(gp) contact click event handling is now in videolayout.js. Is the
45
+        // following statement (newContact.id = resourceJid) still relevant?
44 46
         newContact.id = resourceJid;
45 47
         newContact.className = "clickable";
46 48
         newContact.onclick = function(event) {
47 49
             if(event.currentTarget.className === "clickable") {
48
-                var jid = event.currentTarget.id;
49
-                var videoContainer = $("#participant_" + jid);
50
-                if (videoContainer.length > 0) {
51
-                    videoContainer.click();
52
-                } else if (jid == Strophe.getResourceFromJid(connection.emuc.myroomjid)) {
53
-                    $("#localVideoContainer").click();
54
-                }
50
+                $(ContactList).trigger('contactclicked', [peerJid]);
55 51
             }
56 52
         };
57 53
 

+ 2
- 2
index.html 查看文件

@@ -37,7 +37,7 @@
37 37
     <script src="app.js?v=20"></script><!-- application logic -->
38 38
     <script src="commands.js?v=1"></script><!-- application logic -->
39 39
     <script src="chat.js?v=14"></script><!-- chat logic -->
40
-    <script src="contact_list.js?v=5"></script><!-- contact list logic -->
40
+    <script src="contact_list.js?v=6"></script><!-- contact list logic -->
41 41
     <script src="util.js?v=6"></script><!-- utility functions -->
42 42
     <script src="etherpad.js?v=9"></script><!-- etherpad plugin -->
43 43
     <script src="prezi.js?v=6"></script><!-- prezi plugin -->
@@ -47,7 +47,7 @@
47 47
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
48 48
     <script src="rtp_sts.js?v=5"></script><!-- RTP stats processing -->
49 49
     <script src="local_sts.js?v=2"></script><!-- Local stats processing -->
50
-    <script src="videolayout.js?v=27"></script><!-- video ui -->
50
+    <script src="videolayout.js?v=28"></script><!-- video ui -->
51 51
     <script src="connectionquality.js?v=1"></script>
52 52
     <script src="toolbar.js?v=6"></script><!-- toolbar ui -->
53 53
     <script src="toolbar_toggler.js?v=2"></script>

+ 104
- 26
videolayout.js 查看文件

@@ -4,6 +4,7 @@ var VideoLayout = (function (my) {
4 4
     var localLastNCount = config.channelLastN;
5 5
     var localLastNSet = [];
6 6
     var lastNEndpointsCache = [];
7
+    var lastNPickupJid = null;
7 8
     var largeVideoState = {
8 9
         updateInProgress: false,
9 10
         newSrc: ''
@@ -238,7 +239,7 @@ var VideoLayout = (function (my) {
238 239
         }
239 240
     };
240 241
 
241
-    my.handleVideoThumbClicked = function(videoSrc) {
242
+    my.handleVideoThumbClicked = function(videoSrc, noPinnedEndpointChangedEvent) {
242 243
         // Restore style for previously focused video
243 244
         var focusJid = getJidFromVideoSrc(focusedVideoSrc);
244 245
         var oldContainer = getParticipantContainer(focusJid);
@@ -263,7 +264,9 @@ var VideoLayout = (function (my) {
263 264
                 }
264 265
             }
265 266
 
266
-            $(document).trigger("pinnedendpointchanged");
267
+            if (!noPinnedEndpointChangedEvent) {
268
+                $(document).trigger("pinnedendpointchanged");
269
+            }
267 270
             return;
268 271
         }
269 272
 
@@ -277,7 +280,13 @@ var VideoLayout = (function (my) {
277 280
             var container = getParticipantContainer(userJid);
278 281
             container.addClass("videoContainerFocused");
279 282
 
280
-            $(document).trigger("pinnedendpointchanged", [userJid]);
283
+            if (!noPinnedEndpointChangedEvent) {
284
+                $(document).trigger("pinnedendpointchanged", [userJid]);
285
+            }
286
+        }
287
+
288
+        if ($('#largeVideo').attr('src') == videoSrc) {
289
+            return;
281 290
         }
282 291
 
283 292
         // Triggers a "video.selected" event. The "false" parameter indicates
@@ -599,7 +608,9 @@ var VideoLayout = (function (my) {
599 608
             VideoLayout.resizeThumbnails();
600 609
         }
601 610
 
602
-        ContactList.setClickable(resourceJid, !isHide);
611
+        // We want to be able to pin a participant from the contact list, even
612
+        // if he's not in the lastN set!
613
+        // ContactList.setClickable(resourceJid, !isHide);
603 614
 
604 615
     };
605 616
 
@@ -1271,6 +1282,48 @@ var VideoLayout = (function (my) {
1271 1282
         popupmenuElement.appendChild(paddingSpan);
1272 1283
     }
1273 1284
 
1285
+    /**
1286
+     * On contact list item clicked.
1287
+     */
1288
+    $(ContactList).bind('contactclicked', function(event, jid) {
1289
+        if (!jid) {
1290
+            return;
1291
+        }
1292
+
1293
+        var resource = Strophe.getResourceFromJid(jid);
1294
+        var videoContainer = $("#participant_" + resource);
1295
+        if (videoContainer.length > 0) {
1296
+            var videoThumb = $('video', videoContainer).get(0);
1297
+            // It is not always the case that a videoThumb exists (if there is
1298
+            // no actual video).
1299
+            if (videoThumb) {
1300
+                if (videoThumb.src && videoThumb.src != '') {
1301
+
1302
+                    // We have a video src, great! Let's update the large video
1303
+                    // now.
1304
+
1305
+                    VideoLayout.handleVideoThumbClicked(videoThumb.src);
1306
+                } else {
1307
+
1308
+                    // If we don't have a video src for jid, there's absolutely
1309
+                    // no point in calling handleVideoThumbClicked; Quite
1310
+                    // simply, it won't work because it needs an src to attach
1311
+                    // to the large video.
1312
+                    //
1313
+                    // Instead, we trigger the pinned endpoint changed event to
1314
+                    // let the bridge adjust its lastN set for myjid and store
1315
+                    // the pinned user in the lastNPickupJid variable to be
1316
+                    // picked up later by the lastN changed event handler.
1317
+
1318
+                    lastNPickupJid = jid;
1319
+                    $(document).trigger("pinnedendpointchanged", [jid]);
1320
+                }
1321
+            } else if (jid == connection.emuc.myroomjid) {
1322
+                $("#localVideoContainer").click();
1323
+            }
1324
+        }
1325
+    });
1326
+
1274 1327
     /**
1275 1328
      * On audio muted event.
1276 1329
      */
@@ -1430,6 +1483,8 @@ var VideoLayout = (function (my) {
1430 1483
 
1431 1484
         localLastNSet = nextLocalLastNSet;
1432 1485
 
1486
+        var updateLargeVideo = false;
1487
+
1433 1488
         // Handle LastN/local LastN changes.
1434 1489
         $('#remoteVideos>span').each(function( index, element ) {
1435 1490
             var resourceJid = VideoLayout.getPeerContainerResourceJid(element);
@@ -1455,28 +1510,8 @@ var VideoLayout = (function (my) {
1455 1510
                 // displayed in the large video we have to switch to another
1456 1511
                 // user.
1457 1512
                 var largeVideoResource = VideoLayout.getLargeVideoResource();
1458
-                if (resourceJid === largeVideoResource) {
1459
-                    var resource, container, src;
1460
-                    var myResource
1461
-                        = Strophe.getResourceFromJid(connection.emuc.myroomjid);
1462
-
1463
-                    // Find out which endpoint to show in the large video.
1464
-                    for (var i = 0; i < lastNEndpoints.length; i++) {
1465
-                        resource = lastNEndpoints[i];
1466
-                        if (!resource || resource === myResource)
1467
-                            continue;
1468
-
1469
-                        container = $("#participant_" + resource);
1470
-                        if (container.length == 0)
1471
-                            continue;
1472
-
1473
-                        src = $('video', container).attr('src');
1474
-                        if (!src)
1475
-                            continue;
1476
-
1477
-                        VideoLayout.updateLargeVideo(src);
1478
-                        break;
1479
-                    }
1513
+                if (!updateLargeVideo && resourceJid === largeVideoResource) {
1514
+                    updateLargeVideo = true;
1480 1515
                 }
1481 1516
             }
1482 1517
         });
@@ -1501,6 +1536,18 @@ var VideoLayout = (function (my) {
1501 1536
 
1502 1537
                             var videoStream = simulcast.getReceivingVideoStream(mediaStream.stream);
1503 1538
                             RTC.attachMediaStream(sel, videoStream);
1539
+                            videoSrcToSsrc[sel.attr('src')] = mediaStream.ssrc;
1540
+                            if (lastNPickupJid == mediaStream.peerjid) {
1541
+                                // Clean up the lastN pickup jid.
1542
+                                lastNPickupJid = null;
1543
+
1544
+                                // Don't fire the events again, they've already
1545
+                                // been fired in the contact list click handler.
1546
+                                VideoLayout.handleVideoThumbClicked($(sel).attr('src'), false);
1547
+
1548
+                                updateLargeVideo = false;
1549
+                            }
1550
+
1504 1551
                             waitForRemoteVideo(
1505 1552
                                     sel,
1506 1553
                                     mediaStream.ssrc,
@@ -1511,6 +1558,37 @@ var VideoLayout = (function (my) {
1511 1558
                 }
1512 1559
             });
1513 1560
         }
1561
+
1562
+        // The endpoint that was being shown in the large video has dropped out
1563
+        // of the lastN set and there was no lastN pickup jid. We need to update
1564
+        // the large video now.
1565
+
1566
+        if (updateLargeVideo) {
1567
+
1568
+            var resource, container, src;
1569
+            var myResource
1570
+                = Strophe.getResourceFromJid(connection.emuc.myroomjid);
1571
+
1572
+            // Find out which endpoint to show in the large video.
1573
+            for (var i = 0; i < lastNEndpoints.length; i++) {
1574
+                resource = lastNEndpoints[i];
1575
+                if (!resource || resource === myResource)
1576
+                    continue;
1577
+
1578
+                container = $("#participant_" + resource);
1579
+                if (container.length == 0)
1580
+                    continue;
1581
+
1582
+                src = $('video', container).attr('src');
1583
+                if (!src)
1584
+                    continue;
1585
+
1586
+                // videoSrcToSsrc needs to be update for this call to succeed.
1587
+                VideoLayout.updateLargeVideo(src);
1588
+                break;
1589
+
1590
+            }
1591
+        }
1514 1592
     });
1515 1593
 
1516 1594
     $(document).bind('videoactive.jingle', function (event, videoelem) {

Loading…
取消
儲存