浏览代码

Handles audio and video streams separately. Minor fixes.

master
paweldomas 11 年前
父节点
当前提交
9fd03e1bef
共有 6 个文件被更改,包括 168 次插入74 次删除
  1. 102
    37
      app.js
  2. 3
    0
      index.html
  3. 23
    18
      libs/colibri/colibri.focus.js
  4. 16
    8
      libs/strophe/strophe.jingle.adapter.js
  5. 18
    10
      libs/strophe/strophe.jingle.js
  6. 6
    1
      libs/strophe/strophe.jingle.session.js

+ 102
- 37
app.js 查看文件

@@ -49,11 +49,10 @@ function init() {
49 49
             if (config.useStunTurn) {
50 50
                 connection.jingle.getStunAndTurnCredentials();
51 51
             }
52
-            if (RTC.browser === 'firefox') {
53
-                getUserMediaWithConstraints(['audio']);
54
-            } else {
55
-                getUserMediaWithConstraints(['audio', 'video'], config.resolution || '360');
56
-            }
52
+            getUserMediaWithConstraints( ['audio'], audioStreamReady,
53
+                function(error){
54
+                    console.error('failed to obtain audio stream - stop', error);
55
+                });
57 56
             document.getElementById('connect').disabled = true;
58 57
         } else {
59 58
             console.log('status', status);
@@ -61,6 +60,31 @@ function init() {
61 60
     });
62 61
 }
63 62
 
63
+function audioStreamReady(stream) {
64
+
65
+    change_local_audio(stream);
66
+
67
+    if(RTC.browser !== 'firefox') {
68
+        getUserMediaWithConstraints( ['video'], videoStreamReady, videoStreamFailed, config.resolution || '360' );
69
+    } else {
70
+        doJoin();
71
+    }
72
+}
73
+
74
+function videoStreamReady(stream) {
75
+
76
+    change_local_video(stream);
77
+
78
+    doJoin();
79
+}
80
+
81
+function videoStreamFailed(error) {
82
+
83
+    console.warn("Failed to obtain video stream - continue anyway", error);
84
+
85
+    doJoin();
86
+}
87
+
64 88
 function doJoin() {
65 89
     var roomnode = null;
66 90
     var path = window.location.pathname;
@@ -104,8 +128,17 @@ function doJoin() {
104 128
     connection.emuc.doJoin(roomjid);
105 129
 }
106 130
 
107
-$(document).bind('mediaready.jingle', function (event, stream) {
108
-    connection.jingle.localStream = stream;
131
+function change_local_audio(stream) {
132
+
133
+    connection.jingle.localAudio = stream;
134
+    RTC.attachMediaStream($('#localAudio'), stream);
135
+    document.getElementById('localAudio').autoplay = true;
136
+    document.getElementById('localAudio').volume = 0;
137
+}
138
+
139
+function change_local_video(stream) {
140
+
141
+    connection.jingle.localVideo = stream;
109 142
     RTC.attachMediaStream($('#localVideo'), stream);
110 143
     document.getElementById('localVideo').autoplay = true;
111 144
     document.getElementById('localVideo').volume = 0;
@@ -124,16 +157,14 @@ $(document).bind('mediaready.jingle', function (event, stream) {
124 157
             }
125 158
         });
126 159
     });
127
-
128
-    doJoin();
129
-});
130
-
131
-$(document).bind('mediafailure.jingle', function () {
132
-    // FIXME
133
-});
160
+}
134 161
 
135 162
 $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
136 163
     function waitForRemoteVideo(selector, sid) {
164
+        if(selector.removed) {
165
+            console.warn("media removed before had started", selector);
166
+            return;
167
+        }
137 168
         var sess = connection.jingle.sessions[sid];
138 169
         if (data.stream.id === 'mixedmslabel') return;
139 170
         videoTracks = data.stream.getVideoTracks();
@@ -188,8 +219,11 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
188 219
         remotes.appendChild(container);
189 220
         Util.playSoundNotification('userJoined');
190 221
     }
191
-    var vid = document.createElement('video');
192
-    var id = 'remoteVideo_' + sid + '_' + data.stream.id;
222
+
223
+    var isVideo = data.stream.getVideoTracks().length > 0;
224
+    var vid = isVideo ? document.createElement('video') : document.createElement('audio');
225
+    var id = (isVideo ? 'remoteVideo_' : 'remoteAudio_') + sid + '_' + data.stream.id;
226
+
193 227
     vid.id = id;
194 228
     vid.autoplay = true;
195 229
     vid.oncontextmenu = function () { return false; };
@@ -203,11 +237,14 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
203 237
     var sel = $('#' + id);
204 238
     sel.hide();
205 239
     RTC.attachMediaStream(sel, data.stream);
206
-    waitForRemoteVideo(sel, sid);
240
+
241
+    if(isVideo) {
242
+        waitForRemoteVideo(sel, sid);
243
+    }
244
+
207 245
     data.stream.onended = function () {
208 246
         console.log('stream ended', this.id);
209
-        var src = $('#' + id).attr('src');
210
-        if (src === $('#largeVideo').attr('src')) {
247
+        if (sel.attr('src') === $('#largeVideo').attr('src')) {
211 248
             // this is currently displayed as large
212 249
             // pick the last visible video in the row
213 250
             // if nobody else is left, this picks the local video
@@ -221,9 +258,21 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
221 258
                  updateLargeVideo(pick.src, isLocalVideo, pick.volume);
222 259
             }
223 260
         }
224
-        $('#' + id).parent().remove();
225
-        Util.playSoundNotification('userLeft');
226
-        resizeThumbnails();
261
+        // Mark video as removed to cancel waiting loop(if video is removed before has started)
262
+        sel.removed = true;
263
+
264
+        var userContainer = sel.parent();
265
+        if(userContainer.children().length === 0) {
266
+            console.log("Remove whole user");
267
+            // Remove whole container
268
+            userContainer.remove();
269
+            Util.playSoundNotification('userLeft');
270
+            resizeThumbnails();
271
+        } else {
272
+            // Remove only stream holder
273
+            sel.remove();
274
+            console.log("Remove stream only", sel);
275
+        }
227 276
     };
228 277
     sel.click(
229 278
         function () {
@@ -232,9 +281,10 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
232 281
         }
233 282
     );
234 283
     // an attempt to work around https://github.com/jitsi/jitmeet/issues/32
235
-    if (data.peerjid && sess.peerjid === data.peerjid &&
236
-            data.stream.getVideoTracks().length === 0 &&
237
-            connection.jingle.localStream.getVideoTracks().length > 0) {
284
+    if (isVideo
285
+        && data.peerjid && sess.peerjid === data.peerjid &&
286
+           data.stream.getVideoTracks().length === 0 &&
287
+           connection.jingle.localVideo.getVideoTracks().length > 0) {
238 288
         window.setTimeout(function() {
239 289
             sendKeyframe(sess.peerconnection);
240 290
         }, 3000);
@@ -379,7 +429,12 @@ $(document).bind('setLocalDescription.jingle', function (event, sid) {
379 429
             var ssrc = SDPUtil.find_line(media, 'a=ssrc:').substring(7).split(' ')[0];
380 430
             newssrcs[type] = ssrc;
381 431
 
382
-            directions[type] = (SDPUtil.find_line(media, 'a=sendrecv') || SDPUtil.find_line(media, 'a=recvonly') || SDPUtil.find_line('a=sendonly') || SDPUtil.find_line('a=inactive') || 'a=sendrecv').substr(2);
432
+            directions[type] = (
433
+                SDPUtil.find_line(media, 'a=sendrecv')
434
+                || SDPUtil.find_line(media, 'a=recvonly')
435
+                || SDPUtil.find_line('a=sendonly')
436
+                || SDPUtil.find_line('a=inactive')
437
+                || 'a=sendrecv' ).substr(2);
383 438
         }
384 439
     });
385 440
     console.log('new ssrcs', newssrcs);
@@ -422,7 +477,7 @@ $(document).bind('joined.muc', function (event, jid, info) {
422 477
 
423 478
 $(document).bind('entered.muc', function (event, jid, info, pres) {
424 479
     console.log('entered', jid, info);
425
-    console.log(focus);
480
+    console.log('is focus?' + focus ? 'true' : 'false');
426 481
 
427 482
     var videoSpanId = 'participant_' + Strophe.getResourceFromJid(jid);
428 483
     var container = addRemoteVideoContainer(videoSpanId);
@@ -712,17 +767,22 @@ function updateLargeVideo(newSrc, localVideo, vol) {
712 767
     }
713 768
 }
714 769
 
770
+function getConferenceHandler() {
771
+    return focus ? focus : activecall;
772
+}
773
+
715 774
 function toggleVideo() {
716
-    if (!(connection && connection.jingle.localStream)) return;
775
+    if (!(connection && connection.jingle.localVideo)) return;
717 776
     var ismuted = false;
718
-    for (var idx = 0; idx < connection.jingle.localStream.getVideoTracks().length; idx++) {
719
-        ismuted = !connection.jingle.localStream.getVideoTracks()[idx].enabled;
777
+    var localVideo = connection.jingle.localVideo;
778
+    for (var idx = 0; idx < localVideo.getVideoTracks().length; idx++) {
779
+        ismuted = !localVideo.getVideoTracks()[idx].enabled;
720 780
     }
721
-    for (var idx = 0; idx < connection.jingle.localStream.getVideoTracks().length; idx++) {
722
-        connection.jingle.localStream.getVideoTracks()[idx].enabled = !connection.jingle.localStream.getVideoTracks()[idx].enabled;
781
+    for (var idx = 0; idx < localVideo.getVideoTracks().length; idx++) {
782
+        localVideo.getVideoTracks()[idx].enabled = !localVideo.getVideoTracks()[idx].enabled;
723 783
     }
724
-    var sess = focus || activecall;
725
-    if (!sess) {
784
+    var sess = getConferenceHandler();
785
+    if (sess) {
726 786
         return;
727 787
     }
728 788
     sess.peerconnection.pendingop = ismuted ? 'unmute' : 'mute';
@@ -730,9 +790,10 @@ function toggleVideo() {
730 790
 }
731 791
 
732 792
 function toggleAudio() {
733
-    if (!(connection && connection.jingle.localStream)) return;
734
-    for (var idx = 0; idx < connection.jingle.localStream.getAudioTracks().length; idx++) {
735
-        connection.jingle.localStream.getAudioTracks()[idx].enabled = !connection.jingle.localStream.getAudioTracks()[idx].enabled;
793
+    if (!(connection && connection.jingle.localAudio)) return;
794
+    var localAudio = connection.jingle.localAudio;
795
+    for (var idx = 0; idx < localAudio.getAudioTracks().length; idx++) {
796
+        localAudio.getAudioTracks()[idx].enabled = !localAudio.getAudioTracks()[idx].enabled;
736 797
     }
737 798
 }
738 799
 
@@ -1170,6 +1231,10 @@ function showFocusIndicator() {
1170 1231
         var session = connection.jingle.sessions[Object.keys(connection.jingle.sessions)[0]];
1171 1232
         var focusId = 'participant_' + Strophe.getResourceFromJid(session.peerjid);
1172 1233
         var focusContainer = document.getElementById(focusId);
1234
+        if(!focusContainer) {
1235
+            console.error("No focus container!");
1236
+            return;
1237
+        }
1173 1238
         var indicatorSpan = $('#' + focusId + ' .focusindicator');
1174 1239
 
1175 1240
         if (!indicatorSpan || indicatorSpan.length === 0) {

+ 3
- 0
index.html 查看文件

@@ -79,6 +79,7 @@
79 79
             <span id="localVideoContainer" class="videocontainer">
80 80
                 <span id="localNick"></span>
81 81
                 <video id="localVideo" autoplay oncontextmenu="return false;" muted></video>
82
+                <audio id="localAudio" autoplay oncontextmenu="return false;" muted></audio>
82 83
                 <span class="focusindicator"></span>
83 84
             </span>
84 85
             <audio id="userJoined" src="sounds/joined.wav" preload="auto"></audio>
@@ -99,6 +100,7 @@
99 100
         <textarea id="usermsg" placeholder='Enter text...' autofocus></textarea>
100 101
     </div>
101 102
     <a id="downloadlog" onclick='dump(event.target);'><i title="Download support information" class="fa fa-cloud-download"></i></a>
103
+    <!-- Google Analytics -->
102 104
     <script>
103 105
         (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
104 106
              (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
@@ -106,5 +108,6 @@
106 108
         ga('create', 'UA-319188-14', 'jit.si');
107 109
         ga('send', 'pageview');
108 110
     </script>
111
+    <!-- End Google Analytics -->
109 112
   </body>
110 113
 </html>

+ 23
- 18
libs/colibri/colibri.focus.js 查看文件

@@ -77,24 +77,29 @@ ColibriFocus.prototype.makeConference = function (peers) {
77 77
         self.channels.push([]);
78 78
     });
79 79
 
80
-    this.peerconnection.addStream(this.connection.jingle.localStream);
80
+    if(connection.jingle.localAudio) {
81
+        this.peerconnection.addStream(connection.jingle.localAudio);
82
+    }
83
+    if(connection.jingle.localVideo) {
84
+        this.peerconnection.addStream(connection.jingle.localVideo);
85
+    }
81 86
     this.peerconnection.oniceconnectionstatechange = function (event) {
82 87
         console.warn('ice connection state changed to', self.peerconnection.iceConnectionState);
83 88
         /*
84
-         if (self.peerconnection.signalingState == 'stable' && self.peerconnection.iceConnectionState == 'connected') {
85
-         console.log('adding new remote SSRCs from iceconnectionstatechange');
86
-         window.setTimeout(function() { self.modifySources(); }, 1000);
87
-         }
88
-         */
89
+        if (self.peerconnection.signalingState == 'stable' && self.peerconnection.iceConnectionState == 'connected') {
90
+            console.log('adding new remote SSRCs from iceconnectionstatechange');
91
+            window.setTimeout(function() { self.modifySources(); }, 1000);
92
+        }
93
+        */
89 94
     };
90 95
     this.peerconnection.onsignalingstatechange = function (event) {
91 96
         console.warn(self.peerconnection.signalingState);
92 97
         /*
93
-         if (self.peerconnection.signalingState == 'stable' && self.peerconnection.iceConnectionState == 'connected') {
94
-         console.log('adding new remote SSRCs from signalingstatechange');
95
-         window.setTimeout(function() { self.modifySources(); }, 1000);
96
-         }
97
-         */
98
+        if (self.peerconnection.signalingState == 'stable' && self.peerconnection.iceConnectionState == 'connected') {
99
+            console.log('adding new remote SSRCs from signalingstatechange');
100
+            window.setTimeout(function() { self.modifySources(); }, 1000);
101
+        }
102
+        */
98 103
     };
99 104
     this.peerconnection.onaddstream = function (event) {
100 105
         self.remoteStream = event.stream;
@@ -146,7 +151,6 @@ ColibriFocus.prototype._makeConference = function () {
146 151
     var elem = $iq({to: this.bridgejid, type: 'get'});
147 152
     elem.c('conference', {xmlns: 'http://jitsi.org/protocol/colibri'});
148 153
 
149
-    var stream = this.connection.jingle.localStream;
150 154
     this.media.forEach(function (name) {
151 155
         elem.c('content', {name: name});
152 156
         elem.c('channel', {initiator: 'true', expire: '15'}).up();
@@ -443,7 +447,8 @@ ColibriFocus.prototype.initiate = function (peer, isInitiator) {
443 447
                                   this.connection);
444 448
     sess.initiate(peer);
445 449
     sess.colibri = this;
446
-    sess.localStream = this.connection.jingle.localStream;
450
+    // We do not announce our audio per conference peer, so only video is set here
451
+    sess.localVideo = this.connection.jingle.localVideo;
447 452
     sess.media_constraints = this.connection.jingle.media_constraints;
448 453
     sess.pc_constraints = this.connection.jingle.pc_constraints;
449 454
     sess.ice_config = this.connection.jingle.ice_config;
@@ -610,7 +615,7 @@ ColibriFocus.prototype.sendSSRCUpdate = function (sdp, jid, isadd) {
610 615
                     console.warn('got modify result');
611 616
                 },
612 617
                 function (err) {
613
-                    console.warn('got modify error');
618
+                    console.warn('got modify error', err);
614 619
                 }
615 620
             );
616 621
         } else {
@@ -697,7 +702,7 @@ ColibriFocus.prototype.addIceCandidate = function (session, elem) {
697 702
             console.log('got result');
698 703
         },
699 704
         function (err) {
700
-            console.warn('got error');
705
+            console.error('got error', err);
701 706
         }
702 707
     );
703 708
 };
@@ -748,7 +753,7 @@ ColibriFocus.prototype.sendIceCandidates = function (candidates) {
748 753
             console.log('got result');
749 754
         },
750 755
         function (err) {
751
-            console.warn('got error');
756
+            console.error('got error', err);
752 757
         }
753 758
     );
754 759
 };
@@ -779,7 +784,7 @@ ColibriFocus.prototype.terminate = function (session, reason) {
779 784
             console.log('got result');
780 785
         },
781 786
         function (err) {
782
-            console.log('got error');
787
+            console.error('got error', err);
783 788
         }
784 789
     );
785 790
     // and remove from channels
@@ -811,7 +816,7 @@ ColibriFocus.prototype.hardMuteVideo = function (muted) {
811 816
 
812 817
     this.peerconnection.hardMuteVideo(muted);
813 818
 
814
-    this.connection.jingle.localStream.getVideoTracks().forEach(function (track) {
819
+    this.connection.jingle.localVideo.getVideoTracks().forEach(function (track) {
815 820
         track.enabled = !muted;
816 821
     });
817 822
 };

+ 16
- 8
libs/strophe/strophe.jingle.adapter.js 查看文件

@@ -220,7 +220,6 @@ TraceablePeerConnection.prototype.addSource = function (elem) {
220 220
         });
221 221
         sdp.raw = sdp.session + sdp.media.join('');
222 222
     });
223
-    this.modifySources();
224 223
 };
225 224
 
226 225
 TraceablePeerConnection.prototype.enqueueRemoveSsrc = function(channel, ssrcLines) {
@@ -257,7 +256,6 @@ TraceablePeerConnection.prototype.removeSource = function (elem) {
257 256
         });
258 257
         sdp.raw = sdp.session + sdp.media.join('');
259 258
     });
260
-    this.modifySources();
261 259
 };
262 260
 
263 261
 TraceablePeerConnection.prototype.modifySources = function(successCallback) {
@@ -275,11 +273,11 @@ TraceablePeerConnection.prototype.modifySources = function(successCallback) {
275 273
     if (!(this.signalingState == 'stable' && this.iceConnectionState == 'connected')) {
276 274
         console.warn('modifySources not yet', this.signalingState, this.iceConnectionState);
277 275
         this.wait = true;
278
-        window.setTimeout(function() { self.modifySources(); }, 250);
276
+        window.setTimeout(function() { self.modifySources(successCallback); }, 250);
279 277
         return;
280 278
     }
281 279
     if (this.wait) {
282
-        window.setTimeout(function() { self.modifySources(); }, 2500);
280
+        window.setTimeout(function() { self.modifySources(successCallback); }, 2500);
283 281
         this.wait = false;
284 282
         return;
285 283
     }
@@ -325,6 +323,12 @@ TraceablePeerConnection.prototype.modifySources = function(successCallback) {
325 323
                         self.pendingop = null;
326 324
                     }
327 325
 
326
+                    // FIXME: pushing down an answer while ice connection state
327
+                    // is still checking is bad...
328
+                    //console.log(self.peerconnection.iceConnectionState);
329
+
330
+                    // trying to work around another chrome bug
331
+                    //modifiedAnswer.sdp = modifiedAnswer.sdp.replace(/a=setup:active/g, 'a=setup:actpass');
328 332
                     self.setLocalDescription(modifiedAnswer,
329 333
                         function() {
330 334
                             //console.log('modified setLocalDescription ok');
@@ -471,7 +475,7 @@ function setupRTC() {
471 475
     return RTC;
472 476
 }
473 477
 
474
-function getUserMediaWithConstraints(um, resolution, bandwidth, fps) {
478
+function getUserMediaWithConstraints(um, success_callback, failure_callback, resolution, bandwidth, fps) {
475 479
     var constraints = {audio: false, video: false};
476 480
 
477 481
     if (um.indexOf('video') >= 0) {
@@ -553,14 +557,18 @@ function getUserMediaWithConstraints(um, resolution, bandwidth, fps) {
553 557
         RTC.getUserMedia(constraints,
554 558
             function (stream) {
555 559
                 console.log('onUserMediaSuccess');
556
-                $(document).trigger('mediaready.jingle', [stream]);
560
+                success_callback(stream);
557 561
             },
558 562
             function (error) {
559 563
                 console.warn('Failed to get access to local media. Error ', error);
560
-                $(document).trigger('mediafailure.jingle');
564
+                if(failure_callback) {
565
+                    failure_callback(error);
566
+                }
561 567
             });
562 568
     } catch (e) {
563 569
         console.error('GUM failed: ', e);
564
-        $(document).trigger('mediafailure.jingle');
570
+        if(failure_callback) {
571
+            failure_callback(e);
572
+        }
565 573
     }
566 574
 }

+ 18
- 10
libs/strophe/strophe.jingle.js 查看文件

@@ -12,7 +12,8 @@ Strophe.addConnectionPlugin('jingle', {
12 12
         }
13 13
         // MozDontOfferDataChannel: true when this is firefox
14 14
     },
15
-    localStream: null,
15
+    localAudio: null,
16
+    localVideo: null,
16 17
 
17 18
     init: function (conn) {
18 19
         this.connection = conn;
@@ -38,12 +39,13 @@ Strophe.addConnectionPlugin('jingle', {
38 39
     onJingle: function (iq) {
39 40
         var sid = $(iq).find('jingle').attr('sid');
40 41
         var action = $(iq).find('jingle').attr('action');
42
+        var fromJid = iq.getAttribute('from');
41 43
         // send ack first
42 44
         var ack = $iq({type: 'result',
43
-            to: iq.getAttribute('from'),
45
+            to: fromJid,
44 46
             id: iq.getAttribute('id')
45 47
         });
46
-        console.log('on jingle ' + action);
48
+        console.log('on jingle ' + action + ' from ' + fromJid, iq);
47 49
         var sess = this.sessions[sid];
48 50
         if ('session-initiate' != action) {
49 51
             if (sess === null) {
@@ -56,8 +58,8 @@ Strophe.addConnectionPlugin('jingle', {
56 58
             }
57 59
             // compare from to sess.peerjid (bare jid comparison for later compat with message-mode)
58 60
             // local jid is not checked
59
-            if (Strophe.getBareJidFromJid(iq.getAttribute('from')) != Strophe.getBareJidFromJid(sess.peerjid)) {
60
-                console.warn('jid mismatch for session id', sid, iq.getAttribute('from'), sess.peerjid);
61
+            if (Strophe.getBareJidFromJid(fromJid) != Strophe.getBareJidFromJid(sess.peerjid)) {
62
+                console.warn('jid mismatch for session id', sid, fromJid, sess.peerjid);
61 63
                 ack.type = 'error';
62 64
                 ack.c('error', {type: 'cancel'})
63 65
                     .c('item-not-found', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up()
@@ -82,14 +84,17 @@ Strophe.addConnectionPlugin('jingle', {
82 84
             case 'session-initiate':
83 85
                 sess = new JingleSession($(iq).attr('to'), $(iq).find('jingle').attr('sid'), this.connection);
84 86
                 // configure session
85
-                if (this.localStream) {
86
-                    sess.localStreams.push(this.localStream);
87
+                if (this.localAudio) {
88
+                    sess.localStreams.push(this.localAudio);
89
+                }
90
+                if (this.localVideo) {
91
+                    sess.localStreams.push(this.localVideo);
87 92
                 }
88 93
                 sess.media_constraints = this.media_constraints;
89 94
                 sess.pc_constraints = this.pc_constraints;
90 95
                 sess.ice_config = this.ice_config;
91 96
 
92
-                sess.initiate($(iq).attr('from'), false);
97
+                sess.initiate(fromJid, false);
93 98
                 // FIXME: setRemoteDescription should only be done when this call is to be accepted
94 99
                 sess.setRemoteDescription($(iq).find('>jingle'), 'offer');
95 100
 
@@ -152,8 +157,11 @@ Strophe.addConnectionPlugin('jingle', {
152 157
             Math.random().toString(36).substr(2, 12), // random string
153 158
             this.connection);
154 159
         // configure session
155
-        if (this.localStream) {
156
-            sess.localStreams.push(this.localStream);
160
+        if (this.localAudio) {
161
+            sess.localStreams.push(this.localAudio);
162
+        }
163
+        if (this.localVideo) {
164
+            sess.localStreams.push(this.localVideo);
157 165
         }
158 166
         sess.media_constraints = this.media_constraints;
159 167
         sess.pc_constraints = this.pc_constraints;

+ 6
- 1
libs/strophe/strophe.jingle.session.js 查看文件

@@ -76,6 +76,7 @@ JingleSession.prototype.initiate = function (peerjid, isInitiator) {
76 76
     this.peerconnection.onremovestream = function (event) {
77 77
         self.remoteStream = null;
78 78
         // FIXME: remove from this.remoteStreams
79
+        // FIXME: remotestreamremoved.jingle not defined anywhere(unused)
79 80
         $(document).trigger('remotestreamremoved.jingle', [event, self.sid]);
80 81
     };
81 82
     this.peerconnection.onsignalingstatechange = function (event) {
@@ -635,11 +636,15 @@ JingleSession.prototype.sendTerminate = function (reason, text) {
635 636
 JingleSession.prototype.addSource = function (elem) {
636 637
 
637 638
     this.peerconnection.addSource(elem);
639
+
640
+    this.modifySources();
638 641
 };
639 642
 
640 643
 JingleSession.prototype.removeSource = function (elem) {
641 644
 
642 645
     this.peerconnection.removeSource(elem);
646
+
647
+    this.modifySources();
643 648
 };
644 649
 
645 650
 JingleSession.prototype.modifySources = function() {
@@ -655,7 +660,7 @@ JingleSession.prototype.hardMuteVideo = function (muted) {
655 660
 
656 661
     this.peerconnection.hardMuteVideo(muted);
657 662
 
658
-    this.connection.jingle.localStream.getVideoTracks().forEach(function (track) {
663
+    this.connection.jingle.localVideo.getVideoTracks().forEach(function (track) {
659 664
         track.enabled = !muted;
660 665
     });
661 666
 };

正在加载...
取消
保存