werift 0.15.3 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ice/src/ice.js +4 -7
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.js +1 -1
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +3 -1
- package/lib/webrtc/src/media/rtpTransceiver.js +7 -1
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +5 -2
- package/lib/webrtc/src/peerConnection.js +86 -30
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +0 -2
- package/lib/webrtc/src/sdp.js +0 -7
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +6 -0
- package/lib/webrtc/src/transport/ice.js +9 -0
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +2 -1
- package/lib/webrtc/src/transport/sctp.js +1 -1
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/package.json +1 -1
- package/src/media/rtpReceiver.ts +1 -1
- package/src/media/rtpTransceiver.ts +7 -1
- package/src/peerConnection.ts +102 -45
- package/src/sdp.ts +0 -8
- package/src/transport/ice.ts +10 -0
- package/src/transport/sctp.ts +2 -1
package/src/peerConnection.ts
CHANGED
|
@@ -230,11 +230,19 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
230
230
|
|
|
231
231
|
async createOffer() {
|
|
232
232
|
await this.ensureCerts();
|
|
233
|
+
const description = this.buildOfferSdp();
|
|
234
|
+
return description.toJSON();
|
|
235
|
+
}
|
|
233
236
|
|
|
237
|
+
buildOfferSdp() {
|
|
234
238
|
this.transceivers.forEach((transceiver) => {
|
|
235
|
-
transceiver.codecs
|
|
236
|
-
|
|
237
|
-
|
|
239
|
+
if (transceiver.codecs.length === 0) {
|
|
240
|
+
transceiver.codecs = this.configuration.codecs[transceiver.kind];
|
|
241
|
+
}
|
|
242
|
+
if (transceiver.headerExtensions.length === 0) {
|
|
243
|
+
transceiver.headerExtensions =
|
|
244
|
+
this.configuration.headerExtensions[transceiver.kind];
|
|
245
|
+
}
|
|
238
246
|
});
|
|
239
247
|
|
|
240
248
|
const description = new SessionDescription();
|
|
@@ -253,22 +261,24 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
253
261
|
return;
|
|
254
262
|
}
|
|
255
263
|
if (m.kind === "application") {
|
|
264
|
+
if (!this.sctpTransport) {
|
|
265
|
+
throw new Error("sctpTransport not found");
|
|
266
|
+
}
|
|
267
|
+
this.sctpTransport.mLineIndex = i;
|
|
256
268
|
description.media.push(
|
|
257
|
-
createMediaDescriptionForSctp(this.sctpTransport
|
|
269
|
+
createMediaDescriptionForSctp(this.sctpTransport)
|
|
258
270
|
);
|
|
259
271
|
} else {
|
|
260
272
|
const transceiver = this.getTransceiverByMid(mid);
|
|
261
273
|
if (!transceiver) {
|
|
262
|
-
|
|
263
|
-
return;
|
|
274
|
+
throw new Error("transceiver not found");
|
|
264
275
|
}
|
|
265
276
|
transceiver.mLineIndex = i;
|
|
266
277
|
description.media.push(
|
|
267
278
|
createMediaDescriptionForTransceiver(
|
|
268
279
|
transceiver,
|
|
269
280
|
this.cname,
|
|
270
|
-
transceiver.direction
|
|
271
|
-
mid
|
|
281
|
+
transceiver.direction
|
|
272
282
|
)
|
|
273
283
|
);
|
|
274
284
|
}
|
|
@@ -279,26 +289,27 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
279
289
|
.filter((t) => !description.media.find((m) => m.rtp.muxId === t.mid))
|
|
280
290
|
.forEach((transceiver) => {
|
|
281
291
|
transceiver.mLineIndex = description.media.length;
|
|
292
|
+
if (transceiver.mid == undefined) {
|
|
293
|
+
transceiver.mid = allocateMid(this.seenMid) + "_srtp";
|
|
294
|
+
}
|
|
282
295
|
description.media.push(
|
|
283
296
|
createMediaDescriptionForTransceiver(
|
|
284
297
|
transceiver,
|
|
285
298
|
this.cname,
|
|
286
|
-
transceiver.direction
|
|
287
|
-
allocateMid(this.seenMid)
|
|
299
|
+
transceiver.direction
|
|
288
300
|
)
|
|
289
301
|
);
|
|
290
302
|
});
|
|
291
303
|
|
|
292
304
|
if (
|
|
293
305
|
this.sctpTransport &&
|
|
294
|
-
!description.media.find((m) =>
|
|
306
|
+
!description.media.find((m) => m.kind === "application")
|
|
295
307
|
) {
|
|
296
|
-
description.media.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
);
|
|
308
|
+
this.sctpTransport.mLineIndex = description.media.length;
|
|
309
|
+
if (this.sctpTransport.mid == undefined) {
|
|
310
|
+
this.sctpTransport.mid = allocateMid(this.seenMid) + "_sctp";
|
|
311
|
+
}
|
|
312
|
+
description.media.push(createMediaDescriptionForSctp(this.sctpTransport));
|
|
302
313
|
}
|
|
303
314
|
|
|
304
315
|
if (this.configuration.bundlePolicy !== "disable") {
|
|
@@ -309,7 +320,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
309
320
|
description.group.push(bundle);
|
|
310
321
|
}
|
|
311
322
|
|
|
312
|
-
return description
|
|
323
|
+
return description;
|
|
313
324
|
}
|
|
314
325
|
|
|
315
326
|
createDataChannel(
|
|
@@ -423,14 +434,19 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
423
434
|
|
|
424
435
|
iceTransport.iceGather.onIceCandidate = (candidate) => {
|
|
425
436
|
if (!this.localDescription) return;
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
437
|
+
const transceiver = this.transceivers.find(
|
|
438
|
+
(t) => t.dtlsTransport.iceTransport.id === iceTransport.id
|
|
439
|
+
);
|
|
440
|
+
if (transceiver) {
|
|
441
|
+
candidate.sdpMLineIndex = transceiver.mLineIndex;
|
|
442
|
+
candidate.sdpMid = transceiver.mid;
|
|
443
|
+
}
|
|
444
|
+
if (
|
|
445
|
+
this.sctpTransport?.dtlsTransport.iceTransport.id === iceTransport.id
|
|
446
|
+
) {
|
|
447
|
+
candidate.sdpMLineIndex = this.sctpTransport.mLineIndex;
|
|
448
|
+
candidate.sdpMid = this.sctpTransport.mid;
|
|
431
449
|
}
|
|
432
|
-
candidate.sdpMLineIndex = 0;
|
|
433
|
-
candidate.sdpMid = media.rtp.muxId;
|
|
434
450
|
candidate.foundation = "candidate:" + candidate.foundation;
|
|
435
451
|
|
|
436
452
|
this.onIceCandidate.execute(candidate.toJSON());
|
|
@@ -541,9 +557,10 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
541
557
|
this.setLocal(description);
|
|
542
558
|
|
|
543
559
|
// # gather candidates
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
560
|
+
await Promise.all(
|
|
561
|
+
this.iceTransports.map((iceTransport) => iceTransport.iceGather.gather())
|
|
562
|
+
);
|
|
563
|
+
|
|
547
564
|
description.media
|
|
548
565
|
.filter((m) => ["audio", "video"].includes(m.kind))
|
|
549
566
|
.forEach((m, i) => {
|
|
@@ -581,10 +598,54 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
581
598
|
}
|
|
582
599
|
}
|
|
583
600
|
|
|
601
|
+
private getTransportByMid(mid: string) {
|
|
602
|
+
let iceTransport: RTCIceTransport | undefined;
|
|
603
|
+
|
|
604
|
+
const transceiver = this.transceivers.find((t) => t.mid === mid);
|
|
605
|
+
if (transceiver) {
|
|
606
|
+
iceTransport = transceiver.dtlsTransport.iceTransport;
|
|
607
|
+
} else if (!iceTransport && this.sctpTransport?.mid === mid) {
|
|
608
|
+
iceTransport = this.sctpTransport?.dtlsTransport.iceTransport;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
return iceTransport;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
private getTransportByMLineIndex(index: number) {
|
|
615
|
+
const sdp = this.buildOfferSdp();
|
|
616
|
+
const media = sdp.media[index];
|
|
617
|
+
if (!media) {
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
const transport = this.getTransportByMid(media.rtp.muxId!);
|
|
621
|
+
|
|
622
|
+
return transport;
|
|
623
|
+
}
|
|
624
|
+
|
|
584
625
|
async addIceCandidate(candidateMessage: RTCIceCandidate) {
|
|
585
626
|
const candidate = IceCandidate.fromJSON(candidateMessage);
|
|
586
|
-
|
|
627
|
+
if (!candidate) {
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
let iceTransport: RTCIceTransport | undefined;
|
|
632
|
+
|
|
633
|
+
if (typeof candidate.sdpMid === "number") {
|
|
634
|
+
iceTransport = this.getTransportByMid(candidate.sdpMid);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
if (!iceTransport && typeof candidate.sdpMLineIndex === "number") {
|
|
638
|
+
iceTransport = this.getTransportByMLineIndex(candidate.sdpMLineIndex);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
if (!iceTransport) {
|
|
642
|
+
iceTransport = this.iceTransports[0];
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (iceTransport) {
|
|
587
646
|
await iceTransport.addRemoteCandidate(candidate);
|
|
647
|
+
} else {
|
|
648
|
+
log("iceTransport not found", candidate);
|
|
588
649
|
}
|
|
589
650
|
}
|
|
590
651
|
|
|
@@ -704,6 +765,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
704
765
|
transceiver = this.addTransceiver(remoteMedia.kind, {
|
|
705
766
|
direction: "recvonly",
|
|
706
767
|
});
|
|
768
|
+
transceiver.mid = remoteMedia.rtp.muxId;
|
|
707
769
|
this.onRemoteTransceiverAdded.execute(transceiver);
|
|
708
770
|
}
|
|
709
771
|
|
|
@@ -721,6 +783,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
721
783
|
} else if (remoteMedia.kind === "application") {
|
|
722
784
|
if (!this.sctpTransport) {
|
|
723
785
|
this.sctpTransport = this.createSctpTransport();
|
|
786
|
+
this.sctpTransport.mid = remoteMedia.rtp.muxId;
|
|
724
787
|
}
|
|
725
788
|
|
|
726
789
|
if (bundle) {
|
|
@@ -733,7 +796,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
733
796
|
|
|
734
797
|
dtlsTransport = this.sctpTransport.dtlsTransport;
|
|
735
798
|
|
|
736
|
-
this.setRemoteSCTP(remoteMedia, this.sctpTransport);
|
|
799
|
+
this.setRemoteSCTP(remoteMedia, this.sctpTransport, i);
|
|
737
800
|
} else {
|
|
738
801
|
throw new Error("invalid media kind");
|
|
739
802
|
}
|
|
@@ -878,7 +941,8 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
878
941
|
|
|
879
942
|
private setRemoteSCTP(
|
|
880
943
|
remoteMedia: MediaDescription,
|
|
881
|
-
sctpTransport: RTCSctpTransport
|
|
944
|
+
sctpTransport: RTCSctpTransport,
|
|
945
|
+
mLineIndex: number
|
|
882
946
|
) {
|
|
883
947
|
// # configure sctp
|
|
884
948
|
this.sctpRemotePort = remoteMedia.sctpPort;
|
|
@@ -887,6 +951,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
887
951
|
}
|
|
888
952
|
|
|
889
953
|
sctpTransport.setRemotePort(this.sctpRemotePort);
|
|
954
|
+
sctpTransport.mLineIndex = mLineIndex;
|
|
890
955
|
if (!sctpTransport.mid) {
|
|
891
956
|
sctpTransport.mid = remoteMedia.rtp.muxId;
|
|
892
957
|
}
|
|
@@ -1101,18 +1166,14 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
1101
1166
|
media = createMediaDescriptionForTransceiver(
|
|
1102
1167
|
transceiver,
|
|
1103
1168
|
this.cname,
|
|
1104
|
-
andDirection(transceiver.direction, transceiver.offerDirection)
|
|
1105
|
-
transceiver.mid!
|
|
1169
|
+
andDirection(transceiver.direction, transceiver.offerDirection)
|
|
1106
1170
|
);
|
|
1107
1171
|
dtlsTransport = transceiver.dtlsTransport;
|
|
1108
1172
|
} else if (remoteMedia.kind === "application") {
|
|
1109
1173
|
if (!this.sctpTransport || !this.sctpTransport.mid) {
|
|
1110
1174
|
throw new Error("sctpTransport not found");
|
|
1111
1175
|
}
|
|
1112
|
-
media = createMediaDescriptionForSctp(
|
|
1113
|
-
this.sctpTransport,
|
|
1114
|
-
this.sctpTransport.mid
|
|
1115
|
-
);
|
|
1176
|
+
media = createMediaDescriptionForSctp(this.sctpTransport);
|
|
1116
1177
|
|
|
1117
1178
|
dtlsTransport = this.sctpTransport.dtlsTransport;
|
|
1118
1179
|
} else {
|
|
@@ -1282,8 +1343,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
1282
1343
|
export function createMediaDescriptionForTransceiver(
|
|
1283
1344
|
transceiver: RTCRtpTransceiver,
|
|
1284
1345
|
cname: string,
|
|
1285
|
-
direction: Direction
|
|
1286
|
-
mid: string
|
|
1346
|
+
direction: Direction
|
|
1287
1347
|
) {
|
|
1288
1348
|
const media = new MediaDescription(
|
|
1289
1349
|
transceiver.kind,
|
|
@@ -1296,7 +1356,7 @@ export function createMediaDescriptionForTransceiver(
|
|
|
1296
1356
|
media.rtp = {
|
|
1297
1357
|
codecs: transceiver.codecs,
|
|
1298
1358
|
headerExtensions: transceiver.headerExtensions,
|
|
1299
|
-
muxId: mid,
|
|
1359
|
+
muxId: transceiver.mid,
|
|
1300
1360
|
};
|
|
1301
1361
|
media.rtcpHost = "0.0.0.0";
|
|
1302
1362
|
media.rtcpPort = 9;
|
|
@@ -1325,10 +1385,7 @@ export function createMediaDescriptionForTransceiver(
|
|
|
1325
1385
|
return media;
|
|
1326
1386
|
}
|
|
1327
1387
|
|
|
1328
|
-
export function createMediaDescriptionForSctp(
|
|
1329
|
-
sctp: RTCSctpTransport,
|
|
1330
|
-
mid: string
|
|
1331
|
-
) {
|
|
1388
|
+
export function createMediaDescriptionForSctp(sctp: RTCSctpTransport) {
|
|
1332
1389
|
const media = new MediaDescription(
|
|
1333
1390
|
"application",
|
|
1334
1391
|
DISCARD_PORT,
|
|
@@ -1336,7 +1393,7 @@ export function createMediaDescriptionForSctp(
|
|
|
1336
1393
|
["webrtc-datachannel"]
|
|
1337
1394
|
);
|
|
1338
1395
|
media.sctpPort = sctp.port;
|
|
1339
|
-
media.rtp.muxId = mid;
|
|
1396
|
+
media.rtp.muxId = sctp.mid;
|
|
1340
1397
|
media.sctpCapabilities = RTCSctpTransport.getCapabilities();
|
|
1341
1398
|
|
|
1342
1399
|
addTransportDescription(media, sctp.dtlsTransport);
|
package/src/sdp.ts
CHANGED
|
@@ -611,14 +611,6 @@ export function candidateFromSdp(sdp: string) {
|
|
|
611
611
|
|
|
612
612
|
export class RTCSessionDescription {
|
|
613
613
|
constructor(public sdp: string, public type: "offer" | "answer") {}
|
|
614
|
-
|
|
615
|
-
get object() {
|
|
616
|
-
return SessionDescription.parse(this.sdp);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
static isThis(o: any) {
|
|
620
|
-
if (typeof o?.sdp === "string") return true;
|
|
621
|
-
}
|
|
622
614
|
}
|
|
623
615
|
|
|
624
616
|
export function addSDPHeader(
|
package/src/transport/ice.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import Event from "rx.mini";
|
|
2
|
+
import { v4 } from "uuid";
|
|
2
3
|
|
|
3
4
|
import { Candidate, Connection, IceOptions } from "../../../ice/src";
|
|
4
5
|
import { candidateFromSdp, candidateToSdp } from "../sdp";
|
|
5
6
|
|
|
6
7
|
export class RTCIceTransport {
|
|
8
|
+
readonly id = v4();
|
|
7
9
|
connection = this.gather.connection;
|
|
8
10
|
state: RTCIceConnectionState = "new";
|
|
9
11
|
|
|
@@ -182,6 +184,14 @@ export class RTCIceCandidate {
|
|
|
182
184
|
static isThis(o: any) {
|
|
183
185
|
if (typeof o?.candidate === "string") return true;
|
|
184
186
|
}
|
|
187
|
+
|
|
188
|
+
toJSON() {
|
|
189
|
+
return {
|
|
190
|
+
candidate: this.candidate,
|
|
191
|
+
sdpMid: this.sdpMid,
|
|
192
|
+
sdpMLineIndex: this.sdpMLineIndex,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
185
195
|
}
|
|
186
196
|
|
|
187
197
|
export class IceCandidate {
|
package/src/transport/sctp.ts
CHANGED
|
@@ -28,9 +28,10 @@ export class RTCSctpTransport {
|
|
|
28
28
|
sctp!: SCTP;
|
|
29
29
|
|
|
30
30
|
readonly onDataChannel = new Event<[RTCDataChannel]>();
|
|
31
|
-
readonly
|
|
31
|
+
readonly id = uuid.v4();
|
|
32
32
|
|
|
33
33
|
mid?: string;
|
|
34
|
+
mLineIndex?: number;
|
|
34
35
|
bundled = false;
|
|
35
36
|
dataChannels: { [key: number]: RTCDataChannel } = {};
|
|
36
37
|
|