werift 0.15.4 → 0.15.7

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.
@@ -434,24 +434,38 @@ export class RTCPeerConnection extends EventTarget {
434
434
 
435
435
  iceTransport.iceGather.onIceCandidate = (candidate) => {
436
436
  if (!this.localDescription) return;
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
- }
437
+
444
438
  if (
445
- this.sctpTransport?.dtlsTransport.iceTransport.id === iceTransport.id
439
+ this.configuration.bundlePolicy === "max-bundle" ||
440
+ this.remoteIsBundled
446
441
  ) {
447
- candidate.sdpMLineIndex = this.sctpTransport.mLineIndex;
448
- candidate.sdpMid = this.sctpTransport.mid;
442
+ candidate.sdpMLineIndex = 0;
443
+ const media = this._localDescription?.media[0];
444
+ if (media) {
445
+ candidate.sdpMid = media.rtp.muxId;
446
+ }
447
+ } else {
448
+ const transceiver = this.transceivers.find(
449
+ (t) => t.dtlsTransport.iceTransport.id === iceTransport.id
450
+ );
451
+ if (transceiver) {
452
+ candidate.sdpMLineIndex = transceiver.mLineIndex;
453
+ candidate.sdpMid = transceiver.mid;
454
+ }
455
+ if (
456
+ this.sctpTransport?.dtlsTransport.iceTransport.id === iceTransport.id
457
+ ) {
458
+ candidate.sdpMLineIndex = this.sctpTransport.mLineIndex;
459
+ candidate.sdpMid = this.sctpTransport.mid;
460
+ }
449
461
  }
462
+
450
463
  candidate.foundation = "candidate:" + candidate.foundation;
451
464
 
452
465
  this.onIceCandidate.execute(candidate.toJSON());
453
- if (this.onicecandidate)
466
+ if (this.onicecandidate) {
454
467
  this.onicecandidate({ candidate: candidate.toJSON() });
468
+ }
455
469
  this.emit("icecandidate", { candidate });
456
470
  };
457
471
 
@@ -556,6 +570,15 @@ export class RTCPeerConnection extends EventTarget {
556
570
  // for trickle ice
557
571
  this.setLocal(description);
558
572
 
573
+ // connect transports
574
+ if (description.type === "answer") {
575
+ log("callee start connect");
576
+ this.connect().catch((err) => {
577
+ log("connect failed", err);
578
+ this.setConnectionState("failed");
579
+ });
580
+ }
581
+
559
582
  // # gather candidates
560
583
  await Promise.all(
561
584
  this.iceTransports.map((iceTransport) => iceTransport.iceGather.gather())
@@ -573,15 +596,6 @@ export class RTCPeerConnection extends EventTarget {
573
596
 
574
597
  this.setLocal(description);
575
598
 
576
- // connect transports
577
- if (description.type === "answer") {
578
- log("callee start connect");
579
- this.connect().catch((err) => {
580
- log("connect failed", err);
581
- this.setConnectionState("failed");
582
- });
583
- }
584
-
585
599
  if (this.shouldNegotiationneeded) {
586
600
  this.needNegotiation();
587
601
  }
@@ -727,6 +741,16 @@ export class RTCPeerConnection extends EventTarget {
727
741
  return receiveParameters;
728
742
  }
729
743
 
744
+ get remoteIsBundled() {
745
+ const remoteSdp = this._remoteDescription;
746
+ if (!remoteSdp) return;
747
+ const bundle = remoteSdp.group.find(
748
+ (g) =>
749
+ g.semantic === "BUNDLE" && this.configuration.bundlePolicy !== "disable"
750
+ );
751
+ return bundle;
752
+ }
753
+
730
754
  async setRemoteDescription(sessionDescription: {
731
755
  type: "offer" | "answer";
732
756
  sdp: string;
@@ -743,93 +767,93 @@ export class RTCPeerConnection extends EventTarget {
743
767
  this.pendingRemoteDescription = remoteSdp;
744
768
  }
745
769
 
746
- const bundle = remoteSdp.group.find(
747
- (g) =>
748
- g.semantic === "BUNDLE" && this.configuration.bundlePolicy !== "disable"
749
- );
750
770
  let bundleTransport: RTCDtlsTransport | undefined;
751
771
 
752
772
  // # apply description
753
- await Promise.all(
754
- enumerate(remoteSdp.media).map(async ([i, remoteMedia]) => {
755
- let dtlsTransport: RTCDtlsTransport | undefined;
756
-
757
- if (["audio", "video"].includes(remoteMedia.kind)) {
758
- let transceiver = this.transceivers.find(
759
- (t) =>
760
- t.kind === remoteMedia.kind &&
761
- [undefined, remoteMedia.rtp.muxId].includes(t.mid)
762
- );
763
- if (!transceiver) {
764
- // create remote transceiver
765
- transceiver = this.addTransceiver(remoteMedia.kind, {
766
- direction: "recvonly",
767
- });
768
- transceiver.mid = remoteMedia.rtp.muxId;
769
- this.onRemoteTransceiverAdded.execute(transceiver);
770
- }
771
773
 
772
- if (bundle) {
773
- if (!bundleTransport) {
774
- bundleTransport = transceiver.dtlsTransport;
775
- } else {
776
- transceiver.setDtlsTransport(bundleTransport);
777
- }
778
- }
774
+ const transports = enumerate(remoteSdp.media).map(([i, remoteMedia]) => {
775
+ let dtlsTransport: RTCDtlsTransport | undefined;
779
776
 
780
- dtlsTransport = transceiver.dtlsTransport;
777
+ if (["audio", "video"].includes(remoteMedia.kind)) {
778
+ let transceiver = this.transceivers.find(
779
+ (t) =>
780
+ t.kind === remoteMedia.kind &&
781
+ [undefined, remoteMedia.rtp.muxId].includes(t.mid)
782
+ );
783
+ if (!transceiver) {
784
+ // create remote transceiver
785
+ transceiver = this.addTransceiver(remoteMedia.kind, {
786
+ direction: "recvonly",
787
+ });
788
+ transceiver.mid = remoteMedia.rtp.muxId;
789
+ this.onRemoteTransceiverAdded.execute(transceiver);
790
+ }
781
791
 
782
- this.setRemoteRTP(transceiver, remoteMedia, remoteSdp.type, i);
783
- } else if (remoteMedia.kind === "application") {
784
- if (!this.sctpTransport) {
785
- this.sctpTransport = this.createSctpTransport();
786
- this.sctpTransport.mid = remoteMedia.rtp.muxId;
792
+ if (this.remoteIsBundled) {
793
+ if (!bundleTransport) {
794
+ bundleTransport = transceiver.dtlsTransport;
795
+ } else {
796
+ transceiver.setDtlsTransport(bundleTransport);
787
797
  }
798
+ }
788
799
 
789
- if (bundle) {
790
- if (!bundleTransport) {
791
- bundleTransport = this.sctpTransport.dtlsTransport;
792
- } else {
793
- this.sctpTransport.setDtlsTransport(bundleTransport);
794
- }
795
- }
800
+ dtlsTransport = transceiver.dtlsTransport;
796
801
 
797
- dtlsTransport = this.sctpTransport.dtlsTransport;
802
+ this.setRemoteRTP(transceiver, remoteMedia, remoteSdp.type, i);
803
+ } else if (remoteMedia.kind === "application") {
804
+ if (!this.sctpTransport) {
805
+ this.sctpTransport = this.createSctpTransport();
806
+ this.sctpTransport.mid = remoteMedia.rtp.muxId;
807
+ }
798
808
 
799
- this.setRemoteSCTP(remoteMedia, this.sctpTransport, i);
800
- } else {
801
- throw new Error("invalid media kind");
809
+ if (this.remoteIsBundled) {
810
+ if (!bundleTransport) {
811
+ bundleTransport = this.sctpTransport.dtlsTransport;
812
+ } else {
813
+ this.sctpTransport.setDtlsTransport(bundleTransport);
814
+ }
802
815
  }
803
816
 
804
- const iceTransport = dtlsTransport.iceTransport;
817
+ dtlsTransport = this.sctpTransport.dtlsTransport;
818
+
819
+ this.setRemoteSCTP(remoteMedia, this.sctpTransport, i);
820
+ } else {
821
+ throw new Error("invalid media kind");
822
+ }
823
+
824
+ const iceTransport = dtlsTransport.iceTransport;
805
825
 
806
- if (remoteMedia.iceParams && remoteMedia.dtlsParams) {
807
- iceTransport.setRemoteParams(remoteMedia.iceParams);
808
- dtlsTransport.setRemoteParams(remoteMedia.dtlsParams);
826
+ if (remoteMedia.iceParams && remoteMedia.dtlsParams) {
827
+ iceTransport.setRemoteParams(remoteMedia.iceParams);
828
+ dtlsTransport.setRemoteParams(remoteMedia.dtlsParams);
809
829
 
810
- // One agent full, one lite: The full agent MUST take the controlling role, and the lite agent MUST take the controlled role
811
- // RFC 8445 S6.1.1
812
- if (remoteMedia.iceParams?.iceLite) {
813
- iceTransport.connection.iceControlling = true;
814
- }
830
+ // One agent full, one lite: The full agent MUST take the controlling role, and the lite agent MUST take the controlled role
831
+ // RFC 8445 S6.1.1
832
+ if (remoteMedia.iceParams?.iceLite) {
833
+ iceTransport.connection.iceControlling = true;
815
834
  }
835
+ }
816
836
 
817
- // # add ICE candidates
818
- remoteMedia.iceCandidates.forEach(iceTransport.addRemoteCandidate);
837
+ // # add ICE candidates
838
+ remoteMedia.iceCandidates.forEach(iceTransport.addRemoteCandidate);
819
839
 
820
- await iceTransport.iceGather.gather();
840
+ if (remoteMedia.iceCandidatesComplete) {
841
+ iceTransport.addRemoteCandidate(undefined);
842
+ }
821
843
 
822
- if (remoteMedia.iceCandidatesComplete) {
823
- await iceTransport.addRemoteCandidate(undefined);
824
- }
844
+ // # set DTLS role
845
+ if (remoteSdp.type === "answer" && remoteMedia.dtlsParams?.role) {
846
+ dtlsTransport.role =
847
+ remoteMedia.dtlsParams.role === "client" ? "server" : "client";
848
+ }
849
+ return iceTransport;
850
+ });
825
851
 
826
- // # set DTLS role
827
- if (remoteSdp.type === "answer" && remoteMedia.dtlsParams?.role) {
828
- dtlsTransport.role =
829
- remoteMedia.dtlsParams.role === "client" ? "server" : "client";
830
- }
831
- })
832
- );
852
+ if (remoteSdp.type === "offer") {
853
+ this.setSignalingState("have-remote-offer");
854
+ } else if (remoteSdp.type === "answer") {
855
+ this.setSignalingState("stable");
856
+ }
833
857
 
834
858
  // connect transports
835
859
  if (remoteSdp.type === "answer") {
@@ -840,11 +864,11 @@ export class RTCPeerConnection extends EventTarget {
840
864
  });
841
865
  }
842
866
 
843
- if (remoteSdp.type === "offer") {
844
- this.setSignalingState("have-remote-offer");
845
- } else if (remoteSdp.type === "answer") {
846
- this.setSignalingState("stable");
847
- }
867
+ await Promise.all(
868
+ transports.map(async (iceTransport) => {
869
+ await iceTransport.iceGather.gather();
870
+ })
871
+ );
848
872
 
849
873
  this.negotiationneeded = false;
850
874
  if (this.shouldNegotiationneeded) {
@@ -1140,6 +1164,12 @@ export class RTCPeerConnection extends EventTarget {
1140
1164
  }
1141
1165
 
1142
1166
  async createAnswer() {
1167
+ await this.ensureCerts();
1168
+ const description = this.buildAnswer();
1169
+ return description.toJSON();
1170
+ }
1171
+
1172
+ private buildAnswer() {
1143
1173
  this.assertNotClosed();
1144
1174
  if (
1145
1175
  !["have-remote-offer", "have-local-pranswer"].includes(
@@ -1152,8 +1182,6 @@ export class RTCPeerConnection extends EventTarget {
1152
1182
  throw new Error("wrong state");
1153
1183
  }
1154
1184
 
1155
- await this.ensureCerts();
1156
-
1157
1185
  const description = new SessionDescription();
1158
1186
  addSDPHeader("answer", description);
1159
1187
 
@@ -1206,7 +1234,7 @@ export class RTCPeerConnection extends EventTarget {
1206
1234
  description.group.push(bundle);
1207
1235
  }
1208
1236
 
1209
- return description.toJSON();
1237
+ return description;
1210
1238
  }
1211
1239
 
1212
1240
  async close() {
@@ -43,12 +43,12 @@ export class RTCIceTransport {
43
43
  }
44
44
  }
45
45
 
46
- addRemoteCandidate = async (candidate?: IceCandidate) => {
46
+ addRemoteCandidate = (candidate?: IceCandidate) => {
47
47
  if (!this.connection.remoteCandidatesEnd) {
48
48
  if (!candidate) {
49
- await this.connection.addRemoteCandidate(undefined);
49
+ return this.connection.addRemoteCandidate(undefined);
50
50
  } else {
51
- await this.connection.addRemoteCandidate(candidateToIce(candidate));
51
+ return this.connection.addRemoteCandidate(candidateToIce(candidate));
52
52
  }
53
53
  }
54
54
  };