werift 0.15.3 → 0.15.6

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.
Files changed (38) hide show
  1. package/lib/common/src/promise.d.ts +4 -3
  2. package/lib/common/src/promise.js +11 -5
  3. package/lib/common/src/promise.js.map +1 -1
  4. package/lib/ice/src/dns/lookup.d.ts +9 -0
  5. package/lib/ice/src/dns/lookup.js +66 -0
  6. package/lib/ice/src/dns/lookup.js.map +1 -0
  7. package/lib/ice/src/ice.d.ts +2 -0
  8. package/lib/ice/src/ice.js +24 -24
  9. package/lib/ice/src/ice.js.map +1 -1
  10. package/lib/ice/src/transport.js +2 -1
  11. package/lib/ice/src/transport.js.map +1 -1
  12. package/lib/ice/src/utils.d.ts +1 -0
  13. package/lib/ice/src/utils.js +9 -1
  14. package/lib/ice/src/utils.js.map +1 -1
  15. package/lib/webrtc/src/media/rtpReceiver.js +1 -1
  16. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  17. package/lib/webrtc/src/media/rtpTransceiver.d.ts +3 -1
  18. package/lib/webrtc/src/media/rtpTransceiver.js +7 -1
  19. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  20. package/lib/webrtc/src/peerConnection.d.ts +8 -3
  21. package/lib/webrtc/src/peerConnection.js +134 -54
  22. package/lib/webrtc/src/peerConnection.js.map +1 -1
  23. package/lib/webrtc/src/sdp.d.ts +0 -2
  24. package/lib/webrtc/src/sdp.js +0 -7
  25. package/lib/webrtc/src/sdp.js.map +1 -1
  26. package/lib/webrtc/src/transport/ice.d.ts +7 -1
  27. package/lib/webrtc/src/transport/ice.js +12 -3
  28. package/lib/webrtc/src/transport/ice.js.map +1 -1
  29. package/lib/webrtc/src/transport/sctp.d.ts +2 -1
  30. package/lib/webrtc/src/transport/sctp.js +1 -1
  31. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/media/rtpReceiver.ts +1 -1
  34. package/src/media/rtpTransceiver.ts +7 -1
  35. package/src/peerConnection.ts +213 -128
  36. package/src/sdp.ts +0 -8
  37. package/src/transport/ice.ts +13 -3
  38. package/src/transport/sctp.ts +2 -1
@@ -194,10 +194,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
194
194
  }
195
195
  async createOffer() {
196
196
  await this.ensureCerts();
197
+ const description = this.buildOfferSdp();
198
+ return description.toJSON();
199
+ }
200
+ buildOfferSdp() {
197
201
  this.transceivers.forEach((transceiver) => {
198
- transceiver.codecs = this.configuration.codecs[transceiver.kind];
199
- transceiver.headerExtensions =
200
- this.configuration.headerExtensions[transceiver.kind];
202
+ if (transceiver.codecs.length === 0) {
203
+ transceiver.codecs = this.configuration.codecs[transceiver.kind];
204
+ }
205
+ if (transceiver.headerExtensions.length === 0) {
206
+ transceiver.headerExtensions =
207
+ this.configuration.headerExtensions[transceiver.kind];
208
+ }
201
209
  });
202
210
  const description = new sdp_1.SessionDescription();
203
211
  (0, sdp_1.addSDPHeader)("offer", description);
@@ -212,16 +220,19 @@ class RTCPeerConnection extends helper_1.EventTarget {
212
220
  return;
213
221
  }
214
222
  if (m.kind === "application") {
215
- description.media.push(createMediaDescriptionForSctp(this.sctpTransport, mid));
223
+ if (!this.sctpTransport) {
224
+ throw new Error("sctpTransport not found");
225
+ }
226
+ this.sctpTransport.mLineIndex = i;
227
+ description.media.push(createMediaDescriptionForSctp(this.sctpTransport));
216
228
  }
217
229
  else {
218
230
  const transceiver = this.getTransceiverByMid(mid);
219
231
  if (!transceiver) {
220
- log("transceiver by mid not found", mid);
221
- return;
232
+ throw new Error("transceiver not found");
222
233
  }
223
234
  transceiver.mLineIndex = i;
224
- description.media.push(createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction, mid));
235
+ description.media.push(createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction));
225
236
  }
226
237
  });
227
238
  // # handle new transceivers / sctp
@@ -229,11 +240,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
229
240
  .filter((t) => !description.media.find((m) => m.rtp.muxId === t.mid))
230
241
  .forEach((transceiver) => {
231
242
  transceiver.mLineIndex = description.media.length;
232
- description.media.push(createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction, allocateMid(this.seenMid)));
243
+ if (transceiver.mid == undefined) {
244
+ transceiver.mid = allocateMid(this.seenMid) + "_srtp";
245
+ }
246
+ description.media.push(createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction));
233
247
  });
234
248
  if (this.sctpTransport &&
235
- !description.media.find((m) => this.sctpTransport.mid === m.rtp.muxId)) {
236
- description.media.push(createMediaDescriptionForSctp(this.sctpTransport, allocateMid(this.seenMid)));
249
+ !description.media.find((m) => m.kind === "application")) {
250
+ this.sctpTransport.mLineIndex = description.media.length;
251
+ if (this.sctpTransport.mid == undefined) {
252
+ this.sctpTransport.mid = allocateMid(this.seenMid) + "_sctp";
253
+ }
254
+ description.media.push(createMediaDescriptionForSctp(this.sctpTransport));
237
255
  }
238
256
  if (this.configuration.bundlePolicy !== "disable") {
239
257
  const mids = description.media
@@ -242,7 +260,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
242
260
  const bundle = new sdp_1.GroupDescription("BUNDLE", mids);
243
261
  description.group.push(bundle);
244
262
  }
245
- return description.toJSON();
263
+ return description;
246
264
  }
247
265
  createDataChannel(label, options = {}) {
248
266
  const base = {
@@ -321,18 +339,30 @@ class RTCPeerConnection extends helper_1.EventTarget {
321
339
  iceTransport.iceGather.onIceCandidate = (candidate) => {
322
340
  if (!this.localDescription)
323
341
  return;
324
- const sdp = sdp_1.SessionDescription.parse(this.localDescription.sdp);
325
- const media = sdp.media[0];
326
- if (!media) {
327
- log("media not exist");
328
- return;
342
+ if (this.configuration.bundlePolicy === "max-bundle" ||
343
+ this.remoteIsBundled) {
344
+ candidate.sdpMLineIndex = 0;
345
+ const media = this._localDescription?.media[0];
346
+ if (media) {
347
+ candidate.sdpMid = media.rtp.muxId;
348
+ }
349
+ }
350
+ else {
351
+ const transceiver = this.transceivers.find((t) => t.dtlsTransport.iceTransport.id === iceTransport.id);
352
+ if (transceiver) {
353
+ candidate.sdpMLineIndex = transceiver.mLineIndex;
354
+ candidate.sdpMid = transceiver.mid;
355
+ }
356
+ if (this.sctpTransport?.dtlsTransport.iceTransport.id === iceTransport.id) {
357
+ candidate.sdpMLineIndex = this.sctpTransport.mLineIndex;
358
+ candidate.sdpMid = this.sctpTransport.mid;
359
+ }
329
360
  }
330
- candidate.sdpMLineIndex = 0;
331
- candidate.sdpMid = media.rtp.muxId;
332
361
  candidate.foundation = "candidate:" + candidate.foundation;
333
362
  this.onIceCandidate.execute(candidate.toJSON());
334
- if (this.onicecandidate)
363
+ if (this.onicecandidate) {
335
364
  this.onicecandidate({ candidate: candidate.toJSON() });
365
+ }
336
366
  this.emit("icecandidate", { candidate });
337
367
  };
338
368
  const dtlsTransport = new dtls_1.RTCDtlsTransport(iceTransport, this.router, this.certificates, srtpProfiles);
@@ -416,10 +446,16 @@ class RTCPeerConnection extends helper_1.EventTarget {
416
446
  });
417
447
  // for trickle ice
418
448
  this.setLocal(description);
419
- // # gather candidates
420
- for (const iceTransport of this.iceTransports) {
421
- await iceTransport.iceGather.gather();
449
+ // connect transports
450
+ if (description.type === "answer") {
451
+ log("callee start connect");
452
+ this.connect().catch((err) => {
453
+ log("connect failed", err);
454
+ this.setConnectionState("failed");
455
+ });
422
456
  }
457
+ // # gather candidates
458
+ await Promise.all(this.iceTransports.map((iceTransport) => iceTransport.iceGather.gather()));
423
459
  description.media
424
460
  .filter((m) => ["audio", "video"].includes(m.kind))
425
461
  .forEach((m, i) => {
@@ -430,14 +466,6 @@ class RTCPeerConnection extends helper_1.EventTarget {
430
466
  addTransportDescription(sctpMedia, this.sctpTransport.dtlsTransport);
431
467
  }
432
468
  this.setLocal(description);
433
- // connect transports
434
- if (description.type === "answer") {
435
- log("callee start connect");
436
- this.connect().catch((err) => {
437
- log("connect failed", err);
438
- this.setConnectionState("failed");
439
- });
440
- }
441
469
  if (this.shouldNegotiationneeded) {
442
470
  this.needNegotiation();
443
471
  }
@@ -452,11 +480,47 @@ class RTCPeerConnection extends helper_1.EventTarget {
452
480
  this.pendingLocalDescription = description;
453
481
  }
454
482
  }
483
+ getTransportByMid(mid) {
484
+ let iceTransport;
485
+ const transceiver = this.transceivers.find((t) => t.mid === mid);
486
+ if (transceiver) {
487
+ iceTransport = transceiver.dtlsTransport.iceTransport;
488
+ }
489
+ else if (!iceTransport && this.sctpTransport?.mid === mid) {
490
+ iceTransport = this.sctpTransport?.dtlsTransport.iceTransport;
491
+ }
492
+ return iceTransport;
493
+ }
494
+ getTransportByMLineIndex(index) {
495
+ const sdp = this.buildOfferSdp();
496
+ const media = sdp.media[index];
497
+ if (!media) {
498
+ return;
499
+ }
500
+ const transport = this.getTransportByMid(media.rtp.muxId);
501
+ return transport;
502
+ }
455
503
  async addIceCandidate(candidateMessage) {
456
504
  const candidate = ice_1.IceCandidate.fromJSON(candidateMessage);
457
- for (const iceTransport of this.iceTransports) {
505
+ if (!candidate) {
506
+ return;
507
+ }
508
+ let iceTransport;
509
+ if (typeof candidate.sdpMid === "number") {
510
+ iceTransport = this.getTransportByMid(candidate.sdpMid);
511
+ }
512
+ if (!iceTransport && typeof candidate.sdpMLineIndex === "number") {
513
+ iceTransport = this.getTransportByMLineIndex(candidate.sdpMLineIndex);
514
+ }
515
+ if (!iceTransport) {
516
+ iceTransport = this.iceTransports[0];
517
+ }
518
+ if (iceTransport) {
458
519
  await iceTransport.addRemoteCandidate(candidate);
459
520
  }
521
+ else {
522
+ log("iceTransport not found", candidate);
523
+ }
460
524
  }
461
525
  async connect() {
462
526
  if (this.masterTransportEstablished)
@@ -518,6 +582,13 @@ class RTCPeerConnection extends helper_1.EventTarget {
518
582
  };
519
583
  return receiveParameters;
520
584
  }
585
+ get remoteIsBundled() {
586
+ const remoteSdp = this._remoteDescription;
587
+ if (!remoteSdp)
588
+ return;
589
+ const bundle = remoteSdp.group.find((g) => g.semantic === "BUNDLE" && this.configuration.bundlePolicy !== "disable");
590
+ return bundle;
591
+ }
521
592
  async setRemoteDescription(sessionDescription) {
522
593
  // # parse and validate description
523
594
  const remoteSdp = sdp_1.SessionDescription.parse(sessionDescription.sdp);
@@ -530,10 +601,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
530
601
  else {
531
602
  this.pendingRemoteDescription = remoteSdp;
532
603
  }
533
- const bundle = remoteSdp.group.find((g) => g.semantic === "BUNDLE" && this.configuration.bundlePolicy !== "disable");
534
604
  let bundleTransport;
535
605
  // # apply description
536
- await Promise.all((0, helper_1.enumerate)(remoteSdp.media).map(async ([i, remoteMedia]) => {
606
+ const transports = (0, helper_1.enumerate)(remoteSdp.media).map(([i, remoteMedia]) => {
537
607
  let dtlsTransport;
538
608
  if (["audio", "video"].includes(remoteMedia.kind)) {
539
609
  let transceiver = this.transceivers.find((t) => t.kind === remoteMedia.kind &&
@@ -543,9 +613,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
543
613
  transceiver = this.addTransceiver(remoteMedia.kind, {
544
614
  direction: "recvonly",
545
615
  });
616
+ transceiver.mid = remoteMedia.rtp.muxId;
546
617
  this.onRemoteTransceiverAdded.execute(transceiver);
547
618
  }
548
- if (bundle) {
619
+ if (this.remoteIsBundled) {
549
620
  if (!bundleTransport) {
550
621
  bundleTransport = transceiver.dtlsTransport;
551
622
  }
@@ -559,8 +630,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
559
630
  else if (remoteMedia.kind === "application") {
560
631
  if (!this.sctpTransport) {
561
632
  this.sctpTransport = this.createSctpTransport();
633
+ this.sctpTransport.mid = remoteMedia.rtp.muxId;
562
634
  }
563
- if (bundle) {
635
+ if (this.remoteIsBundled) {
564
636
  if (!bundleTransport) {
565
637
  bundleTransport = this.sctpTransport.dtlsTransport;
566
638
  }
@@ -569,7 +641,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
569
641
  }
570
642
  }
571
643
  dtlsTransport = this.sctpTransport.dtlsTransport;
572
- this.setRemoteSCTP(remoteMedia, this.sctpTransport);
644
+ this.setRemoteSCTP(remoteMedia, this.sctpTransport, i);
573
645
  }
574
646
  else {
575
647
  throw new Error("invalid media kind");
@@ -586,16 +658,22 @@ class RTCPeerConnection extends helper_1.EventTarget {
586
658
  }
587
659
  // # add ICE candidates
588
660
  remoteMedia.iceCandidates.forEach(iceTransport.addRemoteCandidate);
589
- await iceTransport.iceGather.gather();
590
661
  if (remoteMedia.iceCandidatesComplete) {
591
- await iceTransport.addRemoteCandidate(undefined);
662
+ iceTransport.addRemoteCandidate(undefined);
592
663
  }
593
664
  // # set DTLS role
594
665
  if (remoteSdp.type === "answer" && remoteMedia.dtlsParams?.role) {
595
666
  dtlsTransport.role =
596
667
  remoteMedia.dtlsParams.role === "client" ? "server" : "client";
597
668
  }
598
- }));
669
+ return iceTransport;
670
+ });
671
+ if (remoteSdp.type === "offer") {
672
+ this.setSignalingState("have-remote-offer");
673
+ }
674
+ else if (remoteSdp.type === "answer") {
675
+ this.setSignalingState("stable");
676
+ }
599
677
  // connect transports
600
678
  if (remoteSdp.type === "answer") {
601
679
  log("caller start connect");
@@ -604,12 +682,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
604
682
  this.setConnectionState("failed");
605
683
  });
606
684
  }
607
- if (remoteSdp.type === "offer") {
608
- this.setSignalingState("have-remote-offer");
609
- }
610
- else if (remoteSdp.type === "answer") {
611
- this.setSignalingState("stable");
612
- }
685
+ await Promise.all(transports.map(async (iceTransport) => {
686
+ await iceTransport.iceGather.gather();
687
+ }));
613
688
  this.negotiationneeded = false;
614
689
  if (this.shouldNegotiationneeded) {
615
690
  this.needNegotiation();
@@ -676,13 +751,14 @@ class RTCPeerConnection extends helper_1.EventTarget {
676
751
  }
677
752
  transceiver.receiver.setupTWCC(remoteMedia.ssrc[0]?.ssrc);
678
753
  }
679
- setRemoteSCTP(remoteMedia, sctpTransport) {
754
+ setRemoteSCTP(remoteMedia, sctpTransport, mLineIndex) {
680
755
  // # configure sctp
681
756
  this.sctpRemotePort = remoteMedia.sctpPort;
682
757
  if (!this.sctpRemotePort) {
683
758
  throw new Error("sctpRemotePort not exist");
684
759
  }
685
760
  sctpTransport.setRemotePort(this.sctpRemotePort);
761
+ sctpTransport.mLineIndex = mLineIndex;
686
762
  if (!sctpTransport.mid) {
687
763
  sctpTransport.mid = remoteMedia.rtp.muxId;
688
764
  }
@@ -824,6 +900,11 @@ class RTCPeerConnection extends helper_1.EventTarget {
824
900
  }
825
901
  }
826
902
  async createAnswer() {
903
+ await this.ensureCerts();
904
+ const description = this.buildAnswer();
905
+ return description.toJSON();
906
+ }
907
+ buildAnswer() {
827
908
  this.assertNotClosed();
828
909
  if (!["have-remote-offer", "have-local-pranswer"].includes(this.signalingState)) {
829
910
  throw new Error("createAnswer failed");
@@ -831,7 +912,6 @@ class RTCPeerConnection extends helper_1.EventTarget {
831
912
  if (!this._remoteDescription) {
832
913
  throw new Error("wrong state");
833
914
  }
834
- await this.ensureCerts();
835
915
  const description = new sdp_1.SessionDescription();
836
916
  (0, sdp_1.addSDPHeader)("answer", description);
837
917
  this._remoteDescription.media.forEach((remoteMedia) => {
@@ -839,14 +919,14 @@ class RTCPeerConnection extends helper_1.EventTarget {
839
919
  let media;
840
920
  if (["audio", "video"].includes(remoteMedia.kind)) {
841
921
  const transceiver = this.getTransceiverByMid(remoteMedia.rtp.muxId);
842
- media = createMediaDescriptionForTransceiver(transceiver, this.cname, (0, utils_1.andDirection)(transceiver.direction, transceiver.offerDirection), transceiver.mid);
922
+ media = createMediaDescriptionForTransceiver(transceiver, this.cname, (0, utils_1.andDirection)(transceiver.direction, transceiver.offerDirection));
843
923
  dtlsTransport = transceiver.dtlsTransport;
844
924
  }
845
925
  else if (remoteMedia.kind === "application") {
846
926
  if (!this.sctpTransport || !this.sctpTransport.mid) {
847
927
  throw new Error("sctpTransport not found");
848
928
  }
849
- media = createMediaDescriptionForSctp(this.sctpTransport, this.sctpTransport.mid);
929
+ media = createMediaDescriptionForSctp(this.sctpTransport);
850
930
  dtlsTransport = this.sctpTransport.dtlsTransport;
851
931
  }
852
932
  else {
@@ -875,7 +955,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
875
955
  });
876
956
  description.group.push(bundle);
877
957
  }
878
- return description.toJSON();
958
+ return description;
879
959
  }
880
960
  async close() {
881
961
  if (this.isClosed)
@@ -996,14 +1076,14 @@ class RTCPeerConnection extends helper_1.EventTarget {
996
1076
  }
997
1077
  }
998
1078
  exports.RTCPeerConnection = RTCPeerConnection;
999
- function createMediaDescriptionForTransceiver(transceiver, cname, direction, mid) {
1079
+ function createMediaDescriptionForTransceiver(transceiver, cname, direction) {
1000
1080
  const media = new sdp_1.MediaDescription(transceiver.kind, 9, "UDP/TLS/RTP/SAVPF", transceiver.codecs.map((c) => c.payloadType));
1001
1081
  media.direction = direction;
1002
1082
  media.msid = transceiver.msid;
1003
1083
  media.rtp = {
1004
1084
  codecs: transceiver.codecs,
1005
1085
  headerExtensions: transceiver.headerExtensions,
1006
- muxId: mid,
1086
+ muxId: transceiver.mid,
1007
1087
  };
1008
1088
  media.rtcpHost = "0.0.0.0";
1009
1089
  media.rtcpPort = 9;
@@ -1025,10 +1105,10 @@ function createMediaDescriptionForTransceiver(transceiver, cname, direction, mid
1025
1105
  return media;
1026
1106
  }
1027
1107
  exports.createMediaDescriptionForTransceiver = createMediaDescriptionForTransceiver;
1028
- function createMediaDescriptionForSctp(sctp, mid) {
1108
+ function createMediaDescriptionForSctp(sctp) {
1029
1109
  const media = new sdp_1.MediaDescription("application", const_1.DISCARD_PORT, "UDP/DTLS/SCTP", ["webrtc-datachannel"]);
1030
1110
  media.sctpPort = sctp.port;
1031
- media.rtp.muxId = mid;
1111
+ media.rtp.muxId = sctp.mid;
1032
1112
  media.sctpCapabilities = sctp_1.RTCSctpTransport.getCapabilities();
1033
1113
  addTransportDescription(media, sctp.dtlsTransport);
1034
1114
  return media;