|
@@ -50,10 +50,8 @@ SDP.prototype.removeUdpCandidates = false;
|
50
|
50
|
*/
|
51
|
51
|
SDP.prototype.getMediaSsrcMap = function() {
|
52
|
52
|
const mediaSSRCs = {};
|
53
|
|
- let tmp;
|
54
|
53
|
|
55
|
54
|
for (let mediaindex = 0; mediaindex < this.media.length; mediaindex++) {
|
56
|
|
- tmp = SDPUtil.findLines(this.media[mediaindex], 'a=ssrc:');
|
57
|
55
|
const mid
|
58
|
56
|
= SDPUtil.parseMID(
|
59
|
57
|
SDPUtil.findLine(this.media[mediaindex], 'a=mid:'));
|
|
@@ -65,7 +63,8 @@ SDP.prototype.getMediaSsrcMap = function() {
|
65
|
63
|
};
|
66
|
64
|
|
67
|
65
|
mediaSSRCs[mediaindex] = media;
|
68
|
|
- tmp.forEach(line => {
|
|
66
|
+
|
|
67
|
+ SDPUtil.findLines(this.media[mediaindex], 'a=ssrc:').forEach(line => {
|
69
|
68
|
const linessrc = line.substring(7).split(' ')[0];
|
70
|
69
|
|
71
|
70
|
// allocate new ChannelSsrc
|
|
@@ -78,8 +77,7 @@ SDP.prototype.getMediaSsrcMap = function() {
|
78
|
77
|
}
|
79
|
78
|
media.ssrcs[linessrc].lines.push(line);
|
80
|
79
|
});
|
81
|
|
- tmp = SDPUtil.findLines(this.media[mediaindex], 'a=ssrc-group:');
|
82
|
|
- tmp.forEach(line => {
|
|
80
|
+ SDPUtil.findLines(this.media[mediaindex], 'a=ssrc-group:').forEach(line => {
|
83
|
81
|
const idx = line.indexOf(' ');
|
84
|
82
|
const semantics = line.substr(0, idx).substr(13);
|
85
|
83
|
const ssrcs = line.substr(14 + semantics.length).split(' ');
|
|
@@ -120,31 +118,29 @@ SDP.prototype.containsSSRC = function(ssrc) {
|
120
|
118
|
|
121
|
119
|
// add content's to a jingle element
|
122
|
120
|
SDP.prototype.toJingle = function(elem, thecreator) {
|
123
|
|
- let i, j, k, lines, mline, rtpmap, ssrc, tmp;
|
124
|
|
-
|
125
|
|
- // new bundle plan
|
|
121
|
+ // https://xmpp.org/extensions/xep-0338.html
|
|
122
|
+ SDPUtil.findLines(this.session, 'a=group:').forEach(line => {
|
|
123
|
+ const parts = line.split(' ');
|
|
124
|
+ const semantics = parts.shift().substr(8);
|
|
125
|
+
|
|
126
|
+ elem.c('group', { xmlns: 'urn:xmpp:jingle:apps:grouping:0',
|
|
127
|
+ semantics });
|
|
128
|
+ for (let j = 0; j < parts.length; j++) {
|
|
129
|
+ elem.c('content', { name: parts[j] }).up();
|
|
130
|
+ }
|
|
131
|
+ elem.up();
|
|
132
|
+ });
|
126
|
133
|
|
127
|
|
- lines = SDPUtil.findLines(this.session, 'a=group:');
|
128
|
|
- if (lines.length) {
|
129
|
|
- for (i = 0; i < lines.length; i++) {
|
130
|
|
- tmp = lines[i].split(' ');
|
131
|
|
- const semantics = tmp.shift().substr(8);
|
|
134
|
+ for (let i = 0; i < this.media.length; i++) {
|
|
135
|
+ const mline = SDPUtil.parseMLine(this.media[i].split('\r\n')[0]);
|
132
|
136
|
|
133
|
|
- elem.c('group', { xmlns: 'urn:xmpp:jingle:apps:grouping:0',
|
134
|
|
- semantics });
|
135
|
|
- for (j = 0; j < tmp.length; j++) {
|
136
|
|
- elem.c('content', { name: tmp[j] }).up();
|
137
|
|
- }
|
138
|
|
- elem.up();
|
139
|
|
- }
|
140
|
|
- }
|
141
|
|
- for (i = 0; i < this.media.length; i++) {
|
142
|
|
- mline = SDPUtil.parseMLine(this.media[i].split('\r\n')[0]);
|
143
|
137
|
if (!(mline.media === 'audio'
|
144
|
138
|
|| mline.media === 'video'
|
145
|
139
|
|| mline.media === 'application')) {
|
146
|
140
|
continue; // eslint-disable-line no-continue
|
147
|
141
|
}
|
|
142
|
+
|
|
143
|
+ let ssrc;
|
148
|
144
|
const assrcline = SDPUtil.findLine(this.media[i], 'a=ssrc:');
|
149
|
145
|
|
150
|
146
|
if (assrcline) {
|
|
@@ -164,18 +160,19 @@ SDP.prototype.toJingle = function(elem, thecreator) {
|
164
|
160
|
elem.attrs({ name: mid });
|
165
|
161
|
}
|
166
|
162
|
|
167
|
|
- if (SDPUtil.findLine(this.media[i], 'a=rtpmap:').length) {
|
|
163
|
+ if (mline.media === 'audio' || mline.media === 'video') {
|
168
|
164
|
elem.c('description',
|
169
|
165
|
{ xmlns: 'urn:xmpp:jingle:apps:rtp:1',
|
170
|
166
|
media: mline.media });
|
171
|
167
|
if (ssrc) {
|
172
|
168
|
elem.attrs({ ssrc });
|
173
|
169
|
}
|
174
|
|
- for (j = 0; j < mline.fmt.length; j++) {
|
175
|
|
- rtpmap
|
|
170
|
+ for (let j = 0; j < mline.fmt.length; j++) {
|
|
171
|
+ const rtpmap
|
176
|
172
|
= SDPUtil.findLine(
|
177
|
173
|
this.media[i],
|
178
|
174
|
`a=rtpmap:${mline.fmt[j]}`);
|
|
175
|
+
|
179
|
176
|
elem.c('payload-type', SDPUtil.parseRTPMap(rtpmap));
|
180
|
177
|
|
181
|
178
|
// put any 'a=fmtp:' + mline.fmt[j] lines into <param name=foo
|
|
@@ -186,11 +183,11 @@ SDP.prototype.toJingle = function(elem, thecreator) {
|
186
|
183
|
`a=fmtp:${mline.fmt[j]}`);
|
187
|
184
|
|
188
|
185
|
if (afmtpline) {
|
189
|
|
- tmp = SDPUtil.parseFmtp(afmtpline);
|
|
186
|
+ const fmtpParameters = SDPUtil.parseFmtp(afmtpline);
|
190
|
187
|
|
191
|
188
|
// eslint-disable-next-line max-depth
|
192
|
|
- for (k = 0; k < tmp.length; k++) {
|
193
|
|
- elem.c('parameter', tmp[k]).up();
|
|
189
|
+ for (let k = 0; k < fmtpParameters.length; k++) {
|
|
190
|
+ elem.c('parameter', fmtpParameters[k]).up();
|
194
|
191
|
}
|
195
|
192
|
}
|
196
|
193
|
|
|
@@ -290,39 +287,39 @@ SDP.prototype.toJingle = function(elem, thecreator) {
|
290
|
287
|
this.rtcpFbToJingle(i, elem, '*');
|
291
|
288
|
|
292
|
289
|
// XEP-0294
|
293
|
|
- lines = SDPUtil.findLines(this.media[i], 'a=extmap:');
|
294
|
|
- if (lines.length) {
|
295
|
|
- for (j = 0; j < lines.length; j++) {
|
296
|
|
- tmp = SDPUtil.parseExtmap(lines[j]);
|
297
|
|
- elem.c('rtp-hdrext', {
|
298
|
|
- xmlns: 'urn:xmpp:jingle:apps:rtp:rtp-hdrext:0',
|
299
|
|
- uri: tmp.uri,
|
300
|
|
- id: tmp.value
|
301
|
|
- });
|
|
290
|
+ const extmapLines = SDPUtil.findLines(this.media[i], 'a=extmap:');
|
|
291
|
+
|
|
292
|
+ for (let j = 0; j < extmapLines.length; j++) {
|
|
293
|
+ const extmap = SDPUtil.parseExtmap(extmapLines[j]);
|
|
294
|
+
|
|
295
|
+ elem.c('rtp-hdrext', {
|
|
296
|
+ xmlns: 'urn:xmpp:jingle:apps:rtp:rtp-hdrext:0',
|
|
297
|
+ uri: extmap.uri,
|
|
298
|
+ id: extmap.value
|
|
299
|
+ });
|
|
300
|
+
|
|
301
|
+ // eslint-disable-next-line max-depth
|
|
302
|
+ if (extmap.hasOwnProperty('direction')) {
|
302
|
303
|
|
303
|
304
|
// eslint-disable-next-line max-depth
|
304
|
|
- if (tmp.hasOwnProperty('direction')) {
|
305
|
|
-
|
306
|
|
- // eslint-disable-next-line max-depth
|
307
|
|
- switch (tmp.direction) {
|
308
|
|
- case 'sendonly':
|
309
|
|
- elem.attrs({ senders: 'responder' });
|
310
|
|
- break;
|
311
|
|
- case 'recvonly':
|
312
|
|
- elem.attrs({ senders: 'initiator' });
|
313
|
|
- break;
|
314
|
|
- case 'sendrecv':
|
315
|
|
- elem.attrs({ senders: 'both' });
|
316
|
|
- break;
|
317
|
|
- case 'inactive':
|
318
|
|
- elem.attrs({ senders: 'none' });
|
319
|
|
- break;
|
320
|
|
- }
|
|
305
|
+ switch (extmap.direction) {
|
|
306
|
+ case 'sendonly':
|
|
307
|
+ elem.attrs({ senders: 'responder' });
|
|
308
|
+ break;
|
|
309
|
+ case 'recvonly':
|
|
310
|
+ elem.attrs({ senders: 'initiator' });
|
|
311
|
+ break;
|
|
312
|
+ case 'sendrecv':
|
|
313
|
+ elem.attrs({ senders: 'both' });
|
|
314
|
+ break;
|
|
315
|
+ case 'inactive':
|
|
316
|
+ elem.attrs({ senders: 'none' });
|
|
317
|
+ break;
|
321
|
318
|
}
|
322
|
|
-
|
323
|
|
- // TODO: handle params
|
324
|
|
- elem.up();
|
325
|
319
|
}
|
|
320
|
+
|
|
321
|
+ // TODO: handle params
|
|
322
|
+ elem.up();
|
326
|
323
|
}
|
327
|
324
|
elem.up(); // end of description
|
328
|
325
|
}
|
|
@@ -356,8 +353,6 @@ SDP.prototype.toJingle = function(elem, thecreator) {
|
356
|
353
|
};
|
357
|
354
|
|
358
|
355
|
SDP.prototype.transportToJingle = function(mediaindex, elem) {
|
359
|
|
- let tmp;
|
360
|
|
-
|
361
|
356
|
elem.c('transport');
|
362
|
357
|
|
363
|
358
|
// XEP-0343 DTLS/SCTP
|
|
@@ -388,55 +383,55 @@ SDP.prototype.transportToJingle = function(mediaindex, elem) {
|
388
|
383
|
this.session);
|
389
|
384
|
|
390
|
385
|
fingerprints.forEach(line => {
|
391
|
|
- tmp = SDPUtil.parseFingerprint(line);
|
392
|
|
- tmp.xmlns = 'urn:xmpp:jingle:apps:dtls:0';
|
393
|
|
- elem.c('fingerprint').t(tmp.fingerprint);
|
394
|
|
- delete tmp.fingerprint;
|
|
386
|
+ const fingerprint = SDPUtil.parseFingerprint(line);
|
395
|
387
|
|
396
|
|
- // eslint-disable-next-line no-param-reassign
|
397
|
|
- line
|
|
388
|
+ fingerprint.xmlns = 'urn:xmpp:jingle:apps:dtls:0';
|
|
389
|
+ elem.c('fingerprint').t(fingerprint.fingerprint);
|
|
390
|
+ delete fingerprint.fingerprint;
|
|
391
|
+
|
|
392
|
+ const setupLine
|
398
|
393
|
= SDPUtil.findLine(
|
399
|
394
|
this.media[mediaindex],
|
400
|
395
|
'a=setup:',
|
401
|
396
|
this.session);
|
402
|
|
- if (line) {
|
403
|
|
- tmp.setup = line.substr(8);
|
|
397
|
+
|
|
398
|
+ if (setupLine) {
|
|
399
|
+ fingerprint.setup = setupLine.substr(8);
|
404
|
400
|
}
|
405
|
|
- elem.attrs(tmp);
|
|
401
|
+ elem.attrs(fingerprint);
|
406
|
402
|
elem.up(); // end of fingerprint
|
407
|
403
|
});
|
408
|
|
- tmp = SDPUtil.iceparams(this.media[mediaindex], this.session);
|
409
|
|
- if (tmp) {
|
410
|
|
- tmp.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';
|
411
|
|
- elem.attrs(tmp);
|
|
404
|
+ const iceParameters = SDPUtil.iceparams(this.media[mediaindex], this.session);
|
|
405
|
+
|
|
406
|
+ if (iceParameters) {
|
|
407
|
+ iceParameters.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';
|
|
408
|
+ elem.attrs(iceParameters);
|
412
|
409
|
|
413
|
410
|
// XEP-0176
|
414
|
|
- const lines
|
|
411
|
+ const candidateLines
|
415
|
412
|
= SDPUtil.findLines(
|
416
|
413
|
this.media[mediaindex],
|
417
|
414
|
'a=candidate:',
|
418
|
415
|
this.session);
|
419
|
416
|
|
420
|
|
- if (lines.length) { // add any a=candidate lines
|
421
|
|
- lines.forEach(line => {
|
422
|
|
- const candidate = SDPUtil.candidateToJingle(line);
|
|
417
|
+ candidateLines.forEach(line => { // add any a=candidate lines
|
|
418
|
+ const candidate = SDPUtil.candidateToJingle(line);
|
423
|
419
|
|
424
|
|
- if (this.failICE) {
|
425
|
|
- candidate.ip = '1.1.1.1';
|
426
|
|
- }
|
427
|
|
- const protocol
|
428
|
|
- = candidate && typeof candidate.protocol === 'string'
|
429
|
|
- ? candidate.protocol.toLowerCase()
|
430
|
|
- : '';
|
431
|
|
-
|
432
|
|
- if ((this.removeTcpCandidates
|
433
|
|
- && (protocol === 'tcp' || protocol === 'ssltcp'))
|
434
|
|
- || (this.removeUdpCandidates && protocol === 'udp')) {
|
435
|
|
- return;
|
436
|
|
- }
|
437
|
|
- elem.c('candidate', candidate).up();
|
438
|
|
- });
|
439
|
|
- }
|
|
420
|
+ if (this.failICE) {
|
|
421
|
+ candidate.ip = '1.1.1.1';
|
|
422
|
+ }
|
|
423
|
+ const protocol
|
|
424
|
+ = candidate && typeof candidate.protocol === 'string'
|
|
425
|
+ ? candidate.protocol.toLowerCase()
|
|
426
|
+ : '';
|
|
427
|
+
|
|
428
|
+ if ((this.removeTcpCandidates
|
|
429
|
+ && (protocol === 'tcp' || protocol === 'ssltcp'))
|
|
430
|
+ || (this.removeUdpCandidates && protocol === 'udp')) {
|
|
431
|
+ return;
|
|
432
|
+ }
|
|
433
|
+ elem.c('candidate', candidate).up();
|
|
434
|
+ });
|
440
|
435
|
}
|
441
|
436
|
elem.up(); // end of transport
|
442
|
437
|
};
|
|
@@ -449,21 +444,21 @@ SDP.prototype.rtcpFbToJingle = function(mediaindex, elem, payloadtype) {
|
449
|
444
|
`a=rtcp-fb:${payloadtype}`);
|
450
|
445
|
|
451
|
446
|
lines.forEach(line => {
|
452
|
|
- const tmp = SDPUtil.parseRTCPFB(line);
|
|
447
|
+ const feedback = SDPUtil.parseRTCPFB(line);
|
453
|
448
|
|
454
|
|
- if (tmp.type === 'trr-int') {
|
|
449
|
+ if (feedback.type === 'trr-int') {
|
455
|
450
|
elem.c('rtcp-fb-trr-int', {
|
456
|
451
|
xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0',
|
457
|
|
- value: tmp.params[0]
|
|
452
|
+ value: feedback.params[0]
|
458
|
453
|
});
|
459
|
454
|
elem.up();
|
460
|
455
|
} else {
|
461
|
456
|
elem.c('rtcp-fb', {
|
462
|
457
|
xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0',
|
463
|
|
- type: tmp.type
|
|
458
|
+ type: feedback.type
|
464
|
459
|
});
|
465
|
|
- if (tmp.params.length > 0) {
|
466
|
|
- elem.attrs({ 'subtype': tmp.params[0] });
|
|
460
|
+ if (feedback.params.length > 0) {
|
|
461
|
+ elem.attrs({ 'subtype': feedback.params[0] });
|
467
|
462
|
}
|
468
|
463
|
elem.up();
|
469
|
464
|
}
|
|
@@ -471,30 +466,32 @@ SDP.prototype.rtcpFbToJingle = function(mediaindex, elem, payloadtype) {
|
471
|
466
|
};
|
472
|
467
|
|
473
|
468
|
SDP.prototype.rtcpFbFromJingle = function(elem, payloadtype) { // XEP-0293
|
474
|
|
- let media = '';
|
475
|
|
- let tmp
|
|
469
|
+ let sdp = '';
|
|
470
|
+ const feedbackElementTrrInt
|
476
|
471
|
= elem.find(
|
477
|
472
|
'>rtcp-fb-trr-int[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
|
478
|
473
|
|
479
|
|
- if (tmp.length) {
|
480
|
|
- media += 'a=rtcp-fb:* trr-int ';
|
481
|
|
- if (tmp.attr('value')) {
|
482
|
|
- media += tmp.attr('value');
|
|
474
|
+ if (feedbackElementTrrInt.length) {
|
|
475
|
+ sdp += 'a=rtcp-fb:* trr-int ';
|
|
476
|
+ if (feedbackElementTrrInt.attr('value')) {
|
|
477
|
+ sdp += feedbackElementTrrInt.attr('value');
|
483
|
478
|
} else {
|
484
|
|
- media += '0';
|
|
479
|
+ sdp += '0';
|
485
|
480
|
}
|
486
|
|
- media += '\r\n';
|
|
481
|
+ sdp += '\r\n';
|
487
|
482
|
}
|
488
|
|
- tmp = elem.find('>rtcp-fb[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
|
489
|
|
- tmp.each((_, fb) => {
|
490
|
|
- media += `a=rtcp-fb:${payloadtype} ${fb.getAttribute('type')}`;
|
|
483
|
+
|
|
484
|
+ const feedbackElements = elem.find('>rtcp-fb[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
|
|
485
|
+
|
|
486
|
+ feedbackElements.each((_, fb) => {
|
|
487
|
+ sdp += `a=rtcp-fb:${payloadtype} ${fb.getAttribute('type')}`;
|
491
|
488
|
if (fb.hasAttribute('subtype')) {
|
492
|
|
- media += ` ${fb.getAttribute('subtype')}`;
|
|
489
|
+ sdp += ` ${fb.getAttribute('subtype')}`;
|
493
|
490
|
}
|
494
|
|
- media += '\r\n';
|
|
491
|
+ sdp += '\r\n';
|
495
|
492
|
});
|
496
|
493
|
|
497
|
|
- return media;
|
|
494
|
+ return sdp;
|
498
|
495
|
};
|
499
|
496
|
|
500
|
497
|
// construct an SDP from a jingle stanza
|
|
@@ -552,62 +549,62 @@ SDP.prototype.fromJingle = function(jingle) {
|
552
|
549
|
SDP.prototype.jingle2media = function(content) {
|
553
|
550
|
const desc = content.find('>description');
|
554
|
551
|
const transport = content.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
555
|
|
- let media = '';
|
|
552
|
+ let sdp = '';
|
556
|
553
|
const sctp = transport.find(
|
557
|
554
|
'>sctpmap[xmlns="urn:xmpp:jingle:transports:dtls-sctp:1"]');
|
558
|
555
|
|
559
|
|
- let tmp = { media: desc.attr('media') };
|
|
556
|
+ const media = { media: desc.attr('media') };
|
560
|
557
|
|
561
|
|
- tmp.port = '1';
|
|
558
|
+ media.port = '1';
|
562
|
559
|
if (content.attr('senders') === 'rejected') {
|
563
|
560
|
// estos hack to reject an m-line.
|
564
|
|
- tmp.port = '0';
|
|
561
|
+ media.port = '0';
|
565
|
562
|
}
|
566
|
563
|
if (transport.find('>fingerprint[xmlns="urn:xmpp:jingle:apps:dtls:0"]').length) {
|
567
|
|
- tmp.proto = sctp.length ? 'DTLS/SCTP' : 'RTP/SAVPF';
|
|
564
|
+ media.proto = sctp.length ? 'DTLS/SCTP' : 'RTP/SAVPF';
|
568
|
565
|
} else {
|
569
|
|
- tmp.proto = 'RTP/AVPF';
|
|
566
|
+ media.proto = 'RTP/AVPF';
|
570
|
567
|
}
|
571
|
568
|
if (sctp.length) {
|
572
|
|
- media += `m=application ${tmp.port} DTLS/SCTP ${
|
|
569
|
+ sdp += `m=application ${media.port} DTLS/SCTP ${
|
573
|
570
|
sctp.attr('number')}\r\n`;
|
574
|
|
- media += `a=sctpmap:${sctp.attr('number')} ${sctp.attr('protocol')}`;
|
|
571
|
+ sdp += `a=sctpmap:${sctp.attr('number')} ${sctp.attr('protocol')}`;
|
575
|
572
|
|
576
|
573
|
const streamCount = sctp.attr('streams');
|
577
|
574
|
|
578
|
575
|
if (streamCount) {
|
579
|
|
- media += ` ${streamCount}\r\n`;
|
|
576
|
+ sdp += ` ${streamCount}\r\n`;
|
580
|
577
|
} else {
|
581
|
|
- media += '\r\n';
|
|
578
|
+ sdp += '\r\n';
|
582
|
579
|
}
|
583
|
580
|
} else {
|
584
|
|
- tmp.fmt
|
|
581
|
+ media.fmt
|
585
|
582
|
= desc
|
586
|
583
|
.find('>payload-type')
|
587
|
584
|
.map((_, payloadType) => payloadType.getAttribute('id'))
|
588
|
585
|
.get();
|
589
|
|
- media += `${SDPUtil.buildMLine(tmp)}\r\n`;
|
|
586
|
+ sdp += `${SDPUtil.buildMLine(media)}\r\n`;
|
590
|
587
|
}
|
591
|
588
|
|
592
|
|
- media += 'c=IN IP4 0.0.0.0\r\n';
|
|
589
|
+ sdp += 'c=IN IP4 0.0.0.0\r\n';
|
593
|
590
|
if (!sctp.length) {
|
594
|
|
- media += 'a=rtcp:1 IN IP4 0.0.0.0\r\n';
|
|
591
|
+ sdp += 'a=rtcp:1 IN IP4 0.0.0.0\r\n';
|
595
|
592
|
}
|
596
|
593
|
|
597
|
594
|
// XEP-0176 ICE parameters
|
598
|
595
|
if (transport.length) {
|
599
|
596
|
if (transport.attr('ufrag')) {
|
600
|
|
- media += `${SDPUtil.buildICEUfrag(transport.attr('ufrag'))}\r\n`;
|
|
597
|
+ sdp += `${SDPUtil.buildICEUfrag(transport.attr('ufrag'))}\r\n`;
|
601
|
598
|
}
|
602
|
599
|
if (transport.attr('pwd')) {
|
603
|
|
- media += `${SDPUtil.buildICEPwd(transport.attr('pwd'))}\r\n`;
|
|
600
|
+ sdp += `${SDPUtil.buildICEPwd(transport.attr('pwd'))}\r\n`;
|
604
|
601
|
}
|
605
|
602
|
transport.find('>fingerprint[xmlns="urn:xmpp:jingle:apps:dtls:0"]').each((_, fingerprint) => {
|
606
|
|
- media += `a=fingerprint:${fingerprint.getAttribute('hash')}`;
|
607
|
|
- media += ` ${$(fingerprint).text()}`;
|
608
|
|
- media += '\r\n';
|
|
603
|
+ sdp += `a=fingerprint:${fingerprint.getAttribute('hash')}`;
|
|
604
|
+ sdp += ` ${$(fingerprint).text()}`;
|
|
605
|
+ sdp += '\r\n';
|
609
|
606
|
if (fingerprint.hasAttribute('setup')) {
|
610
|
|
- media += `a=setup:${fingerprint.getAttribute('setup')}\r\n`;
|
|
607
|
+ sdp += `a=setup:${fingerprint.getAttribute('setup')}\r\n`;
|
611
|
608
|
}
|
612
|
609
|
});
|
613
|
610
|
}
|
|
@@ -628,38 +625,38 @@ SDP.prototype.jingle2media = function(content) {
|
628
|
625
|
candidate.setAttribute('ip', '1.1.1.1');
|
629
|
626
|
}
|
630
|
627
|
|
631
|
|
- media += SDPUtil.candidateFromJingle(candidate);
|
|
628
|
+ sdp += SDPUtil.candidateFromJingle(candidate);
|
632
|
629
|
});
|
633
|
630
|
|
634
|
631
|
switch (content.attr('senders')) {
|
635
|
632
|
case 'initiator':
|
636
|
|
- media += 'a=sendonly\r\n';
|
|
633
|
+ sdp += 'a=sendonly\r\n';
|
637
|
634
|
break;
|
638
|
635
|
case 'responder':
|
639
|
|
- media += 'a=recvonly\r\n';
|
|
636
|
+ sdp += 'a=recvonly\r\n';
|
640
|
637
|
break;
|
641
|
638
|
case 'none':
|
642
|
|
- media += 'a=inactive\r\n';
|
|
639
|
+ sdp += 'a=inactive\r\n';
|
643
|
640
|
break;
|
644
|
641
|
case 'both':
|
645
|
|
- media += 'a=sendrecv\r\n';
|
|
642
|
+ sdp += 'a=sendrecv\r\n';
|
646
|
643
|
break;
|
647
|
644
|
}
|
648
|
|
- media += `a=mid:${content.attr('name')}\r\n`;
|
|
645
|
+ sdp += `a=mid:${content.attr('name')}\r\n`;
|
649
|
646
|
|
650
|
647
|
// <description><rtcp-mux/></description>
|
651
|
648
|
// see http://code.google.com/p/libjingle/issues/detail?id=309 -- no spec
|
652
|
649
|
// though
|
653
|
650
|
// and http://mail.jabber.org/pipermail/jingle/2011-December/001761.html
|
654
|
651
|
if (desc.find('>rtcp-mux').length) {
|
655
|
|
- media += 'a=rtcp-mux\r\n';
|
|
652
|
+ sdp += 'a=rtcp-mux\r\n';
|
656
|
653
|
}
|
657
|
654
|
|
658
|
655
|
desc.find('>payload-type').each((_, payloadType) => {
|
659
|
|
- media += `${SDPUtil.buildRTPMap(payloadType)}\r\n`;
|
|
656
|
+ sdp += `${SDPUtil.buildRTPMap(payloadType)}\r\n`;
|
660
|
657
|
if ($(payloadType).find('>parameter').length) {
|
661
|
|
- media += `a=fmtp:${payloadType.getAttribute('id')} `;
|
662
|
|
- media
|
|
658
|
+ sdp += `a=fmtp:${payloadType.getAttribute('id')} `;
|
|
659
|
+ sdp
|
663
|
660
|
+= $(payloadType)
|
664
|
661
|
.find('>parameter')
|
665
|
662
|
.map((__, parameter) => {
|
|
@@ -671,25 +668,24 @@ SDP.prototype.jingle2media = function(content) {
|
671
|
668
|
})
|
672
|
669
|
.get()
|
673
|
670
|
.join('; ');
|
674
|
|
- media += '\r\n';
|
|
671
|
+ sdp += '\r\n';
|
675
|
672
|
}
|
676
|
673
|
|
677
|
674
|
// xep-0293
|
678
|
|
- media += this.rtcpFbFromJingle($(payloadType), payloadType.getAttribute('id'));
|
|
675
|
+ sdp += this.rtcpFbFromJingle($(payloadType), payloadType.getAttribute('id'));
|
679
|
676
|
});
|
680
|
677
|
|
681
|
678
|
// xep-0293
|
682
|
|
- media += this.rtcpFbFromJingle(desc, '*');
|
|
679
|
+ sdp += this.rtcpFbFromJingle(desc, '*');
|
683
|
680
|
|
684
|
681
|
// xep-0294
|
685
|
|
- tmp
|
686
|
|
- = desc.find(
|
687
|
|
- '>rtp-hdrext[xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0"]');
|
688
|
|
- tmp.each((_, hdrExt) => {
|
689
|
|
- media
|
690
|
|
- += `a=extmap:${hdrExt.getAttribute('id')} ${
|
691
|
|
- hdrExt.getAttribute('uri')}\r\n`;
|
692
|
|
- });
|
|
682
|
+ desc
|
|
683
|
+ .find('>rtp-hdrext[xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0"]')
|
|
684
|
+ .each((_, hdrExt) => {
|
|
685
|
+ sdp
|
|
686
|
+ += `a=extmap:${hdrExt.getAttribute('id')} ${
|
|
687
|
+ hdrExt.getAttribute('uri')}\r\n`;
|
|
688
|
+ });
|
693
|
689
|
|
694
|
690
|
// XEP-0339 handle ssrc-group attributes
|
695
|
691
|
desc
|
|
@@ -703,30 +699,30 @@ SDP.prototype.jingle2media = function(content) {
|
703
|
699
|
.get();
|
704
|
700
|
|
705
|
701
|
if (ssrcs.length) {
|
706
|
|
- media += `a=ssrc-group:${semantics} ${ssrcs.join(' ')}\r\n`;
|
|
702
|
+ sdp += `a=ssrc-group:${semantics} ${ssrcs.join(' ')}\r\n`;
|
707
|
703
|
}
|
708
|
704
|
});
|
709
|
705
|
|
710
|
|
- tmp
|
711
|
|
- = desc.find(
|
712
|
|
- '>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]');
|
713
|
|
- tmp.each((_, source) => {
|
714
|
|
- const ssrc = source.getAttribute('ssrc');
|
715
|
|
-
|
716
|
|
- $(source)
|
717
|
|
- .find('>parameter')
|
718
|
|
- .each((__, parameter) => {
|
719
|
|
- const name = parameter.getAttribute('name');
|
720
|
|
- let value = parameter.getAttribute('value');
|
721
|
|
-
|
722
|
|
- value = SDPUtil.filterSpecialChars(value);
|
723
|
|
- media += `a=ssrc:${ssrc} ${name}`;
|
724
|
|
- if (value && value.length) {
|
725
|
|
- media += `:${value}`;
|
726
|
|
- }
|
727
|
|
- media += '\r\n';
|
728
|
|
- });
|
729
|
|
- });
|
|
706
|
+ // XEP-0339 handle source attributes
|
|
707
|
+ desc
|
|
708
|
+ .find('>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]')
|
|
709
|
+ .each((_, source) => {
|
|
710
|
+ const ssrc = source.getAttribute('ssrc');
|
|
711
|
+
|
|
712
|
+ $(source)
|
|
713
|
+ .find('>parameter')
|
|
714
|
+ .each((__, parameter) => {
|
|
715
|
+ const name = parameter.getAttribute('name');
|
|
716
|
+ let value = parameter.getAttribute('value');
|
|
717
|
+
|
|
718
|
+ value = SDPUtil.filterSpecialChars(value);
|
|
719
|
+ sdp += `a=ssrc:${ssrc} ${name}`;
|
|
720
|
+ if (value && value.length) {
|
|
721
|
+ sdp += `:${value}`;
|
|
722
|
+ }
|
|
723
|
+ sdp += '\r\n';
|
|
724
|
+ });
|
|
725
|
+ });
|
730
|
726
|
|
731
|
|
- return media;
|
|
727
|
+ return sdp;
|
732
|
728
|
};
|