|
@@ -48,6 +48,8 @@ function JingleSession(me, sid, connection, service, eventEmitter) {
|
48
|
48
|
|
49
|
49
|
this.wait = true;
|
50
|
50
|
this.localStreamsSSRC = null;
|
|
51
|
+ this.ssrcOwners = {};
|
|
52
|
+ this.ssrcVideoTypes = {};
|
51
|
53
|
this.eventEmitter = eventEmitter;
|
52
|
54
|
|
53
|
55
|
/**
|
|
@@ -189,6 +191,10 @@ function onIceConnectionStateChange(sid, session) {
|
189
|
191
|
}
|
190
|
192
|
}
|
191
|
193
|
|
|
194
|
+JingleSession.prototype.getVideoType = function () {
|
|
195
|
+ return APP.desktopsharing.isUsingScreenStream() ? 'screen' : 'camera';
|
|
196
|
+};
|
|
197
|
+
|
192
|
198
|
JingleSession.prototype.accept = function () {
|
193
|
199
|
this.state = 'active';
|
194
|
200
|
|
|
@@ -216,7 +222,12 @@ JingleSession.prototype.accept = function () {
|
216
|
222
|
initiator: this.initiator,
|
217
|
223
|
responder: this.responder,
|
218
|
224
|
sid: this.sid });
|
219
|
|
- prsdp.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder', this.localStreamsSSRC);
|
|
225
|
+ // FIXME why do we generate session-accept in 3 different places ?
|
|
226
|
+ prsdp.toJingle(
|
|
227
|
+ accept,
|
|
228
|
+ this.initiator == this.me ? 'initiator' : 'responder',
|
|
229
|
+ this.localStreamsSSRC,
|
|
230
|
+ self.getVideoType());
|
220
|
231
|
var sdp = this.peerconnection.localDescription.sdp;
|
221
|
232
|
while (SDPUtil.find_line(sdp, 'a=inactive')) {
|
222
|
233
|
// FIXME: change any inactive to sendrecv or whatever they were originally
|
|
@@ -303,6 +314,7 @@ JingleSession.prototype.sendIceCandidate = function (candidate) {
|
303
|
314
|
//console.log('sendIceCandidate: last candidate.');
|
304
|
315
|
if (!this.usetrickle) {
|
305
|
316
|
//console.log('should send full offer now...');
|
|
317
|
+ //FIXME why do we generate session-accept in 3 different places ?
|
306
|
318
|
var init = $iq({to: this.peerjid,
|
307
|
319
|
type: 'set'})
|
308
|
320
|
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
|
@@ -314,7 +326,11 @@ JingleSession.prototype.sendIceCandidate = function (candidate) {
|
314
|
326
|
var sendJingle = function (ssrc) {
|
315
|
327
|
if(!ssrc)
|
316
|
328
|
ssrc = {};
|
317
|
|
- self.localSDP.toJingle(init, self.initiator == self.me ? 'initiator' : 'responder', ssrc);
|
|
329
|
+ self.localSDP.toJingle(
|
|
330
|
+ init,
|
|
331
|
+ self.initiator == self.me ? 'initiator' : 'responder',
|
|
332
|
+ ssrc,
|
|
333
|
+ self.getVideoType());
|
318
|
334
|
self.connection.sendIQ(init,
|
319
|
335
|
function () {
|
320
|
336
|
//console.log('session initiate ack');
|
|
@@ -414,6 +430,7 @@ JingleSession.prototype.sendOffer = function () {
|
414
|
430
|
);
|
415
|
431
|
};
|
416
|
432
|
|
|
433
|
+// FIXME createdOffer is never used in jitsi-meet
|
417
|
434
|
JingleSession.prototype.createdOffer = function (sdp) {
|
418
|
435
|
//console.log('createdOffer', sdp);
|
419
|
436
|
var self = this;
|
|
@@ -426,7 +443,11 @@ JingleSession.prototype.createdOffer = function (sdp) {
|
426
|
443
|
action: 'session-initiate',
|
427
|
444
|
initiator: this.initiator,
|
428
|
445
|
sid: this.sid});
|
429
|
|
- self.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder', this.localStreamsSSRC);
|
|
446
|
+ self.localSDP.toJingle(
|
|
447
|
+ init,
|
|
448
|
+ this.initiator == this.me ? 'initiator' : 'responder',
|
|
449
|
+ this.localStreamsSSRC,
|
|
450
|
+ self.getVideoType());
|
430
|
451
|
self.connection.sendIQ(init,
|
431
|
452
|
function () {
|
432
|
453
|
var ack = {};
|
|
@@ -471,10 +492,35 @@ JingleSession.prototype.createdOffer = function (sdp) {
|
471
|
492
|
}
|
472
|
493
|
};
|
473
|
494
|
|
|
495
|
+JingleSession.prototype.readSsrcInfo = function (contents) {
|
|
496
|
+ var self = this;
|
|
497
|
+ $(contents).each(function (idx, content) {
|
|
498
|
+ var name = $(content).attr('name');
|
|
499
|
+ var mediaType = this.getAttribute('name');
|
|
500
|
+ var ssrcs = $(content).find('description>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]');
|
|
501
|
+ ssrcs.each(function () {
|
|
502
|
+ var ssrc = this.getAttribute('ssrc');
|
|
503
|
+ $(this).find('>ssrc-info[xmlns="http://jitsi.org/jitmeet"]').each(
|
|
504
|
+ function () {
|
|
505
|
+ var owner = this.getAttribute('owner');
|
|
506
|
+ var videoType = this.getAttribute('video-type');
|
|
507
|
+ self.ssrcOwners[ssrc] = owner;
|
|
508
|
+ self.ssrcVideoTypes[ssrc] = videoType;
|
|
509
|
+ }
|
|
510
|
+ );
|
|
511
|
+ });
|
|
512
|
+ });
|
|
513
|
+};
|
|
514
|
+
|
|
515
|
+JingleSession.prototype.getSsrcOwner = function (ssrc) {
|
|
516
|
+ return this.ssrcOwners[ssrc];
|
|
517
|
+};
|
|
518
|
+
|
474
|
519
|
JingleSession.prototype.setRemoteDescription = function (elem, desctype) {
|
475
|
520
|
//console.log('setting remote description... ', desctype);
|
476
|
521
|
this.remoteSDP = new SDP('');
|
477
|
522
|
this.remoteSDP.fromJingle(elem);
|
|
523
|
+ this.readSsrcInfo($(elem).find(">content"));
|
478
|
524
|
if (this.peerconnection.remoteDescription !== null) {
|
479
|
525
|
console.log('setRemoteDescription when remote description is not null, should be pranswer', this.peerconnection.remoteDescription);
|
480
|
526
|
if (this.peerconnection.remoteDescription.type == 'pranswer') {
|
|
@@ -655,7 +701,7 @@ JingleSession.prototype.createdAnswer = function (sdp, provisional) {
|
655
|
701
|
}
|
656
|
702
|
var self = this;
|
657
|
703
|
var sendJingle = function (ssrcs) {
|
658
|
|
-
|
|
704
|
+ // FIXME why do we generate session-accept in 3 different places ?
|
659
|
705
|
var accept = $iq({to: self.peerjid,
|
660
|
706
|
type: 'set'})
|
661
|
707
|
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
|
@@ -663,7 +709,11 @@ JingleSession.prototype.createdAnswer = function (sdp, provisional) {
|
663
|
709
|
initiator: self.initiator,
|
664
|
710
|
responder: self.responder,
|
665
|
711
|
sid: self.sid });
|
666
|
|
- self.localSDP.toJingle(accept, self.initiator == self.me ? 'initiator' : 'responder', ssrcs);
|
|
712
|
+ self.localSDP.toJingle(
|
|
713
|
+ accept,
|
|
714
|
+ self.initiator == self.me ? 'initiator' : 'responder',
|
|
715
|
+ ssrcs,
|
|
716
|
+ self.getVideoType());
|
667
|
717
|
self.connection.sendIQ(accept,
|
668
|
718
|
function () {
|
669
|
719
|
var ack = {};
|
|
@@ -762,6 +812,9 @@ JingleSession.prototype.addSource = function (elem, fromJid) {
|
762
|
812
|
|
763
|
813
|
console.log('addssrc', new Date().getTime());
|
764
|
814
|
console.log('ice', this.peerconnection.iceConnectionState);
|
|
815
|
+
|
|
816
|
+ this.readSsrcInfo(elem);
|
|
817
|
+
|
765
|
818
|
var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
|
766
|
819
|
var mySdp = new SDP(this.peerconnection.localDescription.sdp);
|
767
|
820
|
|
|
@@ -1085,7 +1138,7 @@ JingleSession.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) {
|
1085
|
1138
|
sid: this.sid
|
1086
|
1139
|
}
|
1087
|
1140
|
);
|
1088
|
|
- var added = sdpDiffer.toJingle(add);
|
|
1141
|
+ var added = sdpDiffer.toJingle(add, this.getVideoType());
|
1089
|
1142
|
if (added) {
|
1090
|
1143
|
this.connection.sendIQ(add,
|
1091
|
1144
|
function (res) {
|
|
@@ -1245,7 +1298,7 @@ JingleSession.onJingleFatalError = function (session, error)
|
1245
|
1298
|
}
|
1246
|
1299
|
|
1247
|
1300
|
JingleSession.prototype.setLocalDescription = function () {
|
1248
|
|
- // put our ssrcs into presence so other clients can identify our stream
|
|
1301
|
+ var self = this;
|
1249
|
1302
|
var newssrcs = [];
|
1250
|
1303
|
var session = transform.parse(this.peerconnection.localDescription.sdp);
|
1251
|
1304
|
session.media.forEach(function (media) {
|
|
@@ -1258,17 +1311,15 @@ JingleSession.prototype.setLocalDescription = function () {
|
1258
|
1311
|
}
|
1259
|
1312
|
newssrcs.push({
|
1260
|
1313
|
'ssrc': ssrc.id,
|
1261
|
|
- 'type': media.type,
|
1262
|
|
- 'direction': media.direction
|
|
1314
|
+ 'type': media.type
|
1263
|
1315
|
});
|
1264
|
1316
|
});
|
1265
|
1317
|
}
|
1266
|
|
- else if(this.localStreamsSSRC && this.localStreamsSSRC[media.type])
|
|
1318
|
+ else if(self.localStreamsSSRC && self.localStreamsSSRC[media.type])
|
1267
|
1319
|
{
|
1268
|
1320
|
newssrcs.push({
|
1269
|
|
- 'ssrc': this.localStreamsSSRC[media.type],
|
1270
|
|
- 'type': media.type,
|
1271
|
|
- 'direction': media.direction
|
|
1321
|
+ 'ssrc': self.localStreamsSSRC[media.type],
|
|
1322
|
+ 'type': media.type
|
1272
|
1323
|
});
|
1273
|
1324
|
}
|
1274
|
1325
|
|
|
@@ -1276,20 +1327,16 @@ JingleSession.prototype.setLocalDescription = function () {
|
1276
|
1327
|
|
1277
|
1328
|
console.log('new ssrcs', newssrcs);
|
1278
|
1329
|
|
1279
|
|
- // Have to clear presence map to get rid of removed streams
|
1280
|
|
- this.connection.emuc.clearPresenceMedia();
|
1281
|
|
-
|
|
1330
|
+ // Bind us as local SSRCs owner
|
1282
|
1331
|
if (newssrcs.length > 0) {
|
1283
|
1332
|
for (var i = 1; i <= newssrcs.length; i ++) {
|
1284
|
|
- // Change video type to screen
|
1285
|
|
- if (newssrcs[i-1].type === 'video' && APP.desktopsharing.isUsingScreenStream()) {
|
1286
|
|
- newssrcs[i-1].type = 'screen';
|
|
1333
|
+ var ssrc = newssrcs[i-1].ssrc;
|
|
1334
|
+ var myJid = self.connection.emuc.myroomjid;
|
|
1335
|
+ self.ssrcOwners[ssrc] = myJid;
|
|
1336
|
+ if (newssrcs[i-1].type === 'video'){
|
|
1337
|
+ self.ssrcVideoTypes[ssrc] = self.getVideoType();
|
1287
|
1338
|
}
|
1288
|
|
- this.connection.emuc.addMediaToPresence(i,
|
1289
|
|
- newssrcs[i-1].type, newssrcs[i-1].ssrc, newssrcs[i-1].direction);
|
1290
|
1339
|
}
|
1291
|
|
-
|
1292
|
|
- this.connection.emuc.sendPresence();
|
1293
|
1340
|
}
|
1294
|
1341
|
}
|
1295
|
1342
|
|
|
@@ -1331,7 +1378,6 @@ function sendKeyframe(pc) {
|
1331
|
1378
|
JingleSession.prototype.remoteStreamAdded = function (data, times) {
|
1332
|
1379
|
var self = this;
|
1333
|
1380
|
var thessrc;
|
1334
|
|
- var ssrc2jid = this.connection.emuc.ssrc2jid;
|
1335
|
1381
|
var streamId = APP.RTC.getStreamID(data.stream);
|
1336
|
1382
|
|
1337
|
1383
|
// look up an associated JID for a stream id
|
|
@@ -1354,40 +1400,14 @@ JingleSession.prototype.remoteStreamAdded = function (data, times) {
|
1354
|
1400
|
if (ssrclines.length) {
|
1355
|
1401
|
thessrc = ssrclines[0].substring(7).split(' ')[0];
|
1356
|
1402
|
|
1357
|
|
- // We signal our streams (through Jingle to the focus) before we set
|
1358
|
|
- // our presence (through which peers associate remote streams to
|
1359
|
|
- // jids). So, it might arrive that a remote stream is added but
|
1360
|
|
- // ssrc2jid is not yet updated and thus data.peerjid cannot be
|
1361
|
|
- // successfully set. Here we wait for up to a second for the
|
1362
|
|
- // presence to arrive.
|
1363
|
|
-
|
1364
|
|
- if (!ssrc2jid[thessrc]) {
|
1365
|
|
-
|
1366
|
|
- if (typeof times === 'undefined')
|
1367
|
|
- {
|
1368
|
|
- times = 0;
|
1369
|
|
- }
|
1370
|
|
-
|
1371
|
|
- if (times > 10)
|
1372
|
|
- {
|
1373
|
|
- console.warning('Waiting for jid timed out', thessrc);
|
1374
|
|
- }
|
1375
|
|
- else
|
1376
|
|
- {
|
1377
|
|
- setTimeout(function(d) {
|
1378
|
|
- return function() {
|
1379
|
|
- self.remoteStreamAdded(d, times++);
|
1380
|
|
- }
|
1381
|
|
- }(data), 250);
|
1382
|
|
- }
|
|
1403
|
+ if (!self.ssrcOwners[thessrc]) {
|
|
1404
|
+ console.error("No SSRC owner known for: " + thessrc);
|
1383
|
1405
|
return;
|
1384
|
1406
|
}
|
1385
|
|
-
|
1386
|
|
- // ok to overwrite the one from focus? might save work in colibri.js
|
1387
|
|
- console.log('associated jid', ssrc2jid[thessrc], thessrc);
|
1388
|
|
- if (ssrc2jid[thessrc]) {
|
1389
|
|
- data.peerjid = ssrc2jid[thessrc];
|
1390
|
|
- }
|
|
1407
|
+ data.peerjid = self.ssrcOwners[thessrc];
|
|
1408
|
+ data.videoType = self.ssrcVideoTypes[thessrc]
|
|
1409
|
+ console.log('associated jid', self.ssrcOwners[thessrc],
|
|
1410
|
+ thessrc, data.videoType);
|
1391
|
1411
|
}
|
1392
|
1412
|
}
|
1393
|
1413
|
|