Browse Source

Adds support for FF/multistream.

j8
George Politis 10 years ago
parent
commit
05bbfda5bb
6 changed files with 21971 additions and 20851 deletions
  1. 1
    1
      index.html
  2. 21887
    20798
      libs/app.bundle.js
  3. 0
    7
      modules/RTC/MediaStream.js
  4. 23
    32
      modules/xmpp/JingleSession.js
  5. 58
    12
      modules/xmpp/TraceablePeerConnection.js
  6. 2
    1
      package.json

+ 1
- 1
index.html View File

19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
19
     <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
20
     <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
21
     <script src="interface_config.js?v=5"></script>
21
     <script src="interface_config.js?v=5"></script>
22
-    <script src="libs/app.bundle.js?v=27"></script>
22
+    <script src="libs/app.bundle.js?v=28"></script>
23
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
23
     <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
24
     <link rel="stylesheet" href="css/font.css?v=6"/>
24
     <link rel="stylesheet" href="css/font.css?v=6"/>
25
     <link rel="stylesheet" href="css/toastr.css?v=1">
25
     <link rel="stylesheet" href="css/toastr.css?v=1">

+ 21887
- 20798
libs/app.bundle.js
File diff suppressed because it is too large
View File


+ 0
- 7
modules/RTC/MediaStream.js View File

33
         MediaStreamType.VIDEO_TYPE : MediaStreamType.AUDIO_TYPE;
33
         MediaStreamType.VIDEO_TYPE : MediaStreamType.AUDIO_TYPE;
34
     this.videoType = null;
34
     this.videoType = null;
35
     this.muted = false;
35
     this.muted = false;
36
-    if(browser == RTCBrowserType.RTC_BROWSER_FIREFOX)
37
-    {
38
-        if (!this.getVideoTracks)
39
-            this.getVideoTracks = function () { return []; };
40
-        if (!this.getAudioTracks)
41
-            this.getAudioTracks = function () { return []; };
42
-    }
43
 }
36
 }
44
 
37
 
45
 
38
 

+ 23
- 32
modules/xmpp/JingleSession.js View File

736
     $(elem).each(function (idx, content) {
736
     $(elem).each(function (idx, content) {
737
         var name = $(content).attr('name');
737
         var name = $(content).attr('name');
738
         var lines = '';
738
         var lines = '';
739
-        tmp = $(content).find('ssrc-group[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]').each(function() {
739
+        $(content).find('ssrc-group[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]').each(function() {
740
             var semantics = this.getAttribute('semantics');
740
             var semantics = this.getAttribute('semantics');
741
             var ssrcs = $(this).find('>source').map(function () {
741
             var ssrcs = $(this).find('>source').map(function () {
742
                 return this.getAttribute('ssrc');
742
                 return this.getAttribute('ssrc');
746
                 lines += 'a=ssrc-group:' + semantics + ' ' + ssrcs.join(' ') + '\r\n';
746
                 lines += 'a=ssrc-group:' + semantics + ' ' + ssrcs.join(' ') + '\r\n';
747
             }
747
             }
748
         });
748
         });
749
-        tmp = $(content).find('source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]'); // can handle both >source and >description>source
749
+        var tmp = $(content).find('source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]'); // can handle both >source and >description>source
750
         tmp.each(function () {
750
         tmp.each(function () {
751
             var ssrc = $(this).attr('ssrc');
751
             var ssrc = $(this).attr('ssrc');
752
             if(mySdp.containsSSRC(ssrc)){
752
             if(mySdp.containsSSRC(ssrc)){
801
     $(elem).each(function (idx, content) {
801
     $(elem).each(function (idx, content) {
802
         var name = $(content).attr('name');
802
         var name = $(content).attr('name');
803
         var lines = '';
803
         var lines = '';
804
-        tmp = $(content).find('ssrc-group[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]').each(function() {
804
+        $(content).find('ssrc-group[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]').each(function() {
805
             var semantics = this.getAttribute('semantics');
805
             var semantics = this.getAttribute('semantics');
806
             var ssrcs = $(this).find('>source').map(function () {
806
             var ssrcs = $(this).find('>source').map(function () {
807
                 return this.getAttribute('ssrc');
807
                 return this.getAttribute('ssrc');
811
                 lines += 'a=ssrc-group:' + semantics + ' ' + ssrcs.join(' ') + '\r\n';
811
                 lines += 'a=ssrc-group:' + semantics + ' ' + ssrcs.join(' ') + '\r\n';
812
             }
812
             }
813
         });
813
         });
814
-        tmp = $(content).find('source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]'); // can handle both >source and >description>source
814
+        var tmp = $(content).find('source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]'); // can handle both >source and >description>source
815
         tmp.each(function () {
815
         tmp.each(function () {
816
             var ssrc = $(this).attr('ssrc');
816
             var ssrc = $(this).attr('ssrc');
817
             // This should never happen, but can be useful for bug detection
817
             // This should never happen, but can be useful for bug detection
1310
 }
1310
 }
1311
 
1311
 
1312
 
1312
 
1313
-JingleSession.prototype.remoteStreamAdded = function (data) {
1313
+JingleSession.prototype.remoteStreamAdded = function (data, times) {
1314
     var self = this;
1314
     var self = this;
1315
     var thessrc;
1315
     var thessrc;
1316
     var ssrc2jid = this.connection.emuc.ssrc2jid;
1316
     var ssrc2jid = this.connection.emuc.ssrc2jid;
1339
             // presence to arrive.
1339
             // presence to arrive.
1340
 
1340
 
1341
             if (!ssrc2jid[thessrc]) {
1341
             if (!ssrc2jid[thessrc]) {
1342
-                // TODO(gp) limit wait duration to 1 sec.
1343
-                setTimeout(function(d) {
1344
-                    return function() {
1345
-                        self.remoteStreamAdded(d);
1346
-                    }
1347
-                }(data), 250);
1342
+
1343
+                if (typeof times === 'undefined')
1344
+                {
1345
+                    times = 0;
1346
+                }
1347
+
1348
+                if (times > 10)
1349
+                {
1350
+                    console.warning('Waiting for jid timed out', thessrc);
1351
+                }
1352
+                else
1353
+                {
1354
+                    setTimeout(function(d) {
1355
+                        return function() {
1356
+                            self.remoteStreamAdded(d, times++);
1357
+                        }
1358
+                    }(data), 250);
1359
+                }
1348
                 return;
1360
                 return;
1349
             }
1361
             }
1350
 
1362
 
1356
         }
1368
         }
1357
     }
1369
     }
1358
 
1370
 
1359
-    //TODO: this code should be removed when firefox implement multistream support
1360
-    if(APP.RTC.getBrowserType() == RTCBrowserType.RTC_BROWSER_FIREFOX)
1361
-    {
1362
-        if((JingleSession.notReceivedSSRCs.length == 0) ||
1363
-            !ssrc2jid[JingleSession.notReceivedSSRCs[JingleSession.notReceivedSSRCs.length - 1]])
1364
-        {
1365
-            // TODO(gp) limit wait duration to 1 sec.
1366
-            setTimeout(function(d) {
1367
-                return function() {
1368
-                    self.remoteStreamAdded(d);
1369
-                }
1370
-            }(data), 250);
1371
-            return;
1372
-        }
1373
-
1374
-        thessrc = JingleSession.notReceivedSSRCs.pop();
1375
-        if (ssrc2jid[thessrc]) {
1376
-            data.peerjid = ssrc2jid[thessrc];
1377
-        }
1378
-    }
1379
-
1380
     APP.RTC.createRemoteStream(data, this.sid, thessrc);
1371
     APP.RTC.createRemoteStream(data, this.sid, thessrc);
1381
 
1372
 
1382
     var isVideo = data.stream.getVideoTracks().length > 0;
1373
     var isVideo = data.stream.getVideoTracks().length > 0;

+ 58
- 12
modules/xmpp/TraceablePeerConnection.js View File

6
     this.stats = {};
6
     this.stats = {};
7
     this.statsinterval = null;
7
     this.statsinterval = null;
8
     this.maxstats = 0; // limit to 300 values, i.e. 5 minutes; set to 0 to disable
8
     this.maxstats = 0; // limit to 300 values, i.e. 5 minutes; set to 0 to disable
9
+    var Interop = require('sdp-interop').Interop;
10
+    this.interop = new Interop();
9
 
11
 
10
     // override as desired
12
     // override as desired
11
     this.trace = function (what, info) {
13
     this.trace = function (what, info) {
98
 };
100
 };
99
 
101
 
100
 dumpSDP = function(description) {
102
 dumpSDP = function(description) {
103
+    if (typeof description === 'undefined' || description == null) {
104
+        return '';
105
+    }
106
+
101
     return 'type: ' + description.type + '\r\n' + description.sdp;
107
     return 'type: ' + description.type + '\r\n' + description.sdp;
102
-}
108
+};
103
 
109
 
104
 if (TraceablePeerConnection.prototype.__defineGetter__ !== undefined) {
110
 if (TraceablePeerConnection.prototype.__defineGetter__ !== undefined) {
105
     TraceablePeerConnection.prototype.__defineGetter__('signalingState', function() { return this.peerconnection.signalingState; });
111
     TraceablePeerConnection.prototype.__defineGetter__('signalingState', function() { return this.peerconnection.signalingState; });
106
     TraceablePeerConnection.prototype.__defineGetter__('iceConnectionState', function() { return this.peerconnection.iceConnectionState; });
112
     TraceablePeerConnection.prototype.__defineGetter__('iceConnectionState', function() { return this.peerconnection.iceConnectionState; });
107
     TraceablePeerConnection.prototype.__defineGetter__('localDescription', function() {
113
     TraceablePeerConnection.prototype.__defineGetter__('localDescription', function() {
108
-        var publicLocalDescription = APP.simulcast.reverseTransformLocalDescription(this.peerconnection.localDescription);
109
-        return publicLocalDescription;
114
+        this.trace('getLocalDescription::preTransform (Plan A)', dumpSDP(this.peerconnection.localDescription));
115
+        // if we're running on FF, transform to Plan B first.
116
+        var desc = this.peerconnection.localDescription;
117
+        if (navigator.mozGetUserMedia) {
118
+            desc = this.interop.toPlanB(desc);
119
+        } else {
120
+            desc = APP.simulcast.reverseTransformLocalDescription(this.peerconnection.localDescription);
121
+        }
122
+        this.trace('getLocalDescription::postTransform (Plan B)', dumpSDP(desc));
123
+        return desc;
110
     });
124
     });
111
     TraceablePeerConnection.prototype.__defineGetter__('remoteDescription', function() {
125
     TraceablePeerConnection.prototype.__defineGetter__('remoteDescription', function() {
112
-        var publicRemoteDescription = APP.simulcast.reverseTransformRemoteDescription(this.peerconnection.remoteDescription);
113
-        return publicRemoteDescription;
126
+        this.trace('getRemoteDescription::preTransform (Plan A)', dumpSDP(this.peerconnection.remoteDescription));
127
+        // if we're running on FF, transform to Plan B first.
128
+        var desc = this.peerconnection.remoteDescription;
129
+        if (navigator.mozGetUserMedia) {
130
+            desc = this.interop.toPlanB(desc);
131
+        } else {
132
+            desc = APP.simulcast.reverseTransformRemoteDescription(this.peerconnection.remoteDescription);
133
+        }
134
+        this.trace('getRemoteDescription::postTransform (Plan B)', dumpSDP(desc));
135
+        return desc;
114
     });
136
     });
115
 }
137
 }
116
 
138
 
148
 };
170
 };
149
 
171
 
150
 TraceablePeerConnection.prototype.setLocalDescription = function (description, successCallback, failureCallback) {
172
 TraceablePeerConnection.prototype.setLocalDescription = function (description, successCallback, failureCallback) {
173
+    this.trace('setLocalDescription::preTransform (Plan B)', dumpSDP(description));
174
+    // if we're running on FF, transform to Plan A first.
175
+    if (navigator.mozGetUserMedia) {
176
+        description = this.interop.toPlanA(description);
177
+    } else {
178
+        description = APP.simulcast.transformLocalDescription(description);
179
+    }
180
+    this.trace('setLocalDescription::postTransform (Plan A)', dumpSDP(description));
151
     var self = this;
181
     var self = this;
152
-    description = APP.simulcast.transformLocalDescription(description);
153
-    this.trace('setLocalDescription', dumpSDP(description));
154
     this.peerconnection.setLocalDescription(description,
182
     this.peerconnection.setLocalDescription(description,
155
         function () {
183
         function () {
156
             self.trace('setLocalDescriptionOnSuccess');
184
             self.trace('setLocalDescriptionOnSuccess');
169
 };
197
 };
170
 
198
 
171
 TraceablePeerConnection.prototype.setRemoteDescription = function (description, successCallback, failureCallback) {
199
 TraceablePeerConnection.prototype.setRemoteDescription = function (description, successCallback, failureCallback) {
200
+    this.trace('setRemoteDescription::preTransform (Plan B)', dumpSDP(description));
201
+    // if we're running on FF, transform to Plan A first.
202
+    if (navigator.mozGetUserMedia) {
203
+        description = this.interop.toPlanA(description);
204
+    }
205
+    else {
206
+        description = APP.simulcast.transformRemoteDescription(description);
207
+    }
208
+    this.trace('setRemoteDescription::postTransform (Plan A)', dumpSDP(description));
172
     var self = this;
209
     var self = this;
173
-    description = APP.simulcast.transformRemoteDescription(description);
174
-    this.trace('setRemoteDescription', dumpSDP(description));
175
     this.peerconnection.setRemoteDescription(description,
210
     this.peerconnection.setRemoteDescription(description,
176
         function () {
211
         function () {
177
             self.trace('setRemoteDescriptionOnSuccess');
212
             self.trace('setRemoteDescriptionOnSuccess');
203
     this.trace('createOffer', JSON.stringify(constraints, null, ' '));
238
     this.trace('createOffer', JSON.stringify(constraints, null, ' '));
204
     this.peerconnection.createOffer(
239
     this.peerconnection.createOffer(
205
         function (offer) {
240
         function (offer) {
206
-            self.trace('createOfferOnSuccess', dumpSDP(offer));
241
+            self.trace('createOfferOnSuccess::preTransform (Plan A)', dumpSDP(offer));
242
+            // if we're running on FF, transform to Plan B first.
243
+            if (navigator.mozGetUserMedia) {
244
+                offer = self.interop.toPlanB(offer);
245
+            }
246
+            self.trace('createOfferOnSuccess::postTransform (Plan B)', dumpSDP(offer));
207
             successCallback(offer);
247
             successCallback(offer);
208
         },
248
         },
209
         function(err) {
249
         function(err) {
219
     this.trace('createAnswer', JSON.stringify(constraints, null, ' '));
259
     this.trace('createAnswer', JSON.stringify(constraints, null, ' '));
220
     this.peerconnection.createAnswer(
260
     this.peerconnection.createAnswer(
221
         function (answer) {
261
         function (answer) {
222
-            answer = APP.simulcast.transformAnswer(answer);
223
-            self.trace('createAnswerOnSuccess', dumpSDP(answer));
262
+            self.trace('createAnswerOnSuccess::preTransfom (Plan A)', dumpSDP(answer));
263
+            // if we're running on FF, transform to Plan A first.
264
+            if (navigator.mozGetUserMedia) {
265
+                answer = self.interop.toPlanB(answer);
266
+            } else {
267
+                answer = APP.simulcast.transformAnswer(answer);
268
+            }
269
+            self.trace('createAnswerOnSuccess::postTransfom (Plan B)', dumpSDP(answer));
224
             successCallback(answer);
270
             successCallback(answer);
225
         },
271
         },
226
         function(err) {
272
         function(err) {

+ 2
- 1
package.json View File

17
   "dependencies": {
17
   "dependencies": {
18
       "events": "*",
18
       "events": "*",
19
       "pako": "*",
19
       "pako": "*",
20
-      "i18next-client": "*"
20
+      "i18next-client": "*",
21
+      "sdp-interop": "https://github.com/jitsi/sdp-interop/tarball/master"
21
   },
22
   },
22
   "devDependencies": {
23
   "devDependencies": {
23
   },
24
   },

Loading…
Cancel
Save