werift 0.17.0 → 0.17.2

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 (108) hide show
  1. package/lib/ice/src/ice.d.ts +10 -1
  2. package/lib/ice/src/ice.js +15 -3
  3. package/lib/ice/src/ice.js.map +1 -1
  4. package/lib/rtp/src/container/ebml/ebml.d.ts +32 -0
  5. package/lib/rtp/src/container/ebml/ebml.js +115 -0
  6. package/lib/rtp/src/container/ebml/ebml.js.map +1 -0
  7. package/lib/rtp/src/container/ebml/id.d.ts +221 -0
  8. package/lib/rtp/src/container/ebml/id.js +225 -0
  9. package/lib/rtp/src/container/ebml/id.js.map +1 -0
  10. package/lib/rtp/src/container/ebml/index.d.ts +3 -0
  11. package/lib/rtp/src/container/ebml/index.js +20 -0
  12. package/lib/rtp/src/container/ebml/index.js.map +1 -0
  13. package/lib/rtp/src/container/ebml/typedArrayUtils.d.ts +7 -0
  14. package/lib/rtp/src/container/ebml/typedArrayUtils.js +109 -0
  15. package/lib/rtp/src/container/ebml/typedArrayUtils.js.map +1 -0
  16. package/lib/rtp/src/container/webm.d.ts +10 -4
  17. package/lib/rtp/src/container/webm.js +56 -7
  18. package/lib/rtp/src/container/webm.js.map +1 -1
  19. package/lib/rtp/src/index.d.ts +1 -0
  20. package/lib/rtp/src/index.js +1 -0
  21. package/lib/rtp/src/index.js.map +1 -1
  22. package/lib/rtp/src/processor/avBuffer.d.ts +28 -0
  23. package/lib/rtp/src/processor/avBuffer.js +91 -0
  24. package/lib/rtp/src/processor/avBuffer.js.map +1 -0
  25. package/lib/rtp/src/processor/avBufferCallback.d.ts +10 -0
  26. package/lib/rtp/src/processor/avBufferCallback.js +27 -0
  27. package/lib/rtp/src/processor/avBufferCallback.js.map +1 -0
  28. package/lib/rtp/src/processor/depacketizer.d.ts +1 -1
  29. package/lib/rtp/src/processor/depacketizer.js.map +1 -1
  30. package/lib/rtp/src/processor/depacketizerCallback.d.ts +1 -3
  31. package/lib/rtp/src/processor/depacketizerCallback.js +2 -2
  32. package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -1
  33. package/lib/rtp/src/processor/depacketizerTransformer.d.ts +1 -1
  34. package/lib/rtp/src/processor/index.d.ts +3 -0
  35. package/lib/rtp/src/processor/index.js +3 -0
  36. package/lib/rtp/src/processor/index.js.map +1 -1
  37. package/lib/rtp/src/processor/jitterBuffer.d.ts +1 -1
  38. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  39. package/lib/rtp/src/processor/jitterBufferCallback.d.ts +1 -3
  40. package/lib/rtp/src/processor/jitterBufferCallback.js +2 -2
  41. package/lib/rtp/src/processor/jitterBufferCallback.js.map +1 -1
  42. package/lib/rtp/src/processor/jitterBufferTransformer.d.ts +1 -1
  43. package/lib/rtp/src/processor/source/index.d.ts +2 -2
  44. package/lib/rtp/src/processor/source/index.js +16 -3
  45. package/lib/rtp/src/processor/source/index.js.map +1 -1
  46. package/lib/rtp/src/processor/source/rtpCallback.d.ts +17 -0
  47. package/lib/rtp/src/processor/source/rtpCallback.js +33 -0
  48. package/lib/rtp/src/processor/source/rtpCallback.js.map +1 -0
  49. package/lib/rtp/src/processor/source/{rtp.d.ts → rtpStream.d.ts} +2 -5
  50. package/lib/rtp/src/processor/source/{rtp.js → rtpStream.js} +12 -12
  51. package/lib/rtp/src/processor/source/rtpStream.js.map +1 -0
  52. package/lib/rtp/src/processor/webm.d.ts +17 -2
  53. package/lib/rtp/src/processor/webm.js +83 -33
  54. package/lib/rtp/src/processor/webm.js.map +1 -1
  55. package/lib/rtp/src/processor/webmCallback.d.ts +16 -0
  56. package/lib/rtp/src/processor/webmCallback.js +21 -0
  57. package/lib/rtp/src/processor/webmCallback.js.map +1 -0
  58. package/lib/rtp/src/processor/webmStream.d.ts +5 -16
  59. package/lib/rtp/src/processor/webmStream.js.map +1 -1
  60. package/lib/{webrtc/src/media/receiver/red.d.ts → rtp/src/rtp/red/handler.d.ts} +2 -2
  61. package/lib/{webrtc/src/media/receiver/red.js → rtp/src/rtp/red/handler.js} +10 -10
  62. package/lib/rtp/src/rtp/red/handler.js.map +1 -0
  63. package/lib/webrtc/src/const.d.ts +1 -1
  64. package/lib/webrtc/src/const.js +2 -2
  65. package/lib/webrtc/src/const.js.map +1 -1
  66. package/lib/webrtc/src/media/receiver/nack.d.ts +1 -0
  67. package/lib/webrtc/src/media/receiver/nack.js +29 -16
  68. package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
  69. package/lib/webrtc/src/media/router.js +17 -13
  70. package/lib/webrtc/src/media/router.js.map +1 -1
  71. package/lib/webrtc/src/media/rtpReceiver.d.ts +1 -1
  72. package/lib/webrtc/src/media/rtpReceiver.js +14 -9
  73. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  74. package/lib/webrtc/src/media/rtpTransceiver.d.ts +10 -6
  75. package/lib/webrtc/src/media/rtpTransceiver.js +23 -14
  76. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  77. package/lib/webrtc/src/media/track.js +3 -2
  78. package/lib/webrtc/src/media/track.js.map +1 -1
  79. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  80. package/lib/webrtc/src/nonstandard/userMedia.d.ts +20 -3
  81. package/lib/webrtc/src/nonstandard/userMedia.js +79 -8
  82. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  83. package/lib/webrtc/src/peerConnection.d.ts +5 -2
  84. package/lib/webrtc/src/peerConnection.js +72 -46
  85. package/lib/webrtc/src/peerConnection.js.map +1 -1
  86. package/lib/webrtc/src/sdp.js +2 -2
  87. package/lib/webrtc/src/sdp.js.map +1 -1
  88. package/lib/webrtc/src/transport/ice.js +10 -3
  89. package/lib/webrtc/src/transport/ice.js.map +1 -1
  90. package/lib/webrtc/src/utils.d.ts +0 -1
  91. package/lib/webrtc/src/utils.js +1 -3
  92. package/lib/webrtc/src/utils.js.map +1 -1
  93. package/package.json +1 -1
  94. package/src/const.ts +1 -1
  95. package/src/media/receiver/nack.ts +33 -17
  96. package/src/media/router.ts +16 -13
  97. package/src/media/rtpReceiver.ts +21 -9
  98. package/src/media/rtpTransceiver.ts +28 -15
  99. package/src/media/track.ts +3 -2
  100. package/src/nonstandard/recorder/writer/webm.ts +2 -2
  101. package/src/nonstandard/userMedia.ts +89 -7
  102. package/src/peerConnection.ts +88 -51
  103. package/src/sdp.ts +2 -2
  104. package/src/transport/ice.ts +13 -3
  105. package/src/utils.ts +0 -3
  106. package/lib/rtp/src/processor/source/rtp.js.map +0 -1
  107. package/lib/webrtc/src/media/receiver/red.js.map +0 -1
  108. package/src/media/receiver/red.ts +0 -70
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AudioRedHandler = void 0;
3
+ exports.RedHandler = void 0;
4
4
  const __1 = require("../..");
5
5
  // 0 1 2 3
6
6
  // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -11,29 +11,29 @@ const __1 = require("../..");
11
11
  // +-+-+-+-+-+-+-+-+
12
12
  // |0| Block PT |
13
13
  // +-+-+-+-+-+-+-+-+
14
- class AudioRedHandler {
14
+ class RedHandler {
15
15
  constructor() {
16
16
  this.size = 150;
17
17
  this.sequenceNumbers = [];
18
18
  }
19
- push(red, rtp) {
19
+ push(red, base) {
20
20
  const packets = [];
21
21
  red.blocks.forEach(({ blockPT, timestampOffset, block }, i) => {
22
- const sequenceNumber = (0, __1.uint16Add)(rtp.header.sequenceNumber, -(red.blocks.length - (i + 1)));
22
+ const sequenceNumber = (0, __1.uint16Add)(base.header.sequenceNumber, -(red.blocks.length - (i + 1)));
23
23
  if (timestampOffset) {
24
24
  packets.push(new __1.RtpPacket(new __1.RtpHeader({
25
- timestamp: (0, __1.uint32Add)(rtp.header.timestamp, -timestampOffset),
25
+ timestamp: (0, __1.uint32Add)(base.header.timestamp, -timestampOffset),
26
26
  payloadType: blockPT,
27
- ssrc: rtp.header.ssrc,
27
+ ssrc: base.header.ssrc,
28
28
  sequenceNumber,
29
29
  marker: true,
30
30
  }), block));
31
31
  }
32
32
  else {
33
33
  packets.push(new __1.RtpPacket(new __1.RtpHeader({
34
- timestamp: rtp.header.timestamp,
34
+ timestamp: base.header.timestamp,
35
35
  payloadType: blockPT,
36
- ssrc: rtp.header.ssrc,
36
+ ssrc: base.header.ssrc,
37
37
  sequenceNumber,
38
38
  marker: true,
39
39
  }), block));
@@ -56,5 +56,5 @@ class AudioRedHandler {
56
56
  return filtered;
57
57
  }
58
58
  }
59
- exports.AudioRedHandler = AudioRedHandler;
60
- //# sourceMappingURL=red.js.map
59
+ exports.RedHandler = RedHandler;
60
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../../../../rtp/src/rtp/red/handler.ts"],"names":[],"mappings":";;;AAAA,6BAAwE;AAExE,iEAAiE;AACjE,mEAAmE;AACnE,oEAAoE;AACpE,oEAAoE;AACpE,oEAAoE;AAEpE,kBAAkB;AAClB,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AAEpB,MAAa,UAAU;IAAvB;QACmB,SAAI,GAAG,GAAG,CAAC;QACpB,oBAAe,GAAa,EAAE,CAAC;IAsDzC,CAAC;IApDC,IAAI,CAAC,GAAQ,EAAE,IAAe;QAC5B,MAAM,OAAO,GAAgB,EAAE,CAAC;QAEhC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5D,MAAM,cAAc,GAAG,IAAA,aAAS,EAC9B,IAAI,CAAC,MAAM,CAAC,cAAc,EAC1B,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAC/B,CAAC;YACF,IAAI,eAAe,EAAE;gBACnB,OAAO,CAAC,IAAI,CACV,IAAI,aAAS,CACX,IAAI,aAAS,CAAC;oBACZ,SAAS,EAAE,IAAA,aAAS,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC;oBAC7D,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;oBACtB,cAAc;oBACd,MAAM,EAAE,IAAI;iBACb,CAAC,EACF,KAAK,CACN,CACF,CAAC;aACH;iBAAM;gBACL,OAAO,CAAC,IAAI,CACV,IAAI,aAAS,CACX,IAAI,aAAS,CAAC;oBACZ,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS;oBAChC,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;oBACtB,cAAc;oBACd,MAAM,EAAE,IAAI;iBACb,CAAC,EACF,KAAK,CACN,CACF,CAAC;aACH;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACpC,YAAY;YACZ,IAAI,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;gBAC1D,OAAO,KAAK,CAAC;aACd;iBAAM;gBACL,kBAAkB;gBAClB,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE;oBAC3C,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;iBAC9B;gBACD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBACnD,OAAO,IAAI,CAAC;aACb;QACH,CAAC,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAxDD,gCAwDC","sourcesContent":["import { Red, RtpHeader, RtpPacket, uint16Add, uint32Add } from \"../..\";\n\n// 0 1 2 3\n// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n// |F| block PT | timestamp offset | block length |\n// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n// 0 1 2 3 4 5 6 7\n// +-+-+-+-+-+-+-+-+\n// |0| Block PT |\n// +-+-+-+-+-+-+-+-+\n\nexport class RedHandler {\n private readonly size = 150;\n private sequenceNumbers: number[] = [];\n\n push(red: Red, base: RtpPacket) {\n const packets: RtpPacket[] = [];\n\n red.blocks.forEach(({ blockPT, timestampOffset, block }, i) => {\n const sequenceNumber = uint16Add(\n base.header.sequenceNumber,\n -(red.blocks.length - (i + 1))\n );\n if (timestampOffset) {\n packets.push(\n new RtpPacket(\n new RtpHeader({\n timestamp: uint32Add(base.header.timestamp, -timestampOffset),\n payloadType: blockPT,\n ssrc: base.header.ssrc,\n sequenceNumber,\n marker: true,\n }),\n block\n )\n );\n } else {\n packets.push(\n new RtpPacket(\n new RtpHeader({\n timestamp: base.header.timestamp,\n payloadType: blockPT,\n ssrc: base.header.ssrc,\n sequenceNumber,\n marker: true,\n }),\n block\n )\n );\n }\n });\n\n const filtered = packets.filter((p) => {\n // duplicate\n if (this.sequenceNumbers.includes(p.header.sequenceNumber)) {\n return false;\n } else {\n // buffer overflow\n if (this.sequenceNumbers.length > this.size) {\n this.sequenceNumbers.shift();\n }\n this.sequenceNumbers.push(p.header.sequenceNumber);\n return true;\n }\n });\n return filtered;\n }\n}\n"]}
@@ -32,5 +32,5 @@ export declare const SRTP_PROFILE: {
32
32
  readonly SRTP_AEAD_AES_128_GCM: 7;
33
33
  };
34
34
  export declare const SenderDirections: string[];
35
- export declare const NotSenderDirections: string[];
35
+ export declare const ReceiverDirection: string[];
36
36
  export { HashAlgorithms, SignatureAlgorithm };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SignatureAlgorithm = exports.NotSenderDirections = exports.SenderDirections = exports.SRTP_PROFILE = exports.SSRC_INFO_ATTRS = exports.FMTP_INT_PARAMETERS = exports.DTLS_SETUP_ROLE = exports.DTLS_ROLE_SETUP = exports.DIRECTIONS = exports.MEDIA_KINDS = exports.DISCARD_PORT = exports.DISCARD_HOST = exports.WEBRTC_BINARY_EMPTY = exports.WEBRTC_STRING_EMPTY = exports.WEBRTC_BINARY = exports.WEBRTC_STRING = exports.WEBRTC_DCEP = exports.DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED = exports.DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED = exports.DATA_CHANNEL_RELIABLE_UNORDERED = exports.DATA_CHANNEL_PARTIAL_RELIABLE_TIMED = exports.DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT = exports.DATA_CHANNEL_RELIABLE = exports.DATA_CHANNEL_OPEN = exports.DATA_CHANNEL_ACK = void 0;
3
+ exports.SignatureAlgorithm = exports.ReceiverDirection = exports.SenderDirections = exports.SRTP_PROFILE = exports.SSRC_INFO_ATTRS = exports.FMTP_INT_PARAMETERS = exports.DTLS_SETUP_ROLE = exports.DTLS_ROLE_SETUP = exports.DIRECTIONS = exports.MEDIA_KINDS = exports.DISCARD_PORT = exports.DISCARD_HOST = exports.WEBRTC_BINARY_EMPTY = exports.WEBRTC_STRING_EMPTY = exports.WEBRTC_BINARY = exports.WEBRTC_STRING = exports.WEBRTC_DCEP = exports.DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED = exports.DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED = exports.DATA_CHANNEL_RELIABLE_UNORDERED = exports.DATA_CHANNEL_PARTIAL_RELIABLE_TIMED = exports.DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT = exports.DATA_CHANNEL_RELIABLE = exports.DATA_CHANNEL_OPEN = exports.DATA_CHANNEL_ACK = void 0;
4
4
  const const_1 = require("../../dtls/src/cipher/const");
5
5
  Object.defineProperty(exports, "SignatureAlgorithm", { enumerable: true, get: function () { return const_1.SignatureAlgorithm; } });
6
6
  const srtp_1 = require("../../dtls/src/context/srtp");
@@ -48,5 +48,5 @@ exports.SRTP_PROFILE = {
48
48
  SRTP_AEAD_AES_128_GCM: srtp_1.ProtectionProfileAeadAes128Gcm,
49
49
  };
50
50
  exports.SenderDirections = ["sendonly", "sendrecv"];
51
- exports.NotSenderDirections = ["inactive", "recvonly"];
51
+ exports.ReceiverDirection = ["sendrecv", "recvonly"];
52
52
  //# sourceMappingURL=const.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"const.js","sourceRoot":"","sources":["../../../src/const.ts"],"names":[],"mappings":";;;AAAA,uDAGqC;AA8DZ,mGA/DvB,0BAAkB,OA+DuB;AA7D3C,sDAGqC;AAGrC,gCAAgC;AACnB,QAAA,gBAAgB,GAAG,CAAC,CAAC;AACrB,QAAA,iBAAiB,GAAG,CAAC,CAAC;AAEnC,kCAAkC;AACrB,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAC7B,QAAA,oCAAoC,GAAG,IAAI,CAAC;AAC5C,QAAA,mCAAmC,GAAG,IAAI,CAAC;AAC3C,QAAA,+BAA+B,GAAG,IAAI,CAAC;AACvC,QAAA,8CAA8C,GAAG,IAAI,CAAC;AACtD,QAAA,6CAA6C,GAAG,IAAI,CAAC;AAErD,QAAA,WAAW,GAAG,EAAE,CAAC;AACjB,QAAA,aAAa,GAAG,EAAE,CAAC;AACnB,QAAA,aAAa,GAAG,EAAE,CAAC;AACnB,QAAA,mBAAmB,GAAG,EAAE,CAAC;AACzB,QAAA,mBAAmB,GAAG,EAAE,CAAC;AAEzB,QAAA,YAAY,GAAG,SAAS,CAAC;AACzB,QAAA,YAAY,GAAG,CAAC,CAAC;AACjB,QAAA,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEjC,QAAA,UAAU,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC9D,QAAA,eAAe,GAAG;IAC7B,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,SAAS;CAClB,CAAC;AACW,QAAA,eAAe,GAAgC,MAAM,CAAC,IAAI,CACrE,uBAAe,CAChB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACpB,MAAM,GAAG,GAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAC1C,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACf,OAAO,GAAG,CAAC;AACb,CAAC,EAAE,EAAS,CAAC,CAAC;AACD,QAAA,mBAAmB,GAAG;IACjC,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,iBAAiB;IACjB,UAAU;IACV,QAAQ;IACR,cAAc;CACf,CAAC;AAEW,QAAA,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAExD,QAAA,YAAY,GAAG;IAC1B,2BAA2B,EAAE,2CAAoC;IACjE,qBAAqB,EAAE,qCAA8B;CAC7C,CAAC;AAEE,QAAA,gBAAgB,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC5C,QAAA,mBAAmB,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC","sourcesContent":["import {\n HashAlgorithms,\n SignatureAlgorithm,\n} from \"../../dtls/src/cipher/const\";\nimport {\n ProtectionProfileAeadAes128Gcm,\n ProtectionProfileAes128CmHmacSha1_80,\n} from \"../../dtls/src/context/srtp\";\nimport { DtlsRole } from \"./transport/dtls\";\n\n// data channel export constants\nexport const DATA_CHANNEL_ACK = 2;\nexport const DATA_CHANNEL_OPEN = 3;\n\n// 5.1. DATA_CHANNEL_OPEN Message\nexport const DATA_CHANNEL_RELIABLE = 0x00;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT = 0x01;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_TIMED = 0x02;\nexport const DATA_CHANNEL_RELIABLE_UNORDERED = 0x80;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED = 0x81;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED = 0x82;\n\nexport const WEBRTC_DCEP = 50;\nexport const WEBRTC_STRING = 51;\nexport const WEBRTC_BINARY = 53;\nexport const WEBRTC_STRING_EMPTY = 56;\nexport const WEBRTC_BINARY_EMPTY = 57;\n\nexport const DISCARD_HOST = \"0.0.0.0\";\nexport const DISCARD_PORT = 9;\nexport const MEDIA_KINDS = [\"audio\", \"video\"];\n\nexport const DIRECTIONS = [\"inactive\", \"sendonly\", \"recvonly\", \"sendrecv\"];\nexport const DTLS_ROLE_SETUP = {\n auto: \"actpass\",\n client: \"active\",\n server: \"passive\",\n};\nexport const DTLS_SETUP_ROLE: { [key: string]: DtlsRole } = Object.keys(\n DTLS_ROLE_SETUP\n).reduce((acc, cur) => {\n const key = (DTLS_ROLE_SETUP as any)[cur];\n acc[key] = cur;\n return acc;\n}, {} as any);\nexport const FMTP_INT_PARAMETERS = [\n \"apt\",\n \"max-fr\",\n \"max-fs\",\n \"maxplaybackrate\",\n \"minptime\",\n \"stereo\",\n \"useinbandfec\",\n];\n\nexport const SSRC_INFO_ATTRS = [\"cname\", \"msid\", \"mslabel\", \"label\"];\n\nexport const SRTP_PROFILE = {\n SRTP_AES128_CM_HMAC_SHA1_80: ProtectionProfileAes128CmHmacSha1_80,\n SRTP_AEAD_AES_128_GCM: ProtectionProfileAeadAes128Gcm,\n} as const;\n\nexport const SenderDirections = [\"sendonly\", \"sendrecv\"];\nexport const NotSenderDirections = [\"inactive\", \"recvonly\"];\n\nexport { HashAlgorithms, SignatureAlgorithm };\n"]}
1
+ {"version":3,"file":"const.js","sourceRoot":"","sources":["../../../src/const.ts"],"names":[],"mappings":";;;AAAA,uDAGqC;AA8DZ,mGA/DvB,0BAAkB,OA+DuB;AA7D3C,sDAGqC;AAGrC,gCAAgC;AACnB,QAAA,gBAAgB,GAAG,CAAC,CAAC;AACrB,QAAA,iBAAiB,GAAG,CAAC,CAAC;AAEnC,kCAAkC;AACrB,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAC7B,QAAA,oCAAoC,GAAG,IAAI,CAAC;AAC5C,QAAA,mCAAmC,GAAG,IAAI,CAAC;AAC3C,QAAA,+BAA+B,GAAG,IAAI,CAAC;AACvC,QAAA,8CAA8C,GAAG,IAAI,CAAC;AACtD,QAAA,6CAA6C,GAAG,IAAI,CAAC;AAErD,QAAA,WAAW,GAAG,EAAE,CAAC;AACjB,QAAA,aAAa,GAAG,EAAE,CAAC;AACnB,QAAA,aAAa,GAAG,EAAE,CAAC;AACnB,QAAA,mBAAmB,GAAG,EAAE,CAAC;AACzB,QAAA,mBAAmB,GAAG,EAAE,CAAC;AAEzB,QAAA,YAAY,GAAG,SAAS,CAAC;AACzB,QAAA,YAAY,GAAG,CAAC,CAAC;AACjB,QAAA,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEjC,QAAA,UAAU,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC9D,QAAA,eAAe,GAAG;IAC7B,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,SAAS;CAClB,CAAC;AACW,QAAA,eAAe,GAAgC,MAAM,CAAC,IAAI,CACrE,uBAAe,CAChB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IACpB,MAAM,GAAG,GAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAC1C,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACf,OAAO,GAAG,CAAC;AACb,CAAC,EAAE,EAAS,CAAC,CAAC;AACD,QAAA,mBAAmB,GAAG;IACjC,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,iBAAiB;IACjB,UAAU;IACV,QAAQ;IACR,cAAc;CACf,CAAC;AAEW,QAAA,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAExD,QAAA,YAAY,GAAG;IAC1B,2BAA2B,EAAE,2CAAoC;IACjE,qBAAqB,EAAE,qCAA8B;CAC7C,CAAC;AAEE,QAAA,gBAAgB,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC5C,QAAA,iBAAiB,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC","sourcesContent":["import {\n HashAlgorithms,\n SignatureAlgorithm,\n} from \"../../dtls/src/cipher/const\";\nimport {\n ProtectionProfileAeadAes128Gcm,\n ProtectionProfileAes128CmHmacSha1_80,\n} from \"../../dtls/src/context/srtp\";\nimport { DtlsRole } from \"./transport/dtls\";\n\n// data channel export constants\nexport const DATA_CHANNEL_ACK = 2;\nexport const DATA_CHANNEL_OPEN = 3;\n\n// 5.1. DATA_CHANNEL_OPEN Message\nexport const DATA_CHANNEL_RELIABLE = 0x00;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT = 0x01;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_TIMED = 0x02;\nexport const DATA_CHANNEL_RELIABLE_UNORDERED = 0x80;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED = 0x81;\nexport const DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED = 0x82;\n\nexport const WEBRTC_DCEP = 50;\nexport const WEBRTC_STRING = 51;\nexport const WEBRTC_BINARY = 53;\nexport const WEBRTC_STRING_EMPTY = 56;\nexport const WEBRTC_BINARY_EMPTY = 57;\n\nexport const DISCARD_HOST = \"0.0.0.0\";\nexport const DISCARD_PORT = 9;\nexport const MEDIA_KINDS = [\"audio\", \"video\"];\n\nexport const DIRECTIONS = [\"inactive\", \"sendonly\", \"recvonly\", \"sendrecv\"];\nexport const DTLS_ROLE_SETUP = {\n auto: \"actpass\",\n client: \"active\",\n server: \"passive\",\n};\nexport const DTLS_SETUP_ROLE: { [key: string]: DtlsRole } = Object.keys(\n DTLS_ROLE_SETUP\n).reduce((acc, cur) => {\n const key = (DTLS_ROLE_SETUP as any)[cur];\n acc[key] = cur;\n return acc;\n}, {} as any);\nexport const FMTP_INT_PARAMETERS = [\n \"apt\",\n \"max-fr\",\n \"max-fs\",\n \"maxplaybackrate\",\n \"minptime\",\n \"stereo\",\n \"useinbandfec\",\n];\n\nexport const SSRC_INFO_ATTRS = [\"cname\", \"msid\", \"mslabel\", \"label\"];\n\nexport const SRTP_PROFILE = {\n SRTP_AES128_CM_HMAC_SHA1_80: ProtectionProfileAes128CmHmacSha1_80,\n SRTP_AEAD_AES_128_GCM: ProtectionProfileAeadAes128Gcm,\n} as const;\n\nexport const SenderDirections = [\"sendonly\", \"sendrecv\"];\nexport const ReceiverDirection = [\"sendrecv\", \"recvonly\"];\n\nexport { HashAlgorithms, SignatureAlgorithm };\n"]}
@@ -10,6 +10,7 @@ export declare class NackHandler {
10
10
  mediaSourceSsrc?: number;
11
11
  retryCount: number;
12
12
  constructor(receiver: RTCRtpReceiver);
13
+ private start;
13
14
  get lostSeqNumbers(): number[];
14
15
  getLost(seq: number): number;
15
16
  setLost(seq: number, count: number): void;
@@ -16,9 +16,36 @@ class NackHandler {
16
16
  this.receiver = receiver;
17
17
  this.newEstSeqNum = 0;
18
18
  this._lost = {};
19
- this.nackLoop = setInterval(() => this.sendNack(), 20);
20
19
  this.onPacketLost = new rx_mini_1.default();
21
20
  this.retryCount = 10;
21
+ this.sendNack = () => new Promise((r, f) => {
22
+ if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {
23
+ const nack = new src_2.GenericNack({
24
+ senderSsrc: this.receiver.rtcpSsrc,
25
+ mediaSourceSsrc: this.mediaSourceSsrc,
26
+ lost: this.lostSeqNumbers,
27
+ });
28
+ const rtcp = new src_2.RtcpTransportLayerFeedback({
29
+ feedback: nack,
30
+ });
31
+ this.receiver.dtlsTransport.sendRtcp([rtcp]).then(r).catch(f);
32
+ this.updateRetryCount();
33
+ this.onPacketLost.execute(nack);
34
+ }
35
+ });
36
+ }
37
+ start() {
38
+ if (this.nackLoop) {
39
+ return;
40
+ }
41
+ this.nackLoop = setInterval(async () => {
42
+ try {
43
+ await this.sendNack();
44
+ }
45
+ catch (error) {
46
+ log("failed to send nack", error);
47
+ }
48
+ }, 20);
22
49
  }
23
50
  get lostSeqNumbers() {
24
51
  return Object.keys(this._lost).map(Number).sort();
@@ -33,6 +60,7 @@ class NackHandler {
33
60
  delete this._lost[sequenceNumber];
34
61
  }
35
62
  addPacket(packet) {
63
+ this.start();
36
64
  const { sequenceNumber, ssrc } = packet.header;
37
65
  this.mediaSourceSsrc = ssrc;
38
66
  if (this.newEstSeqNum === 0) {
@@ -79,21 +107,6 @@ class NackHandler {
79
107
  }
80
108
  });
81
109
  }
82
- sendNack() {
83
- if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {
84
- const nack = new src_2.GenericNack({
85
- senderSsrc: this.receiver.rtcpSsrc,
86
- mediaSourceSsrc: this.mediaSourceSsrc,
87
- lost: this.lostSeqNumbers,
88
- });
89
- const rtcp = new src_2.RtcpTransportLayerFeedback({
90
- feedback: nack,
91
- });
92
- this.receiver.dtlsTransport.sendRtcp([rtcp]);
93
- this.updateRetryCount();
94
- this.onPacketLost.execute(nack);
95
- }
96
- }
97
110
  }
98
111
  exports.NackHandler = NackHandler;
99
112
  //# sourceMappingURL=nack.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nack.js","sourceRoot":"","sources":["../../../../../src/media/receiver/nack.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport range from \"lodash/range\";\nimport Event from \"rx.mini\";\n\nimport { uint16Add } from \"../../../../common/src\";\nimport {\n GenericNack,\n RtcpTransportLayerFeedback,\n RtpPacket,\n} from \"../../../../rtp/src\";\nimport { RTCRtpReceiver } from \"../rtpReceiver\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/receiver/nack.ts\");\n\nconst LOST_SIZE = 30 * 5;\n\nexport class NackHandler {\n private newEstSeqNum = 0;\n private _lost: { [seqNum: number]: number } = {};\n private nackLoop = setInterval(() => this.sendNack(), 20);\n\n readonly onPacketLost = new Event<[GenericNack]>();\n mediaSourceSsrc?: number;\n retryCount = 10;\n\n constructor(private receiver: RTCRtpReceiver) {}\n\n get lostSeqNumbers() {\n return Object.keys(this._lost).map(Number).sort();\n }\n\n getLost(seq: number) {\n return this._lost[seq];\n }\n\n setLost(seq: number, count: number) {\n this._lost[seq] = count;\n }\n\n removeLost(sequenceNumber: number) {\n delete this._lost[sequenceNumber];\n }\n\n addPacket(packet: RtpPacket) {\n const { sequenceNumber, ssrc } = packet.header;\n this.mediaSourceSsrc = ssrc;\n\n if (this.newEstSeqNum === 0) {\n this.newEstSeqNum = sequenceNumber;\n return;\n }\n\n if (this.getLost(sequenceNumber)) {\n this.removeLost(sequenceNumber);\n return;\n }\n\n if (sequenceNumber === uint16Add(this.newEstSeqNum, 1)) {\n this.newEstSeqNum = sequenceNumber;\n } else if (sequenceNumber > uint16Add(this.newEstSeqNum, 1)) {\n // packet lost detected\n range(uint16Add(this.newEstSeqNum, 1), sequenceNumber).forEach((seq) => {\n this.setLost(seq, 1);\n });\n this.receiver.sendRtcpPLI(this.mediaSourceSsrc);\n\n this.newEstSeqNum = sequenceNumber;\n this.pruneLost();\n }\n }\n\n private pruneLost() {\n if (this.lostSeqNumbers.length > LOST_SIZE) {\n this._lost = Object.entries(this._lost)\n .slice(-LOST_SIZE)\n .reduce((acc, [key, v]) => {\n acc[key] = v;\n return acc;\n }, {} as { [seqNum: number]: number });\n }\n }\n\n close() {\n clearInterval(this.nackLoop);\n this._lost = {};\n }\n\n private updateRetryCount() {\n this.lostSeqNumbers.forEach((seq) => {\n const count = this._lost[seq]++;\n if (count > this.retryCount) {\n this.removeLost(seq);\n return seq;\n }\n });\n }\n\n private sendNack() {\n if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {\n const nack = new GenericNack({\n senderSsrc: this.receiver.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lostSeqNumbers,\n });\n const rtcp = new RtcpTransportLayerFeedback({\n feedback: nack,\n });\n this.receiver.dtlsTransport.sendRtcp([rtcp]);\n\n this.updateRetryCount();\n this.onPacketLost.execute(nack);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"nack.js","sourceRoot":"","sources":["../../../../../src/media/receiver/nack.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport range from \"lodash/range\";\nimport Event from \"rx.mini\";\n\nimport { uint16Add } from \"../../../../common/src\";\nimport {\n GenericNack,\n RtcpTransportLayerFeedback,\n RtpPacket,\n} from \"../../../../rtp/src\";\nimport { RTCRtpReceiver } from \"../rtpReceiver\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/receiver/nack.ts\");\n\nconst LOST_SIZE = 30 * 5;\n\nexport class NackHandler {\n private newEstSeqNum = 0;\n private _lost: { [seqNum: number]: number } = {};\n private nackLoop: any;\n\n readonly onPacketLost = new Event<[GenericNack]>();\n mediaSourceSsrc?: number;\n retryCount = 10;\n\n constructor(private receiver: RTCRtpReceiver) {}\n\n private start() {\n if (this.nackLoop) {\n return;\n }\n this.nackLoop = setInterval(async () => {\n try {\n await this.sendNack();\n } catch (error) {\n log(\"failed to send nack\", error);\n }\n }, 20);\n }\n\n get lostSeqNumbers() {\n return Object.keys(this._lost).map(Number).sort();\n }\n\n getLost(seq: number) {\n return this._lost[seq];\n }\n\n setLost(seq: number, count: number) {\n this._lost[seq] = count;\n }\n\n removeLost(sequenceNumber: number) {\n delete this._lost[sequenceNumber];\n }\n\n addPacket(packet: RtpPacket) {\n this.start();\n\n const { sequenceNumber, ssrc } = packet.header;\n this.mediaSourceSsrc = ssrc;\n\n if (this.newEstSeqNum === 0) {\n this.newEstSeqNum = sequenceNumber;\n return;\n }\n\n if (this.getLost(sequenceNumber)) {\n this.removeLost(sequenceNumber);\n return;\n }\n\n if (sequenceNumber === uint16Add(this.newEstSeqNum, 1)) {\n this.newEstSeqNum = sequenceNumber;\n } else if (sequenceNumber > uint16Add(this.newEstSeqNum, 1)) {\n // packet lost detected\n range(uint16Add(this.newEstSeqNum, 1), sequenceNumber).forEach((seq) => {\n this.setLost(seq, 1);\n });\n this.receiver.sendRtcpPLI(this.mediaSourceSsrc);\n\n this.newEstSeqNum = sequenceNumber;\n this.pruneLost();\n }\n }\n\n private pruneLost() {\n if (this.lostSeqNumbers.length > LOST_SIZE) {\n this._lost = Object.entries(this._lost)\n .slice(-LOST_SIZE)\n .reduce((acc, [key, v]) => {\n acc[key] = v;\n return acc;\n }, {} as { [seqNum: number]: number });\n }\n }\n\n close() {\n clearInterval(this.nackLoop);\n this._lost = {};\n }\n\n private updateRetryCount() {\n this.lostSeqNumbers.forEach((seq) => {\n const count = this._lost[seq]++;\n if (count > this.retryCount) {\n this.removeLost(seq);\n return seq;\n }\n });\n }\n\n private sendNack = () =>\n new Promise((r, f) => {\n if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {\n const nack = new GenericNack({\n senderSsrc: this.receiver.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lostSeqNumbers,\n });\n const rtcp = new RtcpTransportLayerFeedback({\n feedback: nack,\n });\n this.receiver.dtlsTransport.sendRtcp([rtcp]).then(r).catch(f);\n\n this.updateRetryCount();\n this.onPacketLost.execute(nack);\n }\n });\n}\n"]}
@@ -18,38 +18,41 @@ class RtpRouter {
18
18
  this.extIdUriMap = {};
19
19
  this.routeRtp = (packet) => {
20
20
  const extensions = RtpRouter.rtpHeaderExtensionsParser(packet.header.extensions, this.extIdUriMap);
21
- let ssrcReceiver = this.ssrcTable[packet.header.ssrc];
21
+ let rtpReceiver = this.ssrcTable[packet.header.ssrc];
22
22
  const rid = extensions[rtpExtension_1.RTP_EXTENSION_URI.sdesRTPStreamID];
23
23
  if (typeof rid === "string") {
24
- ssrcReceiver = this.ridTable[rid];
25
- ssrcReceiver.latestRid = rid;
26
- ssrcReceiver.handleRtpByRid(packet, rid, extensions);
24
+ rtpReceiver = this.ridTable[rid];
25
+ rtpReceiver.latestRid = rid;
26
+ rtpReceiver.handleRtpByRid(packet, rid, extensions);
27
27
  }
28
- else if (ssrcReceiver) {
29
- ssrcReceiver.handleRtpBySsrc(packet, extensions);
28
+ else if (rtpReceiver) {
29
+ rtpReceiver.handleRtpBySsrc(packet, extensions);
30
30
  }
31
31
  else {
32
32
  // simulcast after send receiver report
33
- ssrcReceiver = Object.values(this.ridTable)
33
+ rtpReceiver = Object.values(this.ridTable)
34
34
  .filter((r) => r instanceof rtpReceiver_1.RTCRtpReceiver)
35
35
  .find((r) => r.trackBySSRC[packet.header.ssrc]);
36
- if (ssrcReceiver) {
36
+ if (rtpReceiver) {
37
37
  log("simulcast register receiver by ssrc", packet.header.ssrc);
38
- this.registerRtpReceiver(ssrcReceiver, packet.header.ssrc);
39
- ssrcReceiver.handleRtpBySsrc(packet, extensions);
38
+ this.registerRtpReceiver(rtpReceiver, packet.header.ssrc);
39
+ rtpReceiver.handleRtpBySsrc(packet, extensions);
40
+ }
41
+ else {
42
+ // bug
40
43
  }
41
44
  }
42
- if (!ssrcReceiver) {
45
+ if (!rtpReceiver) {
43
46
  log("ssrcReceiver not found");
44
47
  return;
45
48
  }
46
49
  const sdesMid = extensions[rtpExtension_1.RTP_EXTENSION_URI.sdesMid];
47
50
  if (typeof sdesMid === "string") {
48
- ssrcReceiver.sdesMid = sdesMid;
51
+ rtpReceiver.sdesMid = sdesMid;
49
52
  }
50
53
  const repairedRid = extensions[rtpExtension_1.RTP_EXTENSION_URI.repairedRtpStreamId];
51
54
  if (typeof repairedRid === "string") {
52
- ssrcReceiver.latestRepairedRid = repairedRid;
55
+ rtpReceiver.latestRepairedRid = repairedRid;
53
56
  }
54
57
  };
55
58
  this.routeRtcp = (packet) => {
@@ -106,6 +109,7 @@ class RtpRouter {
106
109
  this.ssrcTable[sender.ssrc] = sender;
107
110
  }
108
111
  registerRtpReceiver(receiver, ssrc) {
112
+ log("registerRtpReceiver", ssrc);
109
113
  this.ssrcTable[ssrc] = receiver;
110
114
  }
111
115
  registerRtpReceiverBySsrc(transceiver, params) {
@@ -1 +1 @@
1
- {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/media/router.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { bufferReader } from \"../../../common/src\";\nimport {\n Extension,\n ReceiverEstimatedMaxBitrate,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n RtpPacket,\n} from \"../../../rtp/src\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport {\n RTCRtpReceiveParameters,\n RTCRtpSimulcastParameters,\n} from \"./parameters\";\nimport { RTCRtpReceiver } from \"./rtpReceiver\";\nimport { RTCRtpSender } from \"./rtpSender\";\nimport { RTCRtpTransceiver } from \"./rtpTransceiver\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/router.ts\");\n\nexport type Extensions = { [uri: string]: number | string };\n\nexport class RtpRouter {\n ssrcTable: { [ssrc: number]: RTCRtpReceiver | RTCRtpSender } = {};\n ridTable: { [rid: string]: RTCRtpReceiver | RTCRtpSender } = {};\n extIdUriMap: { [id: number]: string } = {};\n\n constructor() {}\n\n registerRtpSender(sender: RTCRtpSender) {\n this.ssrcTable[sender.ssrc] = sender;\n }\n\n private registerRtpReceiver(receiver: RTCRtpReceiver, ssrc: number) {\n this.ssrcTable[ssrc] = receiver;\n }\n\n registerRtpReceiverBySsrc(\n transceiver: RTCRtpTransceiver,\n params: RTCRtpReceiveParameters\n ) {\n log(\"registerRtpReceiverBySsrc\", params);\n\n params.encodings\n .filter((e) => e.ssrc != undefined) // todo fix\n .forEach((encode, i) => {\n this.registerRtpReceiver(transceiver.receiver, encode.ssrc);\n transceiver.addTrack(\n new MediaStreamTrack({\n ssrc: encode.ssrc,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec: params.codecs[i],\n })\n );\n if (encode.rtx) {\n this.registerRtpReceiver(transceiver.receiver, encode.rtx.ssrc);\n }\n });\n\n params.headerExtensions.forEach((extension) => {\n this.extIdUriMap[extension.id] = extension.uri;\n });\n }\n\n registerRtpReceiverByRid(\n transceiver: RTCRtpTransceiver,\n param: RTCRtpSimulcastParameters,\n params: RTCRtpReceiveParameters\n ) {\n // サイマルキャスト利用時のRTXをサポートしていないのでcodecs/encodingsは常に一つ\n const [codec] = params.codecs;\n\n log(\"registerRtpReceiverByRid\", param);\n transceiver.addTrack(\n new MediaStreamTrack({\n rid: param.rid,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec,\n })\n );\n this.ridTable[param.rid] = transceiver.receiver;\n }\n\n static rtpHeaderExtensionsParser(\n extensions: Extension[],\n extIdUriMap: { [id: number]: string }\n ): Extensions {\n return extensions\n .map((extension) => {\n const uri = extIdUriMap[extension.id];\n switch (uri) {\n case RTP_EXTENSION_URI.sdesMid:\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n return { uri, value: extension.payload.toString() };\n case RTP_EXTENSION_URI.transportWideCC:\n return { uri, value: extension.payload.readUInt16BE() };\n case RTP_EXTENSION_URI.absSendTime:\n return {\n uri,\n value: bufferReader(extension.payload, [3])[0],\n };\n default:\n return { uri, value: 0 };\n }\n })\n .reduce((acc: { [uri: string]: any }, cur) => {\n if (cur) acc[cur.uri] = cur.value;\n return acc;\n }, {});\n }\n\n routeRtp = (packet: RtpPacket) => {\n const extensions = RtpRouter.rtpHeaderExtensionsParser(\n packet.header.extensions,\n this.extIdUriMap\n );\n\n let ssrcReceiver: RTCRtpReceiver | undefined = this.ssrcTable[\n packet.header.ssrc\n ] as RTCRtpReceiver;\n\n const rid = extensions[RTP_EXTENSION_URI.sdesRTPStreamID];\n if (typeof rid === \"string\") {\n ssrcReceiver = this.ridTable[rid] as RTCRtpReceiver;\n ssrcReceiver.latestRid = rid;\n ssrcReceiver.handleRtpByRid(packet, rid, extensions);\n } else if (ssrcReceiver) {\n ssrcReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // simulcast after send receiver report\n ssrcReceiver = Object.values(this.ridTable)\n .filter((r): r is RTCRtpReceiver => r instanceof RTCRtpReceiver)\n .find((r) => r.trackBySSRC[packet.header.ssrc]);\n if (ssrcReceiver) {\n log(\"simulcast register receiver by ssrc\", packet.header.ssrc);\n this.registerRtpReceiver(ssrcReceiver, packet.header.ssrc);\n ssrcReceiver.handleRtpBySsrc(packet, extensions);\n }\n }\n\n if (!ssrcReceiver) {\n log(\"ssrcReceiver not found\");\n return;\n }\n\n const sdesMid = extensions[RTP_EXTENSION_URI.sdesMid];\n if (typeof sdesMid === \"string\") {\n ssrcReceiver.sdesMid = sdesMid;\n }\n\n const repairedRid = extensions[\n RTP_EXTENSION_URI.repairedRtpStreamId\n ] as string;\n if (typeof repairedRid === \"string\") {\n ssrcReceiver.latestRepairedRid = repairedRid;\n }\n };\n\n routeRtcp = (packet: RtcpPacket) => {\n const recipients: (RTCRtpReceiver | RTCRtpSender)[] = [];\n\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n packet = packet as RtcpSrPacket;\n recipients.push(this.ssrcTable[packet.ssrc]);\n }\n break;\n case RtcpRrPacket.type:\n {\n packet = packet as RtcpRrPacket;\n packet.reports.forEach((report) => {\n recipients.push(this.ssrcTable[report.ssrc]);\n });\n }\n break;\n case RtcpSourceDescriptionPacket.type:\n {\n const sdes = packet as RtcpSourceDescriptionPacket;\n // log(\"sdes\", JSON.stringify(sdes.chunks));\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const rtpfb = packet as RtcpTransportLayerFeedback;\n if (rtpfb.feedback) {\n recipients.push(this.ssrcTable[rtpfb.feedback.mediaSourceSsrc]);\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const psfb = packet as RtcpPayloadSpecificFeedback;\n switch (psfb.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n const remb = psfb.feedback as ReceiverEstimatedMaxBitrate;\n recipients.push(this.ssrcTable[remb.ssrcFeedbacks[0]]);\n break;\n default:\n recipients.push(this.ssrcTable[psfb.feedback.senderSsrc]);\n }\n }\n break;\n }\n recipients\n .filter((v) => v) // todo simulcast\n .forEach((recipient) => recipient.handleRtcpPacket(packet));\n };\n}\n"]}
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../../../src/media/router.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\n\nimport { bufferReader } from \"../../../common/src\";\nimport {\n Extension,\n ReceiverEstimatedMaxBitrate,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n RtpPacket,\n} from \"../../../rtp/src\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport {\n RTCRtpReceiveParameters,\n RTCRtpSimulcastParameters,\n} from \"./parameters\";\nimport { RTCRtpReceiver } from \"./rtpReceiver\";\nimport { RTCRtpSender } from \"./rtpSender\";\nimport { RTCRtpTransceiver } from \"./rtpTransceiver\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/router.ts\");\n\nexport type Extensions = { [uri: string]: number | string };\n\nexport class RtpRouter {\n ssrcTable: { [ssrc: number]: RTCRtpReceiver | RTCRtpSender } = {};\n ridTable: { [rid: string]: RTCRtpReceiver | RTCRtpSender } = {};\n extIdUriMap: { [id: number]: string } = {};\n\n constructor() {}\n\n registerRtpSender(sender: RTCRtpSender) {\n this.ssrcTable[sender.ssrc] = sender;\n }\n\n private registerRtpReceiver(receiver: RTCRtpReceiver, ssrc: number) {\n log(\"registerRtpReceiver\", ssrc);\n this.ssrcTable[ssrc] = receiver;\n }\n\n registerRtpReceiverBySsrc(\n transceiver: RTCRtpTransceiver,\n params: RTCRtpReceiveParameters\n ) {\n log(\"registerRtpReceiverBySsrc\", params);\n\n params.encodings\n .filter((e) => e.ssrc != undefined) // todo fix\n .forEach((encode, i) => {\n this.registerRtpReceiver(transceiver.receiver, encode.ssrc);\n transceiver.addTrack(\n new MediaStreamTrack({\n ssrc: encode.ssrc,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec: params.codecs[i],\n })\n );\n if (encode.rtx) {\n this.registerRtpReceiver(transceiver.receiver, encode.rtx.ssrc);\n }\n });\n\n params.headerExtensions.forEach((extension) => {\n this.extIdUriMap[extension.id] = extension.uri;\n });\n }\n\n registerRtpReceiverByRid(\n transceiver: RTCRtpTransceiver,\n param: RTCRtpSimulcastParameters,\n params: RTCRtpReceiveParameters\n ) {\n // サイマルキャスト利用時のRTXをサポートしていないのでcodecs/encodingsは常に一つ\n const [codec] = params.codecs;\n\n log(\"registerRtpReceiverByRid\", param);\n transceiver.addTrack(\n new MediaStreamTrack({\n rid: param.rid,\n kind: transceiver.kind,\n id: transceiver.sender.trackId,\n remote: true,\n codec,\n })\n );\n this.ridTable[param.rid] = transceiver.receiver;\n }\n\n static rtpHeaderExtensionsParser(\n extensions: Extension[],\n extIdUriMap: { [id: number]: string }\n ): Extensions {\n return extensions\n .map((extension) => {\n const uri = extIdUriMap[extension.id];\n switch (uri) {\n case RTP_EXTENSION_URI.sdesMid:\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n return { uri, value: extension.payload.toString() };\n case RTP_EXTENSION_URI.transportWideCC:\n return { uri, value: extension.payload.readUInt16BE() };\n case RTP_EXTENSION_URI.absSendTime:\n return {\n uri,\n value: bufferReader(extension.payload, [3])[0],\n };\n default:\n return { uri, value: 0 };\n }\n })\n .reduce((acc: { [uri: string]: any }, cur) => {\n if (cur) acc[cur.uri] = cur.value;\n return acc;\n }, {});\n }\n\n routeRtp = (packet: RtpPacket) => {\n const extensions = RtpRouter.rtpHeaderExtensionsParser(\n packet.header.extensions,\n this.extIdUriMap\n );\n\n let rtpReceiver: RTCRtpReceiver | undefined = this.ssrcTable[\n packet.header.ssrc\n ] as RTCRtpReceiver;\n\n const rid = extensions[RTP_EXTENSION_URI.sdesRTPStreamID];\n if (typeof rid === \"string\") {\n rtpReceiver = this.ridTable[rid] as RTCRtpReceiver;\n rtpReceiver.latestRid = rid;\n rtpReceiver.handleRtpByRid(packet, rid, extensions);\n } else if (rtpReceiver) {\n rtpReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // simulcast after send receiver report\n rtpReceiver = Object.values(this.ridTable)\n .filter((r): r is RTCRtpReceiver => r instanceof RTCRtpReceiver)\n .find((r) => r.trackBySSRC[packet.header.ssrc]);\n if (rtpReceiver) {\n log(\"simulcast register receiver by ssrc\", packet.header.ssrc);\n this.registerRtpReceiver(rtpReceiver, packet.header.ssrc);\n rtpReceiver.handleRtpBySsrc(packet, extensions);\n } else {\n // bug\n }\n }\n\n if (!rtpReceiver) {\n log(\"ssrcReceiver not found\");\n return;\n }\n\n const sdesMid = extensions[RTP_EXTENSION_URI.sdesMid];\n if (typeof sdesMid === \"string\") {\n rtpReceiver.sdesMid = sdesMid;\n }\n\n const repairedRid = extensions[\n RTP_EXTENSION_URI.repairedRtpStreamId\n ] as string;\n if (typeof repairedRid === \"string\") {\n rtpReceiver.latestRepairedRid = repairedRid;\n }\n };\n\n routeRtcp = (packet: RtcpPacket) => {\n const recipients: (RTCRtpReceiver | RTCRtpSender)[] = [];\n\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n packet = packet as RtcpSrPacket;\n recipients.push(this.ssrcTable[packet.ssrc]);\n }\n break;\n case RtcpRrPacket.type:\n {\n packet = packet as RtcpRrPacket;\n packet.reports.forEach((report) => {\n recipients.push(this.ssrcTable[report.ssrc]);\n });\n }\n break;\n case RtcpSourceDescriptionPacket.type:\n {\n const sdes = packet as RtcpSourceDescriptionPacket;\n // log(\"sdes\", JSON.stringify(sdes.chunks));\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const rtpfb = packet as RtcpTransportLayerFeedback;\n if (rtpfb.feedback) {\n recipients.push(this.ssrcTable[rtpfb.feedback.mediaSourceSsrc]);\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const psfb = packet as RtcpPayloadSpecificFeedback;\n switch (psfb.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n const remb = psfb.feedback as ReceiverEstimatedMaxBitrate;\n recipients.push(this.ssrcTable[remb.ssrcFeedbacks[0]]);\n break;\n default:\n recipients.push(this.ssrcTable[psfb.feedback.senderSsrc]);\n }\n }\n break;\n }\n recipients\n .filter((v) => v) // todo simulcast\n .forEach((recipient) => recipient.handleRtcpPacket(packet));\n };\n}\n"]}
@@ -15,7 +15,7 @@ export declare class RTCRtpReceiver {
15
15
  private get codecArray();
16
16
  private readonly ssrcByRtx;
17
17
  private readonly nack;
18
- private readonly redHandler;
18
+ private readonly audioRedHandler;
19
19
  readonly type = "receiver";
20
20
  readonly uuid: string;
21
21
  readonly tracks: MediaStreamTrack[];
@@ -16,7 +16,6 @@ const utils_1 = require("../utils");
16
16
  const rtpExtension_1 = require("./extension/rtpExtension");
17
17
  const nack_1 = require("./receiver/nack");
18
18
  const receiverTwcc_1 = require("./receiver/receiverTwcc");
19
- const red_1 = require("./receiver/red");
20
19
  const statistics_1 = require("./receiver/statistics");
21
20
  const log = (0, debug_1.debug)("werift:packages/webrtc/src/media/rtpReceiver.ts");
22
21
  class RTCRtpReceiver {
@@ -27,7 +26,7 @@ class RTCRtpReceiver {
27
26
  this.codecs = {};
28
27
  this.ssrcByRtx = {};
29
28
  this.nack = new nack_1.NackHandler(this);
30
- this.redHandler = new red_1.AudioRedHandler();
29
+ this.audioRedHandler = new src_2.RedHandler();
31
30
  this.type = "receiver";
32
31
  this.uuid = (0, uuid_1.v4)();
33
32
  this.tracks = [];
@@ -96,18 +95,23 @@ class RTCRtpReceiver {
96
95
  }
97
96
  addTrack(track) {
98
97
  const exist = this.tracks.find((t) => {
99
- if (t.rid)
98
+ if (t.rid) {
100
99
  return t.rid === track.rid;
101
- if (t.ssrc)
100
+ }
101
+ if (t.ssrc) {
102
102
  return t.ssrc === track.ssrc;
103
+ }
103
104
  });
104
- if (exist)
105
+ if (exist) {
105
106
  return false;
107
+ }
106
108
  this.tracks.push(track);
107
- if (track.ssrc)
109
+ if (track.ssrc) {
108
110
  this.trackBySSRC[track.ssrc] = track;
109
- if (track.rid)
111
+ }
112
+ if (track.rid) {
110
113
  this.trackByRID[track.rid] = track;
114
+ }
111
115
  return true;
112
116
  }
113
117
  stop() {
@@ -199,8 +203,9 @@ class RTCRtpReceiver {
199
203
  this.onRtcp.execute(packet);
200
204
  }
201
205
  handleRTP(packet, extensions, track) {
202
- if (this.stopped)
206
+ if (this.stopped) {
203
207
  return;
208
+ }
204
209
  const codec = this.codecs[packet.header.payloadType];
205
210
  if (!codec) {
206
211
  // log("unknown codec " + packet.header.payloadType);
@@ -242,7 +247,7 @@ class RTCRtpReceiver {
242
247
  if (track) {
243
248
  if (red) {
244
249
  if (track.kind === "audio") {
245
- const payloads = this.redHandler.push(red, packet);
250
+ const payloads = this.audioRedHandler.push(red, packet);
246
251
  for (const packet of payloads) {
247
252
  track.onReceiveRtp.execute(packet.clone());
248
253
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rtpReceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpReceiver.ts"],"names":[],"mappings":"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","sourcesContent":["import { debug } from \"debug\";\nimport { jspack } from \"jspack\";\nimport Event from \"rx.mini\";\nimport { setTimeout } from \"timers/promises\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { int } from \"../../../common/src\";\nimport {\n PictureLossIndication,\n Red,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpReceiverInfo,\n RtcpRrPacket,\n RtcpSrPacket,\n RtpHeader,\n RtpPacket,\n} from \"../../../rtp/src\";\nimport { codecParametersFromString, PeerConfig, usePLI, useTWCC } from \"..\";\nimport { RTCDtlsTransport } from \"../transport/dtls\";\nimport { Kind } from \"../types/domain\";\nimport { compactNtp, timestampSeconds } from \"../utils\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport { RTCRtpCodecParameters, RTCRtpReceiveParameters } from \"./parameters\";\nimport { NackHandler } from \"./receiver/nack\";\nimport { ReceiverTWCC } from \"./receiver/receiverTwcc\";\nimport { AudioRedHandler } from \"./receiver/red\";\nimport { StreamStatistics } from \"./receiver/statistics\";\nimport { Extensions } from \"./router\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpReceiver.ts\");\n\nexport class RTCRtpReceiver {\n private readonly codecs: { [pt: number]: RTCRtpCodecParameters } = {};\n private get codecArray() {\n return Object.values(this.codecs).sort(\n (a, b) => a.payloadType - b.payloadType\n );\n }\n private readonly ssrcByRtx: { [rtxSsrc: number]: number } = {};\n private readonly nack = new NackHandler(this);\n private readonly redHandler = new AudioRedHandler();\n\n readonly type = \"receiver\";\n readonly uuid = uuid();\n readonly tracks: MediaStreamTrack[] = [];\n readonly trackBySSRC: { [ssrc: string]: MediaStreamTrack } = {};\n readonly trackByRID: { [rid: string]: MediaStreamTrack } = {};\n /**last sender Report Timestamp\n * compactNtp\n */\n readonly lastSRtimestamp: { [ssrc: number]: number } = {};\n /**seconds */\n readonly receiveLastSRTimestamp: { [ssrc: number]: number } = {};\n readonly onPacketLost = this.nack.onPacketLost;\n readonly onRtcp = new Event<[RtcpPacket]>();\n\n dtlsTransport!: RTCDtlsTransport;\n sdesMid?: string;\n latestRid?: string;\n latestRepairedRid?: string;\n\n receiverTWCC?: ReceiverTWCC;\n stopped = false;\n remoteStreamId?: string;\n remoteTrackId?: string;\n\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n private remoteStreams: { [ssrc: number]: StreamStatistics } = {};\n\n constructor(\n readonly config: PeerConfig,\n public kind: Kind,\n public rtcpSsrc: number\n ) {}\n\n setDtlsTransport(dtls: RTCDtlsTransport) {\n this.dtlsTransport = dtls;\n }\n\n // todo fix\n get track() {\n return this.tracks[0];\n }\n\n get nackEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find((f) => f.type === \"nack\");\n }\n\n get twccEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === useTWCC().type\n );\n }\n\n get pliEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === usePLI().type\n );\n }\n\n prepareReceive(params: RTCRtpReceiveParameters) {\n params.codecs.forEach((c) => {\n this.codecs[c.payloadType] = c;\n });\n params.encodings.forEach((e) => {\n if (e.rtx) {\n this.ssrcByRtx[e.rtx.ssrc] = e.ssrc;\n }\n });\n }\n\n /**\n * setup TWCC if supported\n */\n setupTWCC(mediaSourceSsrc: number) {\n if (this.twccEnabled && !this.receiverTWCC) {\n this.receiverTWCC = new ReceiverTWCC(\n this.dtlsTransport,\n this.rtcpSsrc,\n mediaSourceSsrc\n );\n }\n }\n\n addTrack(track: MediaStreamTrack) {\n const exist = this.tracks.find((t) => {\n if (t.rid) return t.rid === track.rid;\n if (t.ssrc) return t.ssrc === track.ssrc;\n });\n if (exist) return false;\n this.tracks.push(track);\n if (track.ssrc) this.trackBySSRC[track.ssrc] = track;\n if (track.rid) this.trackByRID[track.rid] = track;\n return true;\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n\n if (this.receiverTWCC) this.receiverTWCC.twccRunning = false;\n this.nack.close();\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const reports = Object.entries(this.remoteStreams).map(\n ([ssrc, stream]) => {\n let lastSRtimestamp = 0,\n delaySinceLastSR = 0;\n if (this.lastSRtimestamp[ssrc]) {\n lastSRtimestamp = this.lastSRtimestamp[ssrc];\n const delaySeconds =\n timestampSeconds() - this.receiveLastSRTimestamp[ssrc];\n if (delaySeconds > 0 && delaySeconds < 65536) {\n delaySinceLastSR = int(delaySeconds * 65536);\n }\n }\n\n return new RtcpReceiverInfo({\n ssrc: Number(ssrc),\n fractionLost: stream.fraction_lost,\n packetsLost: stream.packets_lost,\n highestSequence: stream.max_seq,\n jitter: stream.jitter,\n lsr: lastSRtimestamp,\n dlsr: delaySinceLastSR,\n });\n }\n );\n\n const packet = new RtcpRrPacket({ ssrc: this.rtcpSsrc, reports });\n\n try {\n if (this.config.debug.receiverReportDelay) {\n await setTimeout(this.config.debug.receiverReportDelay);\n }\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n /**todo impl */\n getStats() {}\n\n async sendRtcpPLI(mediaSsrc: number) {\n if (!this.pliEnabled) {\n log(\"pli not supported\", { mediaSsrc });\n return;\n }\n log(\"sendRtcpPLI\", { mediaSsrc });\n\n const packet = new RtcpPayloadSpecificFeedback({\n feedback: new PictureLossIndication({\n senderSsrc: this.rtcpSsrc,\n mediaSsrc,\n }),\n });\n try {\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(error);\n }\n }\n\n handleRtcpPacket(packet: RtcpPacket) {\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n const sr = packet as RtcpSrPacket;\n this.lastSRtimestamp[sr.ssrc] = compactNtp(\n sr.senderInfo.ntpTimestamp\n );\n this.receiveLastSRTimestamp[sr.ssrc] = timestampSeconds();\n\n const track = this.trackBySSRC[packet.ssrc];\n if (track) {\n track.onReceiveRtcp.execute(packet);\n }\n }\n break;\n }\n this.onRtcp.execute(packet);\n }\n\n handleRtpBySsrc = (packet: RtpPacket, extensions: Extensions) => {\n const track = this.trackBySSRC[packet.header.ssrc];\n\n this.handleRTP(packet, extensions, track);\n };\n\n handleRtpByRid = (packet: RtpPacket, rid: string, extensions: Extensions) => {\n const track = this.trackByRID[rid];\n if (!this.trackBySSRC[packet.header.ssrc]) {\n this.trackBySSRC[packet.header.ssrc] = track;\n }\n\n this.handleRTP(packet, extensions, track);\n };\n\n private handleRTP(\n packet: RtpPacket,\n extensions: Extensions,\n track?: MediaStreamTrack\n ) {\n if (this.stopped) return;\n\n const codec = this.codecs[packet.header.payloadType];\n if (!codec) {\n // log(\"unknown codec \" + packet.header.payloadType);\n return;\n }\n\n this.remoteStreams[packet.header.ssrc] =\n this.remoteStreams[packet.header.ssrc] ??\n new StreamStatistics(codec.clockRate);\n this.remoteStreams[packet.header.ssrc].add(packet);\n\n if (this.receiverTWCC) {\n const transportSequenceNumber = extensions[\n RTP_EXTENSION_URI.transportWideCC\n ] as number;\n if (!transportSequenceNumber == undefined) {\n throw new Error(\"undefined\");\n }\n\n this.receiverTWCC.handleTWCC(transportSequenceNumber);\n } else if (this.twccEnabled) {\n this.setupTWCC(packet.header.ssrc);\n }\n\n if (codec.name.toLowerCase() === \"rtx\") {\n const originalSsrc = this.ssrcByRtx[packet.header.ssrc];\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n const rtxCodec = this.codecs[codecParams[\"apt\"]];\n if (packet.payload.length < 2) return;\n\n packet = unwrapRtx(packet, rtxCodec.payloadType, originalSsrc);\n track = this.trackBySSRC[originalSsrc];\n }\n\n let red: Red | undefined;\n if (codec.name.toLowerCase() === \"red\") {\n red = Red.deSerialize(packet.payload);\n if (\n !Object.keys(this.codecs).includes(\n red.header.fields[0].blockPT.toString()\n )\n ) {\n return;\n }\n }\n\n if (track?.kind === \"video\" && this.nackEnabled) {\n this.nack.addPacket(packet);\n }\n\n if (track) {\n if (red) {\n if (track.kind === \"audio\") {\n const payloads = this.redHandler.push(red, packet);\n for (const packet of payloads) {\n track.onReceiveRtp.execute(packet.clone());\n }\n } else {\n }\n } else {\n track.onReceiveRtp.execute(packet.clone());\n }\n }\n\n this.runRtcp();\n }\n}\n\nexport function unwrapRtx(rtx: RtpPacket, payloadType: number, ssrc: number) {\n const packet = new RtpPacket(\n new RtpHeader({\n payloadType,\n marker: rtx.header.marker,\n sequenceNumber: jspack.Unpack(\"!H\", rtx.payload.subarray(0, 2))[0],\n timestamp: rtx.header.timestamp,\n ssrc,\n }),\n rtx.payload.subarray(2)\n );\n return packet;\n}\n"]}
1
+ {"version":3,"file":"rtpReceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpReceiver.ts"],"names":[],"mappings":"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","sourcesContent":["import { debug } from \"debug\";\nimport { jspack } from \"jspack\";\nimport Event from \"rx.mini\";\nimport { setTimeout } from \"timers/promises\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { int } from \"../../../common/src\";\nimport {\n PictureLossIndication,\n Red,\n RedHandler,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpReceiverInfo,\n RtcpRrPacket,\n RtcpSrPacket,\n RtpHeader,\n RtpPacket,\n} from \"../../../rtp/src\";\nimport { codecParametersFromString, PeerConfig, usePLI, useTWCC } from \"..\";\nimport { RTCDtlsTransport } from \"../transport/dtls\";\nimport { Kind } from \"../types/domain\";\nimport { compactNtp, timestampSeconds } from \"../utils\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport { RTCRtpCodecParameters, RTCRtpReceiveParameters } from \"./parameters\";\nimport { NackHandler } from \"./receiver/nack\";\nimport { ReceiverTWCC } from \"./receiver/receiverTwcc\";\nimport { StreamStatistics } from \"./receiver/statistics\";\nimport { Extensions } from \"./router\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpReceiver.ts\");\n\nexport class RTCRtpReceiver {\n private readonly codecs: { [pt: number]: RTCRtpCodecParameters } = {};\n private get codecArray() {\n return Object.values(this.codecs).sort(\n (a, b) => a.payloadType - b.payloadType\n );\n }\n private readonly ssrcByRtx: { [rtxSsrc: number]: number } = {};\n private readonly nack = new NackHandler(this);\n private readonly audioRedHandler = new RedHandler();\n\n readonly type = \"receiver\";\n readonly uuid = uuid();\n readonly tracks: MediaStreamTrack[] = [];\n readonly trackBySSRC: { [ssrc: string]: MediaStreamTrack } = {};\n readonly trackByRID: { [rid: string]: MediaStreamTrack } = {};\n /**last sender Report Timestamp\n * compactNtp\n */\n readonly lastSRtimestamp: { [ssrc: number]: number } = {};\n /**seconds */\n readonly receiveLastSRTimestamp: { [ssrc: number]: number } = {};\n readonly onPacketLost = this.nack.onPacketLost;\n readonly onRtcp = new Event<[RtcpPacket]>();\n\n dtlsTransport!: RTCDtlsTransport;\n sdesMid?: string;\n latestRid?: string;\n latestRepairedRid?: string;\n\n receiverTWCC?: ReceiverTWCC;\n stopped = false;\n remoteStreamId?: string;\n remoteTrackId?: string;\n\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n private remoteStreams: { [ssrc: number]: StreamStatistics } = {};\n\n constructor(\n readonly config: PeerConfig,\n public kind: Kind,\n public rtcpSsrc: number\n ) {}\n\n setDtlsTransport(dtls: RTCDtlsTransport) {\n this.dtlsTransport = dtls;\n }\n\n // todo fix\n get track() {\n return this.tracks[0];\n }\n\n get nackEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find((f) => f.type === \"nack\");\n }\n\n get twccEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === useTWCC().type\n );\n }\n\n get pliEnabled() {\n return this.codecArray[0]?.rtcpFeedback.find(\n (f) => f.type === usePLI().type\n );\n }\n\n prepareReceive(params: RTCRtpReceiveParameters) {\n params.codecs.forEach((c) => {\n this.codecs[c.payloadType] = c;\n });\n params.encodings.forEach((e) => {\n if (e.rtx) {\n this.ssrcByRtx[e.rtx.ssrc] = e.ssrc;\n }\n });\n }\n\n /**\n * setup TWCC if supported\n */\n setupTWCC(mediaSourceSsrc: number) {\n if (this.twccEnabled && !this.receiverTWCC) {\n this.receiverTWCC = new ReceiverTWCC(\n this.dtlsTransport,\n this.rtcpSsrc,\n mediaSourceSsrc\n );\n }\n }\n\n addTrack(track: MediaStreamTrack) {\n const exist = this.tracks.find((t) => {\n if (t.rid) {\n return t.rid === track.rid;\n }\n if (t.ssrc) {\n return t.ssrc === track.ssrc;\n }\n });\n if (exist) {\n return false;\n }\n this.tracks.push(track);\n if (track.ssrc) {\n this.trackBySSRC[track.ssrc] = track;\n }\n if (track.rid) {\n this.trackByRID[track.rid] = track;\n }\n return true;\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n\n if (this.receiverTWCC) this.receiverTWCC.twccRunning = false;\n this.nack.close();\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const reports = Object.entries(this.remoteStreams).map(\n ([ssrc, stream]) => {\n let lastSRtimestamp = 0,\n delaySinceLastSR = 0;\n if (this.lastSRtimestamp[ssrc]) {\n lastSRtimestamp = this.lastSRtimestamp[ssrc];\n const delaySeconds =\n timestampSeconds() - this.receiveLastSRTimestamp[ssrc];\n if (delaySeconds > 0 && delaySeconds < 65536) {\n delaySinceLastSR = int(delaySeconds * 65536);\n }\n }\n\n return new RtcpReceiverInfo({\n ssrc: Number(ssrc),\n fractionLost: stream.fraction_lost,\n packetsLost: stream.packets_lost,\n highestSequence: stream.max_seq,\n jitter: stream.jitter,\n lsr: lastSRtimestamp,\n dlsr: delaySinceLastSR,\n });\n }\n );\n\n const packet = new RtcpRrPacket({ ssrc: this.rtcpSsrc, reports });\n\n try {\n if (this.config.debug.receiverReportDelay) {\n await setTimeout(this.config.debug.receiverReportDelay);\n }\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n /**todo impl */\n getStats() {}\n\n async sendRtcpPLI(mediaSsrc: number) {\n if (!this.pliEnabled) {\n log(\"pli not supported\", { mediaSsrc });\n return;\n }\n log(\"sendRtcpPLI\", { mediaSsrc });\n\n const packet = new RtcpPayloadSpecificFeedback({\n feedback: new PictureLossIndication({\n senderSsrc: this.rtcpSsrc,\n mediaSsrc,\n }),\n });\n try {\n await this.dtlsTransport.sendRtcp([packet]);\n } catch (error) {\n log(error);\n }\n }\n\n handleRtcpPacket(packet: RtcpPacket) {\n switch (packet.type) {\n case RtcpSrPacket.type:\n {\n const sr = packet as RtcpSrPacket;\n this.lastSRtimestamp[sr.ssrc] = compactNtp(\n sr.senderInfo.ntpTimestamp\n );\n this.receiveLastSRTimestamp[sr.ssrc] = timestampSeconds();\n\n const track = this.trackBySSRC[packet.ssrc];\n if (track) {\n track.onReceiveRtcp.execute(packet);\n }\n }\n break;\n }\n this.onRtcp.execute(packet);\n }\n\n handleRtpBySsrc = (packet: RtpPacket, extensions: Extensions) => {\n const track = this.trackBySSRC[packet.header.ssrc];\n\n this.handleRTP(packet, extensions, track);\n };\n\n handleRtpByRid = (packet: RtpPacket, rid: string, extensions: Extensions) => {\n const track = this.trackByRID[rid];\n if (!this.trackBySSRC[packet.header.ssrc]) {\n this.trackBySSRC[packet.header.ssrc] = track;\n }\n\n this.handleRTP(packet, extensions, track);\n };\n\n private handleRTP(\n packet: RtpPacket,\n extensions: Extensions,\n track?: MediaStreamTrack\n ) {\n if (this.stopped) {\n return;\n }\n\n const codec = this.codecs[packet.header.payloadType];\n if (!codec) {\n // log(\"unknown codec \" + packet.header.payloadType);\n return;\n }\n\n this.remoteStreams[packet.header.ssrc] =\n this.remoteStreams[packet.header.ssrc] ??\n new StreamStatistics(codec.clockRate);\n this.remoteStreams[packet.header.ssrc].add(packet);\n\n if (this.receiverTWCC) {\n const transportSequenceNumber = extensions[\n RTP_EXTENSION_URI.transportWideCC\n ] as number;\n if (!transportSequenceNumber == undefined) {\n throw new Error(\"undefined\");\n }\n\n this.receiverTWCC.handleTWCC(transportSequenceNumber);\n } else if (this.twccEnabled) {\n this.setupTWCC(packet.header.ssrc);\n }\n\n if (codec.name.toLowerCase() === \"rtx\") {\n const originalSsrc = this.ssrcByRtx[packet.header.ssrc];\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n const rtxCodec = this.codecs[codecParams[\"apt\"]];\n if (packet.payload.length < 2) return;\n\n packet = unwrapRtx(packet, rtxCodec.payloadType, originalSsrc);\n track = this.trackBySSRC[originalSsrc];\n }\n\n let red: Red | undefined;\n if (codec.name.toLowerCase() === \"red\") {\n red = Red.deSerialize(packet.payload);\n if (\n !Object.keys(this.codecs).includes(\n red.header.fields[0].blockPT.toString()\n )\n ) {\n return;\n }\n }\n\n if (track?.kind === \"video\" && this.nackEnabled) {\n this.nack.addPacket(packet);\n }\n\n if (track) {\n if (red) {\n if (track.kind === \"audio\") {\n const payloads = this.audioRedHandler.push(red, packet);\n for (const packet of payloads) {\n track.onReceiveRtp.execute(packet.clone());\n }\n } else {\n }\n } else {\n track.onReceiveRtp.execute(packet.clone());\n }\n }\n\n this.runRtcp();\n }\n}\n\nexport function unwrapRtx(rtx: RtpPacket, payloadType: number, ssrc: number) {\n const packet = new RtpPacket(\n new RtpHeader({\n payloadType,\n marker: rtx.header.marker,\n sequenceNumber: jspack.Unpack(\"!H\", rtx.payload.subarray(0, 2))[0],\n timestamp: rtx.header.timestamp,\n ssrc,\n }),\n rtx.payload.subarray(2)\n );\n return packet;\n}\n"]}
@@ -10,16 +10,14 @@ export declare class RTCRtpTransceiver {
10
10
  receiver: RTCRtpReceiver;
11
11
  sender: RTCRtpSender;
12
12
  /**RFC 8829 4.2.4. direction the transceiver was initialized with */
13
- direction: Direction;
14
- readonly uuid: string;
13
+ private _direction;
14
+ readonly id: string;
15
15
  readonly onTrack: Event<[MediaStreamTrack, RTCRtpTransceiver]>;
16
16
  mid?: string;
17
17
  mLineIndex?: number;
18
+ /**should not be reused because it has been used for sending before. */
18
19
  usedForSender: boolean;
19
20
  private _currentDirection?;
20
- set currentDirection(direction: Direction | "stopped" | undefined);
21
- /**RFC 8829 4.2.5. last negotiated direction */
22
- get currentDirection(): Direction | "stopped" | undefined;
23
21
  offerDirection: Direction;
24
22
  _codecs: RTCRtpCodecParameters[];
25
23
  set codecs(codecs: RTCRtpCodecParameters[]);
@@ -30,8 +28,14 @@ export declare class RTCRtpTransceiver {
30
28
  stopped: boolean;
31
29
  constructor(kind: Kind, dtlsTransport: RTCDtlsTransport, receiver: RTCRtpReceiver, sender: RTCRtpSender,
32
30
  /**RFC 8829 4.2.4. direction the transceiver was initialized with */
33
- direction: Direction);
31
+ _direction: Direction);
34
32
  get dtlsTransport(): RTCDtlsTransport;
33
+ /**RFC 8829 4.2.4. setDirectionに渡された最後の値を示します */
34
+ get direction(): "inactive" | "sendonly" | "recvonly" | "sendrecv";
35
+ setDirection(direction: Direction): void;
36
+ /**RFC 8829 4.2.5. last negotiated direction */
37
+ get currentDirection(): Direction | undefined;
38
+ setCurrentDirection(direction: Direction | undefined): void;
35
39
  setDtlsTransport(dtls: RTCDtlsTransport): void;
36
40
  get msid(): string;
37
41
  addTrack(track: MediaStreamTrack): void;
@@ -33,13 +33,14 @@ const const_1 = require("../const");
33
33
  class RTCRtpTransceiver {
34
34
  constructor(kind, dtlsTransport, receiver, sender,
35
35
  /**RFC 8829 4.2.4. direction the transceiver was initialized with */
36
- direction) {
36
+ _direction) {
37
37
  this.kind = kind;
38
38
  this.receiver = receiver;
39
39
  this.sender = sender;
40
- this.direction = direction;
41
- this.uuid = uuid.v4();
40
+ this._direction = _direction;
41
+ this.id = uuid.v4();
42
42
  this.onTrack = new rx_mini_1.default();
43
+ /**should not be reused because it has been used for sending before. */
43
44
  this.usedForSender = false;
44
45
  this._codecs = [];
45
46
  this.headerExtensions = [];
@@ -48,16 +49,6 @@ class RTCRtpTransceiver {
48
49
  this.stopped = false;
49
50
  this.setDtlsTransport(dtlsTransport);
50
51
  }
51
- set currentDirection(direction) {
52
- this._currentDirection = direction;
53
- if (const_1.SenderDirections.includes(this._currentDirection || "")) {
54
- this.usedForSender = true;
55
- }
56
- }
57
- /**RFC 8829 4.2.5. last negotiated direction */
58
- get currentDirection() {
59
- return this._currentDirection;
60
- }
61
52
  set codecs(codecs) {
62
53
  this._codecs = codecs;
63
54
  }
@@ -67,6 +58,23 @@ class RTCRtpTransceiver {
67
58
  get dtlsTransport() {
68
59
  return this.receiver.dtlsTransport;
69
60
  }
61
+ /**RFC 8829 4.2.4. setDirectionに渡された最後の値を示します */
62
+ get direction() {
63
+ return this._direction;
64
+ }
65
+ setDirection(direction) {
66
+ this._direction = direction;
67
+ if (const_1.SenderDirections.includes(this._currentDirection ?? "")) {
68
+ this.usedForSender = true;
69
+ }
70
+ }
71
+ /**RFC 8829 4.2.5. last negotiated direction */
72
+ get currentDirection() {
73
+ return this._currentDirection;
74
+ }
75
+ setCurrentDirection(direction) {
76
+ this._currentDirection = direction;
77
+ }
70
78
  setDtlsTransport(dtls) {
71
79
  this.receiver.setDtlsTransport(dtls);
72
80
  this.sender.setDtlsTransport(dtls);
@@ -83,8 +91,9 @@ class RTCRtpTransceiver {
83
91
  // todo impl
84
92
  // https://www.w3.org/TR/webrtc/#methods-8
85
93
  stop() {
86
- if (this.stopping)
94
+ if (this.stopping) {
87
95
  return;
96
+ }
88
97
  // todo Stop sending and receiving with transceiver.
89
98
  this.stopping = true;
90
99
  }