werift 0.16.2 → 0.17.0

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 (47) hide show
  1. package/lib/dtls/src/server.js +3 -0
  2. package/lib/dtls/src/server.js.map +1 -1
  3. package/lib/dtls/src/socket.d.ts +4 -3
  4. package/lib/dtls/src/socket.js +9 -0
  5. package/lib/dtls/src/socket.js.map +1 -1
  6. package/lib/rtp/src/codec/av1.js +4 -4
  7. package/lib/rtp/src/codec/av1.js.map +1 -1
  8. package/lib/rtp/src/codec/h264.js +1 -1
  9. package/lib/rtp/src/codec/h264.js.map +1 -1
  10. package/lib/rtp/src/codec/index.d.ts +0 -2
  11. package/lib/rtp/src/codec/index.js +1 -21
  12. package/lib/rtp/src/codec/index.js.map +1 -1
  13. package/lib/rtp/src/codec/vp8.js +1 -1
  14. package/lib/rtp/src/codec/vp8.js.map +1 -1
  15. package/lib/rtp/src/codec/vp9.js +1 -1
  16. package/lib/rtp/src/codec/vp9.js.map +1 -1
  17. package/lib/rtp/src/processor/depacketizer.d.ts +2 -1
  18. package/lib/rtp/src/processor/depacketizer.js.map +1 -1
  19. package/lib/rtp/src/processor/interface.d.ts +3 -0
  20. package/lib/rtp/src/processor/interface.js +3 -0
  21. package/lib/rtp/src/processor/interface.js.map +1 -0
  22. package/lib/rtp/src/processor/jitterBuffer.d.ts +2 -1
  23. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  24. package/lib/rtp/src/rtcp/rtpfb/nack.js +11 -11
  25. package/lib/rtp/src/rtcp/rtpfb/nack.js.map +1 -1
  26. package/lib/rtp/src/rtp/red/packet.js +3 -3
  27. package/lib/rtp/src/rtp/red/packet.js.map +1 -1
  28. package/lib/webrtc/src/media/receiver/nack.d.ts +4 -4
  29. package/lib/webrtc/src/media/receiver/nack.js +21 -20
  30. package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
  31. package/lib/webrtc/src/media/rtpSender.d.ts +1 -1
  32. package/lib/webrtc/src/media/rtpSender.js +7 -1
  33. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  34. package/lib/webrtc/src/peerConnection.d.ts +1 -0
  35. package/lib/webrtc/src/peerConnection.js +74 -23
  36. package/lib/webrtc/src/peerConnection.js.map +1 -1
  37. package/lib/webrtc/src/sdp.js +21 -0
  38. package/lib/webrtc/src/sdp.js.map +1 -1
  39. package/lib/webrtc/src/transport/dtls.d.ts +1 -0
  40. package/lib/webrtc/src/transport/dtls.js +13 -6
  41. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  42. package/package.json +1 -1
  43. package/src/media/receiver/nack.ts +26 -23
  44. package/src/media/rtpSender.ts +13 -4
  45. package/src/peerConnection.ts +92 -31
  46. package/src/sdp.ts +30 -0
  47. package/src/transport/dtls.ts +15 -6
@@ -61,6 +61,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
61
61
  this.signalingState = "stable";
62
62
  this.negotiationneeded = false;
63
63
  this.transceivers = [];
64
+ this.candidatesSent = new Set();
64
65
  this.iceGatheringStateChange = new rx_mini_1.default();
65
66
  this.iceConnectionStateChange = new rx_mini_1.default();
66
67
  this.signalingStateChange = new rx_mini_1.default();
@@ -245,6 +246,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
245
246
  else {
246
247
  const transceiver = this.getTransceiverByMid(mid);
247
248
  if (!transceiver) {
249
+ if (m.direction === "inactive") {
250
+ description.media.push(m);
251
+ return;
252
+ }
248
253
  throw new Error("transceiver not found");
249
254
  }
250
255
  transceiver.mLineIndex = i;
@@ -255,11 +260,17 @@ class RTCPeerConnection extends helper_1.EventTarget {
255
260
  this.transceivers
256
261
  .filter((t) => !description.media.find((m) => m.rtp.muxId === t.mid))
257
262
  .forEach((transceiver) => {
258
- transceiver.mLineIndex = description.media.length;
259
263
  if (transceiver.mid == undefined) {
260
264
  transceiver.mid = allocateMid(this.seenMid, "av");
261
265
  }
262
- description.media.push(createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction));
266
+ const mediaDescription = createMediaDescriptionForTransceiver(transceiver, this.cname, transceiver.direction);
267
+ if (transceiver.mLineIndex === undefined) {
268
+ transceiver.mLineIndex = description.media.length;
269
+ description.media.push(mediaDescription);
270
+ }
271
+ else {
272
+ description.media[transceiver.mLineIndex] = mediaDescription;
273
+ }
263
274
  });
264
275
  if (this.sctpTransport &&
265
276
  !description.media.find((m) => m.kind === "application")) {
@@ -271,10 +282,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
271
282
  }
272
283
  if (this.config.bundlePolicy !== "disable") {
273
284
  const mids = description.media
274
- .map((m) => m.rtp.muxId)
285
+ .map((m) => (m.direction !== "inactive" ? m.rtp.muxId : undefined))
275
286
  .filter((v) => v);
276
- const bundle = new sdp_1.GroupDescription("BUNDLE", mids);
277
- description.group.push(bundle);
287
+ if (mids.length) {
288
+ const bundle = new sdp_1.GroupDescription("BUNDLE", mids);
289
+ description.group.push(bundle);
290
+ }
278
291
  }
279
292
  return description;
280
293
  }
@@ -317,13 +330,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
317
330
  this.needNegotiation();
318
331
  return;
319
332
  }
320
- if (transceiver.direction === "sendrecv") {
321
- transceiver.direction = "recvonly";
322
- }
323
- else if (transceiver.direction === "sendonly" ||
324
- transceiver.direction === "recvonly") {
333
+ if (transceiver.stopping || transceiver.stopped) {
325
334
  transceiver.direction = "inactive";
326
335
  }
336
+ else {
337
+ if (transceiver.direction === "sendrecv") {
338
+ transceiver.direction = "recvonly";
339
+ }
340
+ else if (transceiver.direction === "sendonly" ||
341
+ transceiver.direction === "recvonly") {
342
+ transceiver.direction = "inactive";
343
+ }
344
+ }
327
345
  this.needNegotiation();
328
346
  }
329
347
  createTransport(srtpProfiles = []) {
@@ -379,6 +397,15 @@ class RTCPeerConnection extends helper_1.EventTarget {
379
397
  }
380
398
  }
381
399
  candidate.foundation = "candidate:" + candidate.foundation;
400
+ // prevent ice candidates that have already been sent from being being resent
401
+ // when the connection is renegotiated during a later setLocalDescription call.
402
+ if (candidate.sdpMid) {
403
+ const candidateKey = `${candidate.foundation}:${candidate.sdpMid}`;
404
+ if (this.candidatesSent.has(candidateKey)) {
405
+ return;
406
+ }
407
+ this.candidatesSent.add(candidateKey);
408
+ }
382
409
  this.onIceCandidate.execute(candidate.toJSON());
383
410
  if (this.onicecandidate) {
384
411
  this.onicecandidate({ candidate: candidate.toJSON() });
@@ -623,11 +650,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
623
650
  }
624
651
  let bundleTransport;
625
652
  // # apply description
626
- const transports = (0, helper_1.enumerate)(remoteSdp.media).map(([i, remoteMedia]) => {
653
+ const matchTransceiverWithMedia = (transceiver, media) => transceiver.kind === media.kind &&
654
+ [undefined, media.rtp.muxId].includes(transceiver.mid);
655
+ let transports = (0, helper_1.enumerate)(remoteSdp.media).map(([i, remoteMedia]) => {
627
656
  let dtlsTransport;
628
657
  if (["audio", "video"].includes(remoteMedia.kind)) {
629
- let transceiver = this.transceivers.find((t) => t.kind === remoteMedia.kind &&
630
- [undefined, remoteMedia.rtp.muxId].includes(t.mid));
658
+ let transceiver = this.transceivers.find((t) => matchTransceiverWithMedia(t, remoteMedia));
631
659
  if (!transceiver) {
632
660
  // create remote transceiver
633
661
  transceiver = this.addTransceiver(remoteMedia.kind, {
@@ -636,6 +664,13 @@ class RTCPeerConnection extends helper_1.EventTarget {
636
664
  transceiver.mid = remoteMedia.rtp.muxId;
637
665
  this.onRemoteTransceiverAdded.execute(transceiver);
638
666
  }
667
+ else {
668
+ if (transceiver.direction === "inactive" && transceiver.stopping) {
669
+ transceiver.stopped = true;
670
+ transceiver.currentDirection = "inactive";
671
+ return;
672
+ }
673
+ }
639
674
  if (this.remoteIsBundled) {
640
675
  if (!bundleTransport) {
641
676
  bundleTransport = transceiver.dtlsTransport;
@@ -688,6 +723,18 @@ class RTCPeerConnection extends helper_1.EventTarget {
688
723
  }
689
724
  return iceTransport;
690
725
  });
726
+ // filter out inactive transports
727
+ transports = transports.filter((iceTransport) => !!iceTransport);
728
+ const removedTransceivers = this.transceivers.filter((t) => remoteSdp.media.find((m) => matchTransceiverWithMedia(t, m)) ==
729
+ undefined);
730
+ if (sessionDescription.type === "answer") {
731
+ for (const transceiver of removedTransceivers) {
732
+ // todo: handle answer side transceiver removal work.
733
+ // event should trigger to notify media source to stop.
734
+ transceiver.stop();
735
+ transceiver.stopped = true;
736
+ }
737
+ }
691
738
  if (remoteSdp.type === "offer") {
692
739
  this.setSignalingState("have-remote-offer");
693
740
  }
@@ -852,7 +899,17 @@ class RTCPeerConnection extends helper_1.EventTarget {
852
899
  const transceiver = new rtpTransceiver_1.RTCRtpTransceiver(kind, dtlsTransport, receiver, sender, direction);
853
900
  transceiver.options = options;
854
901
  this.router.registerRtpSender(transceiver.sender);
855
- this.transceivers.push(transceiver);
902
+ // reuse inactive
903
+ const inactiveTransceiverIndex = this.transceivers.findIndex((t) => t.currentDirection === "inactive");
904
+ const inactiveTransceiver = this.transceivers.find((t) => t.currentDirection === "inactive");
905
+ if (inactiveTransceiverIndex > -1) {
906
+ this.transceivers[inactiveTransceiverIndex] = transceiver;
907
+ transceiver.mLineIndex = inactiveTransceiver.mLineIndex;
908
+ inactiveTransceiver.currentDirection = "stopped";
909
+ }
910
+ else {
911
+ this.transceivers.push(transceiver);
912
+ }
856
913
  this.onTransceiverAdded.execute(transceiver);
857
914
  this.updateIceConnectionState();
858
915
  this.needNegotiation();
@@ -1145,17 +1202,11 @@ function addTransportDescription(media, dtlsTransport) {
1145
1202
  media.iceCandidatesComplete = iceGatherer.gatheringState === "complete";
1146
1203
  media.iceParams = iceGatherer.localParameters;
1147
1204
  media.iceOptions = "trickle";
1148
- if (media.iceCandidates.length > 0) {
1149
- const candidate = media.iceCandidates[media.iceCandidates.length - 1];
1150
- media.host = candidate.ip;
1151
- media.port = candidate.port;
1152
- }
1153
- else {
1154
- media.host = const_1.DISCARD_HOST;
1155
- media.port = const_1.DISCARD_PORT;
1156
- }
1205
+ media.host = const_1.DISCARD_HOST;
1206
+ media.port = const_1.DISCARD_PORT;
1157
1207
  if (media.direction === "inactive") {
1158
1208
  media.port = 0;
1209
+ media.msid = undefined;
1159
1210
  }
1160
1211
  if (!media.dtlsParams) {
1161
1212
  media.dtlsParams = dtlsTransport.localParameters;