werift 0.15.10 → 0.16.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 (164) hide show
  1. package/lib/common/src/index.d.ts +2 -0
  2. package/lib/common/src/index.js +2 -0
  3. package/lib/common/src/index.js.map +1 -1
  4. package/lib/common/src/log.d.ts +11 -0
  5. package/lib/common/src/log.js +17 -0
  6. package/lib/common/src/log.js.map +1 -0
  7. package/lib/common/src/network.d.ts +7 -3
  8. package/lib/common/src/network.js +15 -7
  9. package/lib/common/src/network.js.map +1 -1
  10. package/lib/common/src/type.d.ts +3 -0
  11. package/lib/common/src/type.js +3 -0
  12. package/lib/common/src/type.js.map +1 -0
  13. package/lib/dtls/src/context/cipher.js.map +1 -1
  14. package/lib/dtls/src/flight/server/flight2.js +10 -0
  15. package/lib/dtls/src/flight/server/flight2.js.map +1 -1
  16. package/lib/ice/src/ice.d.ts +3 -0
  17. package/lib/ice/src/ice.js +9 -2
  18. package/lib/ice/src/ice.js.map +1 -1
  19. package/lib/ice/src/stun/protocol.d.ts +2 -1
  20. package/lib/ice/src/stun/protocol.js +3 -3
  21. package/lib/ice/src/stun/protocol.js.map +1 -1
  22. package/lib/ice/src/transport.d.ts +4 -2
  23. package/lib/ice/src/transport.js +8 -6
  24. package/lib/ice/src/transport.js.map +1 -1
  25. package/lib/ice/src/turn/protocol.d.ts +3 -1
  26. package/lib/ice/src/turn/protocol.js +2 -2
  27. package/lib/ice/src/turn/protocol.js.map +1 -1
  28. package/lib/ice/src/utils.d.ts +2 -1
  29. package/lib/ice/src/utils.js +2 -2
  30. package/lib/ice/src/utils.js.map +1 -1
  31. package/lib/rtp/src/codec/index.d.ts +18 -0
  32. package/lib/rtp/src/codec/index.js +81 -0
  33. package/lib/rtp/src/codec/index.js.map +1 -0
  34. package/lib/rtp/src/codec/vp8.d.ts +5 -3
  35. package/lib/rtp/src/codec/vp8.js +19 -5
  36. package/lib/rtp/src/codec/vp8.js.map +1 -1
  37. package/lib/rtp/src/container/webm.d.ts +6 -1
  38. package/lib/rtp/src/container/webm.js +9 -2
  39. package/lib/rtp/src/container/webm.js.map +1 -1
  40. package/lib/rtp/src/index.d.ts +2 -6
  41. package/lib/rtp/src/index.js +2 -6
  42. package/lib/rtp/src/index.js.map +1 -1
  43. package/lib/rtp/src/processor/base.d.ts +3 -1
  44. package/lib/rtp/src/processor/base.js +19 -6
  45. package/lib/rtp/src/processor/base.js.map +1 -1
  46. package/lib/rtp/src/processor/jitterBuffer.js +1 -2
  47. package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
  48. package/lib/rtp/src/processor/lipsync.js +22 -2
  49. package/lib/rtp/src/processor/lipsync.js.map +1 -1
  50. package/lib/rtp/src/processor/webm.d.ts +11 -7
  51. package/lib/rtp/src/processor/webm.js +16 -41
  52. package/lib/rtp/src/processor/webm.js.map +1 -1
  53. package/lib/rtp/src/processor_v2/depacketizer.d.ts +17 -0
  54. package/lib/rtp/src/processor_v2/depacketizer.js +84 -0
  55. package/lib/rtp/src/processor_v2/depacketizer.js.map +1 -0
  56. package/lib/rtp/src/processor_v2/index.d.ts +4 -0
  57. package/lib/rtp/src/processor_v2/index.js +21 -0
  58. package/lib/rtp/src/processor_v2/index.js.map +1 -0
  59. package/lib/rtp/src/processor_v2/jitterBuffer.d.ts +33 -0
  60. package/lib/rtp/src/processor_v2/jitterBuffer.js +154 -0
  61. package/lib/rtp/src/processor_v2/jitterBuffer.js.map +1 -0
  62. package/lib/rtp/src/processor_v2/source/base.d.ts +8 -0
  63. package/lib/rtp/src/processor_v2/source/base.js +16 -0
  64. package/lib/rtp/src/processor_v2/source/base.js.map +1 -0
  65. package/lib/rtp/src/processor_v2/source/index.d.ts +2 -0
  66. package/lib/rtp/src/processor_v2/source/index.js +6 -0
  67. package/lib/rtp/src/processor_v2/source/index.js.map +1 -0
  68. package/lib/rtp/src/processor_v2/source/rtp.d.ts +14 -0
  69. package/lib/rtp/src/processor_v2/source/rtp.js +24 -0
  70. package/lib/rtp/src/processor_v2/source/rtp.js.map +1 -0
  71. package/lib/rtp/src/processor_v2/webmLive.d.ts +51 -0
  72. package/lib/rtp/src/processor_v2/webmLive.js +154 -0
  73. package/lib/rtp/src/processor_v2/webmLive.js.map +1 -0
  74. package/lib/rtp/src/rtcp/header.d.ts +2 -1
  75. package/lib/rtp/src/rtcp/header.js +3 -2
  76. package/lib/rtp/src/rtcp/header.js.map +1 -1
  77. package/lib/rtp/src/rtcp/rr.d.ts +2 -0
  78. package/lib/rtp/src/rtcp/rr.js.map +1 -1
  79. package/lib/rtp/src/rtcp/rtcp.js +4 -4
  80. package/lib/rtp/src/rtcp/rtcp.js.map +1 -1
  81. package/lib/rtp/src/rtcp/rtpfb/index.js +1 -1
  82. package/lib/rtp/src/rtcp/rtpfb/index.js.map +1 -1
  83. package/lib/rtp/src/rtcp/rtpfb/nack.js +15 -7
  84. package/lib/rtp/src/rtcp/rtpfb/nack.js.map +1 -1
  85. package/lib/rtp/src/rtp/red/packet.d.ts +1 -0
  86. package/lib/rtp/src/rtp/red/packet.js.map +1 -1
  87. package/lib/rtp/src/rtp/rtp.d.ts +1 -0
  88. package/lib/rtp/src/rtp/rtp.js +27 -26
  89. package/lib/rtp/src/rtp/rtp.js.map +1 -1
  90. package/lib/rtp/src/srtp/cipher/ctr.d.ts +1 -1
  91. package/lib/rtp/src/srtp/cipher/ctr.js +14 -20
  92. package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
  93. package/lib/webrtc/src/dataChannel.js +1 -1
  94. package/lib/webrtc/src/dataChannel.js.map +1 -1
  95. package/lib/webrtc/src/media/extension/rtpExtension.d.ts +2 -0
  96. package/lib/webrtc/src/media/extension/rtpExtension.js +8 -1
  97. package/lib/webrtc/src/media/extension/rtpExtension.js.map +1 -1
  98. package/lib/webrtc/src/media/parameters.d.ts +2 -0
  99. package/lib/webrtc/src/media/parameters.js +1 -0
  100. package/lib/webrtc/src/media/parameters.js.map +1 -1
  101. package/lib/webrtc/src/media/receiver/nack.d.ts +10 -5
  102. package/lib/webrtc/src/media/receiver/nack.js +44 -27
  103. package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
  104. package/lib/webrtc/src/media/receiver/receiverTwcc.js +1 -1
  105. package/lib/webrtc/src/media/receiver/receiverTwcc.js.map +1 -1
  106. package/lib/webrtc/src/media/receiver/red.d.ts +1 -1
  107. package/lib/webrtc/src/media/receiver/red.js +14 -3
  108. package/lib/webrtc/src/media/receiver/red.js.map +1 -1
  109. package/lib/webrtc/src/media/router.d.ts +10 -3
  110. package/lib/webrtc/src/media/router.js +2 -0
  111. package/lib/webrtc/src/media/router.js.map +1 -1
  112. package/lib/webrtc/src/media/rtpReceiver.d.ts +11 -3
  113. package/lib/webrtc/src/media/rtpReceiver.js +42 -23
  114. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  115. package/lib/webrtc/src/media/rtpSender.d.ts +23 -2
  116. package/lib/webrtc/src/media/rtpSender.js +34 -10
  117. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  118. package/lib/webrtc/src/media/rtpTransceiver.d.ts +5 -1
  119. package/lib/webrtc/src/media/rtpTransceiver.js +9 -9
  120. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  121. package/lib/webrtc/src/media/track.js +4 -2
  122. package/lib/webrtc/src/media/track.js.map +1 -1
  123. package/lib/webrtc/src/nonstandard/recorder/index.d.ts +5 -1
  124. package/lib/webrtc/src/nonstandard/recorder/index.js +2 -2
  125. package/lib/webrtc/src/nonstandard/recorder/index.js.map +1 -1
  126. package/lib/webrtc/src/nonstandard/recorder/writer/index.d.ts +1 -1
  127. package/lib/webrtc/src/nonstandard/recorder/writer/index.js +1 -1
  128. package/lib/webrtc/src/nonstandard/recorder/writer/index.js.map +1 -1
  129. package/lib/webrtc/src/nonstandard/recorder/writer/webm.d.ts +3 -3
  130. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +61 -41
  131. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  132. package/lib/webrtc/src/peerConnection.d.ts +13 -0
  133. package/lib/webrtc/src/peerConnection.js +40 -3
  134. package/lib/webrtc/src/peerConnection.js.map +1 -1
  135. package/lib/webrtc/src/sdp.d.ts +1 -0
  136. package/lib/webrtc/src/sdp.js +4 -0
  137. package/lib/webrtc/src/sdp.js.map +1 -1
  138. package/lib/webrtc/src/transport/dtls.js +6 -1
  139. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  140. package/lib/webrtc/src/transport/sctp.js +1 -1
  141. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  142. package/lib/webrtc/src/utils.d.ts +7 -2
  143. package/lib/webrtc/src/utils.js +9 -3
  144. package/lib/webrtc/src/utils.js.map +1 -1
  145. package/package.json +2 -2
  146. package/src/dataChannel.ts +1 -1
  147. package/src/media/extension/rtpExtension.ts +8 -0
  148. package/src/media/parameters.ts +3 -0
  149. package/src/media/receiver/nack.ts +45 -26
  150. package/src/media/receiver/receiverTwcc.ts +1 -1
  151. package/src/media/receiver/red.ts +14 -1
  152. package/src/media/router.ts +5 -3
  153. package/src/media/rtpReceiver.ts +59 -28
  154. package/src/media/rtpSender.ts +38 -12
  155. package/src/media/rtpTransceiver.ts +10 -8
  156. package/src/media/track.ts +6 -2
  157. package/src/nonstandard/recorder/index.ts +6 -2
  158. package/src/nonstandard/recorder/writer/index.ts +1 -1
  159. package/src/nonstandard/recorder/writer/webm.ts +105 -57
  160. package/src/peerConnection.ts +61 -7
  161. package/src/sdp.ts +3 -0
  162. package/src/transport/dtls.ts +5 -1
  163. package/src/transport/sctp.ts +1 -1
  164. package/src/utils.ts +8 -2
@@ -3,22 +3,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Nack = void 0;
6
+ exports.NackHandler = void 0;
7
+ const debug_1 = __importDefault(require("debug"));
7
8
  const range_1 = __importDefault(require("lodash/range"));
8
9
  const rx_mini_1 = __importDefault(require("rx.mini"));
9
10
  const src_1 = require("../../../../common/src");
10
11
  const src_2 = require("../../../../rtp/src");
12
+ const log = (0, debug_1.default)("werift:packages/webrtc/src/media/receiver/nack.ts");
11
13
  const LOST_SIZE = 30 * 5;
12
- class Nack {
14
+ class NackHandler {
13
15
  constructor(receiver) {
14
16
  this.receiver = receiver;
15
17
  this.newEstSeqNum = 0;
16
- this._lost = {};
17
- this.nackLoop = setInterval(() => this.packetLost(), 20);
18
+ this.lost = {};
19
+ this.nackLoop = setInterval(() => this.sendNack(), 20);
18
20
  this.onPacketLost = new rx_mini_1.default();
21
+ this.retryCount = 10;
19
22
  }
20
- get lost() {
21
- return Object.keys(this._lost).map(Number);
23
+ get lostNumber() {
24
+ return Object.keys(this.lost).map(Number);
25
+ }
26
+ removeLost(sequenceNumber) {
27
+ delete this.lost[sequenceNumber];
22
28
  }
23
29
  addPacket(packet) {
24
30
  const { sequenceNumber, ssrc } = packet.header;
@@ -27,8 +33,8 @@ class Nack {
27
33
  this.newEstSeqNum = sequenceNumber;
28
34
  return;
29
35
  }
30
- if (this._lost[sequenceNumber]) {
31
- delete this._lost[sequenceNumber];
36
+ if (this.lost[sequenceNumber]) {
37
+ this.removeLost(sequenceNumber);
32
38
  return;
33
39
  }
34
40
  if (sequenceNumber === (0, src_1.uint16Add)(this.newEstSeqNum, 1)) {
@@ -37,45 +43,56 @@ class Nack {
37
43
  else if (sequenceNumber > (0, src_1.uint16Add)(this.newEstSeqNum, 1)) {
38
44
  // packet lost detected
39
45
  (0, range_1.default)((0, src_1.uint16Add)(this.newEstSeqNum, 1), sequenceNumber).forEach((seq) => {
40
- this._lost[seq] = 1;
46
+ this.lost[seq] = 1;
41
47
  });
42
48
  this.receiver.sendRtcpPLI(this.mediaSourceSsrc);
43
49
  this.newEstSeqNum = sequenceNumber;
44
- if (Object.keys(this._lost).length > LOST_SIZE) {
45
- this._lost = Object.entries(this._lost)
46
- .slice(-LOST_SIZE)
47
- .reduce((acc, [key, v]) => {
48
- acc[key] = v;
49
- return acc;
50
- }, {});
51
- }
50
+ this.pruneLost();
51
+ }
52
+ }
53
+ pruneLost() {
54
+ if (Object.keys(this.lost).length > LOST_SIZE) {
55
+ this.lost = Object.entries(this.lost)
56
+ .slice(-LOST_SIZE)
57
+ .reduce((acc, [key, v]) => {
58
+ acc[key] = v;
59
+ return acc;
60
+ }, {});
52
61
  }
53
62
  }
54
63
  close() {
55
64
  clearInterval(this.nackLoop);
65
+ this.lost = {};
56
66
  }
57
- increment() {
58
- Object.keys(this._lost).forEach((seq) => {
59
- if (++this._lost[seq] > 10) {
60
- delete this._lost[seq];
67
+ updateRetryCount() {
68
+ const res = Object.keys(this.lost)
69
+ .map((seq) => {
70
+ const count = this.lost[seq]++;
71
+ if (count > this.retryCount) {
72
+ delete this.lost[seq];
73
+ return seq;
61
74
  }
62
- });
75
+ })
76
+ .filter((v) => v != undefined);
77
+ if (res.length > 0) {
78
+ // log("failed to retransmit", res);
79
+ }
63
80
  }
64
- packetLost() {
65
- if (this.lost.length > 0 && this.mediaSourceSsrc) {
81
+ sendNack() {
82
+ if (this.lostNumber.length > 0 && this.mediaSourceSsrc) {
66
83
  const nack = new src_2.GenericNack({
67
84
  senderSsrc: this.receiver.rtcpSsrc,
68
85
  mediaSourceSsrc: this.mediaSourceSsrc,
69
- lost: this.lost,
86
+ lost: this.lostNumber,
70
87
  });
71
88
  const rtcp = new src_2.RtcpTransportLayerFeedback({
72
89
  feedback: nack,
73
90
  });
74
91
  this.receiver.dtlsTransport.sendRtcp([rtcp]);
75
- this.increment();
92
+ this.updateRetryCount();
76
93
  this.onPacketLost.execute(nack);
77
94
  }
78
95
  }
79
96
  }
80
- exports.Nack = Nack;
97
+ exports.NackHandler = NackHandler;
81
98
  //# 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 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 LOST_SIZE = 30 * 5;\n\nexport class Nack {\n private newEstSeqNum = 0;\n private _lost: { [seqNum: number]: number } = {};\n private nackLoop = setInterval(() => this.packetLost(), 20);\n\n readonly onPacketLost = new Event<[GenericNack]>();\n mediaSourceSsrc?: number;\n\n constructor(private receiver: RTCRtpReceiver) {}\n\n get lost() {\n return Object.keys(this._lost).map(Number);\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._lost[sequenceNumber]) {\n delete this._lost[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._lost[seq] = 1;\n });\n this.receiver.sendRtcpPLI(this.mediaSourceSsrc);\n\n this.newEstSeqNum = sequenceNumber;\n\n if (Object.keys(this._lost).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\n close() {\n clearInterval(this.nackLoop);\n }\n\n private increment() {\n Object.keys(this._lost).forEach((seq) => {\n if (++this._lost[seq] > 10) {\n delete this._lost[seq];\n }\n });\n }\n\n private packetLost() {\n if (this.lost.length > 0 && this.mediaSourceSsrc) {\n const nack = new GenericNack({\n senderSsrc: this.receiver.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lost,\n });\n const rtcp = new RtcpTransportLayerFeedback({\n feedback: nack,\n });\n this.receiver.dtlsTransport.sendRtcp([rtcp]);\n\n this.increment();\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 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 lostNumber() {\n return Object.keys(this.lost).map(Number);\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.lost[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.lost[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 (Object.keys(this.lost).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 const res = Object.keys(this.lost)\n .map((seq) => {\n const count = this.lost[seq]++;\n if (count > this.retryCount) {\n delete this.lost[seq];\n return seq;\n }\n })\n .filter((v) => v != undefined);\n if (res.length > 0) {\n // log(\"failed to retransmit\", res);\n }\n }\n\n private sendNack() {\n if (this.lostNumber.length > 0 && this.mediaSourceSsrc) {\n const nack = new GenericNack({\n senderSsrc: this.receiver.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lostNumber,\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"]}
@@ -9,7 +9,7 @@ const promises_1 = require("timers/promises");
9
9
  const src_1 = require("../../../../common/src");
10
10
  const src_2 = require("../../../../rtp/src");
11
11
  const utils_1 = require("../../utils");
12
- const log = (0, debug_1.default)("werift/webrtc/media/receiver/receiverTwcc");
12
+ const log = (0, debug_1.default)("werift:packages/webrtc/media/receiver/receiverTwcc");
13
13
  class ReceiverTWCC {
14
14
  constructor(dtlsTransport, rtcpSsrc, mediaSourceSsrc) {
15
15
  this.dtlsTransport = dtlsTransport;
@@ -1 +1 @@
1
- {"version":3,"file":"receiverTwcc.js","sourceRoot":"","sources":["../../../../../src/media/receiver/receiverTwcc.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport { setTimeout } from \"timers/promises\";\n\nimport { uint8Add, uint16Add, uint24 } from \"../../../../common/src\";\nimport {\n PacketStatus,\n RecvDelta,\n RtcpTransportLayerFeedback,\n RunLengthChunk,\n StatusVectorChunk,\n TransportWideCC,\n} from \"../../../../rtp/src\";\nimport { RTCDtlsTransport } from \"../../transport/dtls\";\nimport { microTime } from \"../../utils\";\n\nconst log = debug(\"werift/webrtc/media/receiver/receiverTwcc\");\n\ntype ExtensionInfo = { tsn: number; timestamp: number };\n\nexport class ReceiverTWCC {\n extensionInfo: {\n [tsn: number]: ExtensionInfo;\n } = {};\n twccRunning = false;\n /** uint8 */\n fbPktCount = 0;\n lastTimestamp?: number;\n\n constructor(\n private dtlsTransport: RTCDtlsTransport,\n private rtcpSsrc: number,\n private mediaSourceSsrc: number\n ) {\n this.runTWCC();\n }\n\n handleTWCC(transportSequenceNumber: number) {\n this.extensionInfo[transportSequenceNumber] = {\n tsn: transportSequenceNumber,\n timestamp: microTime(),\n };\n\n if (Object.keys(this.extensionInfo).length > 10) {\n this.sendTWCC();\n }\n }\n\n private async runTWCC() {\n while (this.twccRunning) {\n this.sendTWCC();\n await setTimeout(100);\n }\n }\n\n private sendTWCC() {\n if (Object.keys(this.extensionInfo).length === 0) return;\n const extensionsArr = Object.values(this.extensionInfo).sort(\n (a, b) => a.tsn - b.tsn\n );\n\n const minTSN = extensionsArr[0].tsn;\n const maxTSN = extensionsArr.slice(-1)[0].tsn;\n\n const packetChunks: (RunLengthChunk | StatusVectorChunk)[] = [];\n const baseSequenceNumber = extensionsArr[0].tsn;\n const packetStatusCount = uint16Add(maxTSN - minTSN, 1);\n /**micro sec */\n let referenceTime!: number;\n let lastPacketStatus: { status: PacketStatus; minTSN: number } | undefined;\n const recvDeltas: RecvDelta[] = [];\n\n for (let i = minTSN; i <= maxTSN; i++) {\n /**micro sec */\n const timestamp = this.extensionInfo[i]?.timestamp;\n\n if (timestamp) {\n if (!this.lastTimestamp) {\n this.lastTimestamp = timestamp;\n }\n if (!referenceTime) {\n referenceTime = this.lastTimestamp;\n }\n\n const delta = timestamp - this.lastTimestamp;\n this.lastTimestamp = timestamp;\n\n const recvDelta = new RecvDelta({\n delta: Number(delta),\n });\n recvDelta.parseDelta();\n recvDeltas.push(recvDelta);\n\n // when status changed\n if (\n lastPacketStatus != undefined &&\n lastPacketStatus.status !== recvDelta.type\n ) {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: lastPacketStatus.status,\n runLength: i - lastPacketStatus.minTSN,\n })\n );\n lastPacketStatus = { minTSN: i, status: recvDelta.type! };\n }\n // last status\n if (i === maxTSN) {\n if (lastPacketStatus != undefined) {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: lastPacketStatus.status,\n runLength: i - lastPacketStatus.minTSN + 1,\n })\n );\n } else {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: recvDelta.type,\n runLength: 1,\n })\n );\n }\n }\n\n if (lastPacketStatus == undefined) {\n lastPacketStatus = { minTSN: i, status: recvDelta.type! };\n }\n }\n }\n\n if (!referenceTime) {\n return;\n }\n\n const packet = new RtcpTransportLayerFeedback({\n feedback: new TransportWideCC({\n senderSsrc: this.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n baseSequenceNumber,\n packetStatusCount,\n referenceTime: uint24(Math.floor(referenceTime / 1000 / 64)),\n fbPktCount: this.fbPktCount,\n recvDeltas,\n packetChunks,\n }),\n });\n\n this.dtlsTransport.sendRtcp([packet]).catch((err) => {\n log(err);\n });\n this.extensionInfo = {};\n this.fbPktCount = uint8Add(this.fbPktCount, 1);\n }\n}\n"]}
1
+ {"version":3,"file":"receiverTwcc.js","sourceRoot":"","sources":["../../../../../src/media/receiver/receiverTwcc.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport { setTimeout } from \"timers/promises\";\n\nimport { uint8Add, uint16Add, uint24 } from \"../../../../common/src\";\nimport {\n PacketStatus,\n RecvDelta,\n RtcpTransportLayerFeedback,\n RunLengthChunk,\n StatusVectorChunk,\n TransportWideCC,\n} from \"../../../../rtp/src\";\nimport { RTCDtlsTransport } from \"../../transport/dtls\";\nimport { microTime } from \"../../utils\";\n\nconst log = debug(\"werift:packages/webrtc/media/receiver/receiverTwcc\");\n\ntype ExtensionInfo = { tsn: number; timestamp: number };\n\nexport class ReceiverTWCC {\n extensionInfo: {\n [tsn: number]: ExtensionInfo;\n } = {};\n twccRunning = false;\n /** uint8 */\n fbPktCount = 0;\n lastTimestamp?: number;\n\n constructor(\n private dtlsTransport: RTCDtlsTransport,\n private rtcpSsrc: number,\n private mediaSourceSsrc: number\n ) {\n this.runTWCC();\n }\n\n handleTWCC(transportSequenceNumber: number) {\n this.extensionInfo[transportSequenceNumber] = {\n tsn: transportSequenceNumber,\n timestamp: microTime(),\n };\n\n if (Object.keys(this.extensionInfo).length > 10) {\n this.sendTWCC();\n }\n }\n\n private async runTWCC() {\n while (this.twccRunning) {\n this.sendTWCC();\n await setTimeout(100);\n }\n }\n\n private sendTWCC() {\n if (Object.keys(this.extensionInfo).length === 0) return;\n const extensionsArr = Object.values(this.extensionInfo).sort(\n (a, b) => a.tsn - b.tsn\n );\n\n const minTSN = extensionsArr[0].tsn;\n const maxTSN = extensionsArr.slice(-1)[0].tsn;\n\n const packetChunks: (RunLengthChunk | StatusVectorChunk)[] = [];\n const baseSequenceNumber = extensionsArr[0].tsn;\n const packetStatusCount = uint16Add(maxTSN - minTSN, 1);\n /**micro sec */\n let referenceTime!: number;\n let lastPacketStatus: { status: PacketStatus; minTSN: number } | undefined;\n const recvDeltas: RecvDelta[] = [];\n\n for (let i = minTSN; i <= maxTSN; i++) {\n /**micro sec */\n const timestamp = this.extensionInfo[i]?.timestamp;\n\n if (timestamp) {\n if (!this.lastTimestamp) {\n this.lastTimestamp = timestamp;\n }\n if (!referenceTime) {\n referenceTime = this.lastTimestamp;\n }\n\n const delta = timestamp - this.lastTimestamp;\n this.lastTimestamp = timestamp;\n\n const recvDelta = new RecvDelta({\n delta: Number(delta),\n });\n recvDelta.parseDelta();\n recvDeltas.push(recvDelta);\n\n // when status changed\n if (\n lastPacketStatus != undefined &&\n lastPacketStatus.status !== recvDelta.type\n ) {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: lastPacketStatus.status,\n runLength: i - lastPacketStatus.minTSN,\n })\n );\n lastPacketStatus = { minTSN: i, status: recvDelta.type! };\n }\n // last status\n if (i === maxTSN) {\n if (lastPacketStatus != undefined) {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: lastPacketStatus.status,\n runLength: i - lastPacketStatus.minTSN + 1,\n })\n );\n } else {\n packetChunks.push(\n new RunLengthChunk({\n packetStatus: recvDelta.type,\n runLength: 1,\n })\n );\n }\n }\n\n if (lastPacketStatus == undefined) {\n lastPacketStatus = { minTSN: i, status: recvDelta.type! };\n }\n }\n }\n\n if (!referenceTime) {\n return;\n }\n\n const packet = new RtcpTransportLayerFeedback({\n feedback: new TransportWideCC({\n senderSsrc: this.rtcpSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n baseSequenceNumber,\n packetStatusCount,\n referenceTime: uint24(Math.floor(referenceTime / 1000 / 64)),\n fbPktCount: this.fbPktCount,\n recvDeltas,\n packetChunks,\n }),\n });\n\n this.dtlsTransport.sendRtcp([packet]).catch((err) => {\n log(err);\n });\n this.extensionInfo = {};\n this.fbPktCount = uint8Add(this.fbPktCount, 1);\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { Red, RtpPacket } from "../..";
2
- export declare class RedHandler {
2
+ export declare class AudioRedHandler {
3
3
  private readonly size;
4
4
  private sequenceNumbers;
5
5
  push(red: Red, rtp: RtpPacket): RtpPacket[];
@@ -1,8 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RedHandler = void 0;
3
+ exports.AudioRedHandler = void 0;
4
4
  const __1 = require("../..");
5
- class RedHandler {
5
+ // 0 1 2 3
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
7
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
8
+ // |F| block PT | timestamp offset | block length |
9
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10
+ // 0 1 2 3 4 5 6 7
11
+ // +-+-+-+-+-+-+-+-+
12
+ // |0| Block PT |
13
+ // +-+-+-+-+-+-+-+-+
14
+ class AudioRedHandler {
6
15
  constructor() {
7
16
  this.size = 150;
8
17
  this.sequenceNumbers = [];
@@ -31,10 +40,12 @@ class RedHandler {
31
40
  }
32
41
  });
33
42
  const filtered = packets.filter((p) => {
43
+ // duplicate
34
44
  if (this.sequenceNumbers.includes(p.header.sequenceNumber)) {
35
45
  return false;
36
46
  }
37
47
  else {
48
+ // buffer overflow
38
49
  if (this.sequenceNumbers.length > this.size) {
39
50
  this.sequenceNumbers.shift();
40
51
  }
@@ -45,5 +56,5 @@ class RedHandler {
45
56
  return filtered;
46
57
  }
47
58
  }
48
- exports.RedHandler = RedHandler;
59
+ exports.AudioRedHandler = AudioRedHandler;
49
60
  //# sourceMappingURL=red.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"red.js","sourceRoot":"","sources":["../../../../../src/media/receiver/red.ts"],"names":[],"mappings":";;;AAAA,6BAAwE;AAExE,MAAa,UAAU;IAAvB;QACmB,SAAI,GAAG,GAAG,CAAC;QACpB,oBAAe,GAAa,EAAE,CAAC;IAoDzC,CAAC;IAlDC,IAAI,CAAC,GAAQ,EAAE,GAAc;QAC3B,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,GAAG,CAAC,MAAM,CAAC,cAAc,EACzB,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,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC;oBAC5D,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;oBACrB,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,GAAG,CAAC,MAAM,CAAC,SAAS;oBAC/B,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;oBACrB,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,IAAI,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;gBAC1D,OAAO,KAAK,CAAC;aACd;iBAAM;gBACL,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;AAtDD,gCAsDC","sourcesContent":["import { Red, RtpHeader, RtpPacket, uint16Add, uint32Add } from \"../..\";\n\nexport class RedHandler {\n private readonly size = 150;\n private sequenceNumbers: number[] = [];\n\n push(red: Red, rtp: RtpPacket) {\n const packets: RtpPacket[] = [];\n\n red.blocks.forEach(({ blockPT, timestampOffset, block }, i) => {\n const sequenceNumber = uint16Add(\n rtp.header.sequenceNumber,\n -(red.blocks.length - (i + 1))\n );\n if (timestampOffset) {\n packets.push(\n new RtpPacket(\n new RtpHeader({\n timestamp: uint32Add(rtp.header.timestamp, -timestampOffset),\n payloadType: blockPT,\n ssrc: rtp.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: rtp.header.timestamp,\n payloadType: blockPT,\n ssrc: rtp.header.ssrc,\n sequenceNumber,\n marker: true,\n }),\n block\n )\n );\n }\n });\n\n const filtered = packets.filter((p) => {\n if (this.sequenceNumbers.includes(p.header.sequenceNumber)) {\n return false;\n } else {\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"]}
1
+ {"version":3,"file":"red.js","sourceRoot":"","sources":["../../../../../src/media/receiver/red.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,eAAe;IAA5B;QACmB,SAAI,GAAG,GAAG,CAAC;QACpB,oBAAe,GAAa,EAAE,CAAC;IAsDzC,CAAC;IApDC,IAAI,CAAC,GAAQ,EAAE,GAAc;QAC3B,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,GAAG,CAAC,MAAM,CAAC,cAAc,EACzB,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,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC;oBAC5D,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;oBACrB,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,GAAG,CAAC,MAAM,CAAC,SAAS;oBAC/B,WAAW,EAAE,OAAO;oBACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI;oBACrB,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,0CAwDC","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 AudioRedHandler {\n private readonly size = 150;\n private sequenceNumbers: number[] = [];\n\n push(red: Red, rtp: RtpPacket) {\n const packets: RtpPacket[] = [];\n\n red.blocks.forEach(({ blockPT, timestampOffset, block }, i) => {\n const sequenceNumber = uint16Add(\n rtp.header.sequenceNumber,\n -(red.blocks.length - (i + 1))\n );\n if (timestampOffset) {\n packets.push(\n new RtpPacket(\n new RtpHeader({\n timestamp: uint32Add(rtp.header.timestamp, -timestampOffset),\n payloadType: blockPT,\n ssrc: rtp.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: rtp.header.timestamp,\n payloadType: blockPT,\n ssrc: rtp.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"]}
@@ -1,14 +1,21 @@
1
1
  import { Extension, RtcpPacket, RtpPacket } from "../../../rtp/src";
2
2
  import { RTCRtpReceiveParameters, RTCRtpSimulcastParameters } from "./parameters";
3
+ import { RTCRtpReceiver } from "./rtpReceiver";
3
4
  import { RTCRtpSender } from "./rtpSender";
4
5
  import { RTCRtpTransceiver } from "./rtpTransceiver";
5
6
  export declare type Extensions = {
6
7
  [uri: string]: number | string;
7
8
  };
8
9
  export declare class RtpRouter {
9
- private ssrcTable;
10
- private ridTable;
11
- private extIdUriMap;
10
+ ssrcTable: {
11
+ [ssrc: number]: RTCRtpReceiver | RTCRtpSender;
12
+ };
13
+ ridTable: {
14
+ [rid: string]: RTCRtpReceiver | RTCRtpSender;
15
+ };
16
+ extIdUriMap: {
17
+ [id: number]: string;
18
+ };
12
19
  constructor();
13
20
  registerRtpSender(sender: RTCRtpSender): void;
14
21
  private registerRtpReceiver;
@@ -158,6 +158,8 @@ class RtpRouter {
158
158
  uri,
159
159
  value: (0, src_1.bufferReader)(extension.payload, [3])[0],
160
160
  };
161
+ default:
162
+ return { uri, value: 0 };
161
163
  }
162
164
  })
163
165
  .reduce((acc, cur) => {
@@ -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 private ssrcTable: { [ssrc: number]: RTCRtpReceiver | RTCRtpSender } = {};\n private ridTable: { [rid: string]: RTCRtpReceiver | RTCRtpSender } = {};\n private 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 }\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":";;;;;;AAAA,kDAA0B;AAE1B,6CAAmD;AACnD,0CAU0B;AAC1B,2DAA6D;AAK7D,+CAA+C;AAG/C,mCAA2C;AAE3C,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,4CAA4C,CAAC,CAAC;AAIhE,MAAa,SAAS;IAKpB;QAJA,cAAS,GAAsD,EAAE,CAAC;QAClE,aAAQ,GAAqD,EAAE,CAAC;QAChE,gBAAW,GAA6B,EAAE,CAAC;QA2F3C,aAAQ,GAAG,CAAC,MAAiB,EAAE,EAAE;YAC/B,MAAM,UAAU,GAAG,SAAS,CAAC,yBAAyB,CACpD,MAAM,CAAC,MAAM,CAAC,UAAU,EACxB,IAAI,CAAC,WAAW,CACjB,CAAC;YAEF,IAAI,YAAY,GAA+B,IAAI,CAAC,SAAS,CAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,CACD,CAAC;YAEpB,MAAM,GAAG,GAAG,UAAU,CAAC,gCAAiB,CAAC,eAAe,CAAC,CAAC;YAC1D,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;gBAC3B,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAmB,CAAC;gBACpD,YAAY,CAAC,SAAS,GAAG,GAAG,CAAC;gBAC7B,YAAY,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;aACtD;iBAAM,IAAI,YAAY,EAAE;gBACvB,YAAY,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;aAClD;iBAAM;gBACL,uCAAuC;gBACvC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;qBACxC,MAAM,CAAC,CAAC,CAAC,EAAuB,EAAE,CAAC,CAAC,YAAY,4BAAc,CAAC;qBAC/D,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClD,IAAI,YAAY,EAAE;oBAChB,GAAG,CAAC,qCAAqC,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC/D,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC3D,YAAY,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;iBAClD;aACF;YAED,IAAI,CAAC,YAAY,EAAE;gBACjB,GAAG,CAAC,wBAAwB,CAAC,CAAC;gBAC9B,OAAO;aACR;YAED,MAAM,OAAO,GAAG,UAAU,CAAC,gCAAiB,CAAC,OAAO,CAAC,CAAC;YACtD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;gBAC/B,YAAY,CAAC,OAAO,GAAG,OAAO,CAAC;aAChC;YAED,MAAM,WAAW,GAAG,UAAU,CAC5B,gCAAiB,CAAC,mBAAmB,CAC5B,CAAC;YACZ,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;gBACnC,YAAY,CAAC,iBAAiB,GAAG,WAAW,CAAC;aAC9C;QACH,CAAC,CAAC;QAEF,cAAS,GAAG,CAAC,MAAkB,EAAE,EAAE;YACjC,MAAM,UAAU,GAAsC,EAAE,CAAC;YAEzD,QAAQ,MAAM,CAAC,IAAI,EAAE;gBACnB,KAAK,kBAAY,CAAC,IAAI;oBACpB;wBACE,MAAM,GAAG,MAAsB,CAAC;wBAChC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;qBAC9C;oBACD,MAAM;gBACR,KAAK,kBAAY,CAAC,IAAI;oBACpB;wBACE,MAAM,GAAG,MAAsB,CAAC;wBAChC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;4BAChC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;wBAC/C,CAAC,CAAC,CAAC;qBACJ;oBACD,MAAM;gBACR,KAAK,iCAA2B,CAAC,IAAI;oBACnC;wBACE,MAAM,IAAI,GAAG,MAAqC,CAAC;wBACnD,4CAA4C;qBAC7C;oBACD,MAAM;gBACR,KAAK,gCAA0B,CAAC,IAAI;oBAClC;wBACE,MAAM,KAAK,GAAG,MAAoC,CAAC;wBACnD,IAAI,KAAK,CAAC,QAAQ,EAAE;4BAClB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;yBACjE;qBACF;oBACD,MAAM;gBACR,KAAK,iCAA2B,CAAC,IAAI;oBACnC;wBACE,MAAM,IAAI,GAAG,MAAqC,CAAC;wBACnD,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;4BAC3B,KAAK,iCAA2B,CAAC,KAAK;gCACpC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAuC,CAAC;gCAC1D,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gCACvD,MAAM;4BACR;gCACE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;yBAC7D;qBACF;oBACD,MAAM;aACT;YACD,UAAU;iBACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,iBAAiB;iBAClC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC;IAzLa,CAAC;IAEhB,iBAAiB,CAAC,MAAoB;QACpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACvC,CAAC;IAEO,mBAAmB,CAAC,QAAwB,EAAE,IAAY;QAChE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED,yBAAyB,CACvB,WAA8B,EAC9B,MAA+B;QAE/B,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;QAEzC,MAAM,CAAC,SAAS;aACb,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,WAAW;aAC9C,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACrB,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5D,WAAW,CAAC,QAAQ,CAClB,IAAI,wBAAgB,CAAC;gBACnB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,IAAI,EAAE,WAAW,CAAC,IAAI;gBACtB,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;gBAC9B,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;aACxB,CAAC,CACH,CAAC;YACF,IAAI,MAAM,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aACjE;QACH,CAAC,CAAC,CAAC;QAEL,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAC5C,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB,CACtB,WAA8B,EAC9B,KAAgC,EAChC,MAA+B;QAE/B,mDAAmD;QACnD,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;QAE9B,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;QACvC,WAAW,CAAC,QAAQ,CAClB,IAAI,wBAAgB,CAAC;YACnB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,EAAE,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;YAC9B,MAAM,EAAE,IAAI;YACZ,KAAK;SACN,CAAC,CACH,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,yBAAyB,CAC9B,UAAuB,EACvB,WAAqC;QAErC,OAAO,UAAU;aACd,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;YACjB,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACtC,QAAQ,GAAG,EAAE;gBACX,KAAK,gCAAiB,CAAC,OAAO,CAAC;gBAC/B,KAAK,gCAAiB,CAAC,eAAe,CAAC;gBACvC,KAAK,gCAAiB,CAAC,mBAAmB;oBACxC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACtD,KAAK,gCAAiB,CAAC,eAAe;oBACpC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;gBAC1D,KAAK,gCAAiB,CAAC,WAAW;oBAChC,OAAO;wBACL,GAAG;wBACH,KAAK,EAAE,IAAA,kBAAY,EAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;qBAC/C,CAAC;gBACJ;oBACE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;aAC5B;QACH,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,GAA2B,EAAE,GAAG,EAAE,EAAE;YAC3C,IAAI,GAAG;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;YAClC,OAAO,GAAG,CAAC;QACb,CAAC,EAAE,EAAE,CAAC,CAAC;IACX,CAAC;CAmGF;AA/LD,8BA+LC","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,5 +1,6 @@
1
1
  import Event from "rx.mini";
2
2
  import { RtcpPacket, RtpPacket } from "../../../rtp/src";
3
+ import { PeerConfig } from "..";
3
4
  import { RTCDtlsTransport } from "../transport/dtls";
4
5
  import { Kind } from "../types/domain";
5
6
  import { RTCRtpReceiveParameters } from "./parameters";
@@ -7,9 +8,11 @@ import { ReceiverTWCC } from "./receiver/receiverTwcc";
7
8
  import { Extensions } from "./router";
8
9
  import { MediaStreamTrack } from "./track";
9
10
  export declare class RTCRtpReceiver {
11
+ readonly config: PeerConfig;
10
12
  kind: Kind;
11
13
  rtcpSsrc: number;
12
14
  private readonly codecs;
15
+ private get codecArray();
13
16
  private readonly ssrcByRtx;
14
17
  private readonly nack;
15
18
  private readonly redHandler;
@@ -22,10 +25,14 @@ export declare class RTCRtpReceiver {
22
25
  readonly trackByRID: {
23
26
  [rid: string]: MediaStreamTrack;
24
27
  };
25
- readonly lsr: {
28
+ /**last sender Report Timestamp
29
+ * compactNtp
30
+ */
31
+ readonly lastSRtimestamp: {
26
32
  [ssrc: number]: number;
27
33
  };
28
- readonly lsrTime: {
34
+ /**seconds */
35
+ readonly receiveLastSRTimestamp: {
29
36
  [ssrc: number]: number;
30
37
  };
31
38
  readonly onPacketLost: Event<[import("..").GenericNack]>;
@@ -42,9 +49,10 @@ export declare class RTCRtpReceiver {
42
49
  rtcpRunning: boolean;
43
50
  private rtcpCancel;
44
51
  private remoteStreams;
45
- constructor(kind: Kind, rtcpSsrc: number);
52
+ constructor(config: PeerConfig, kind: Kind, rtcpSsrc: number);
46
53
  setDtlsTransport(dtls: RTCDtlsTransport): void;
47
54
  get track(): MediaStreamTrack;
55
+ get nackEnabled(): import("./parameters").RTCPFB | undefined;
48
56
  prepareReceive(params: RTCRtpReceiveParameters): void;
49
57
  /**
50
58
  * setup TWCC if supported
@@ -20,21 +20,25 @@ const red_1 = require("./receiver/red");
20
20
  const statistics_1 = require("./receiver/statistics");
21
21
  const log = (0, debug_1.debug)("werift:packages/webrtc/src/media/rtpReceiver.ts");
22
22
  class RTCRtpReceiver {
23
- constructor(kind, rtcpSsrc) {
23
+ constructor(config, kind, rtcpSsrc) {
24
+ this.config = config;
24
25
  this.kind = kind;
25
26
  this.rtcpSsrc = rtcpSsrc;
26
27
  this.codecs = {};
27
28
  this.ssrcByRtx = {};
28
- this.nack = new nack_1.Nack(this);
29
- this.redHandler = new red_1.RedHandler();
29
+ this.nack = new nack_1.NackHandler(this);
30
+ this.redHandler = new red_1.AudioRedHandler();
30
31
  this.type = "receiver";
31
32
  this.uuid = (0, uuid_1.v4)();
32
33
  this.tracks = [];
33
34
  this.trackBySSRC = {};
34
35
  this.trackByRID = {};
35
- // last senderReport
36
- this.lsr = {};
37
- this.lsrTime = {};
36
+ /**last sender Report Timestamp
37
+ * compactNtp
38
+ */
39
+ this.lastSRtimestamp = {};
40
+ /**seconds */
41
+ this.receiveLastSRTimestamp = {};
38
42
  this.onPacketLost = this.nack.onPacketLost;
39
43
  this.onRtcp = new rx_mini_1.default();
40
44
  this.supportTWCC = false;
@@ -54,6 +58,9 @@ class RTCRtpReceiver {
54
58
  this.handleRTP(packet, extensions, track);
55
59
  };
56
60
  }
61
+ get codecArray() {
62
+ return Object.values(this.codecs).sort((a, b) => a.payloadType - b.payloadType);
63
+ }
57
64
  setDtlsTransport(dtls) {
58
65
  this.dtlsTransport = dtls;
59
66
  }
@@ -61,6 +68,9 @@ class RTCRtpReceiver {
61
68
  get track() {
62
69
  return this.tracks[0];
63
70
  }
71
+ get nackEnabled() {
72
+ return this.codecArray[0].rtcpFeedback.find((f) => f.type === "nack");
73
+ }
64
74
  prepareReceive(params) {
65
75
  params.codecs.forEach((c) => {
66
76
  this.codecs[c.payloadType] = c;
@@ -115,12 +125,12 @@ class RTCRtpReceiver {
115
125
  signal: this.rtcpCancel.signal,
116
126
  });
117
127
  const reports = Object.entries(this.remoteStreams).map(([ssrc, stream]) => {
118
- let lsr = 0, dlsr = 0;
119
- if (this.lsr[ssrc]) {
120
- lsr = this.lsr[ssrc];
121
- const delay = Date.now() / 1000 - this.lsrTime[ssrc];
122
- if (delay > 0 && delay < 65536) {
123
- dlsr = (0, src_1.int)(delay * 65536);
128
+ let lastSRtimestamp = 0, delaySinceLastSR = 0;
129
+ if (this.lastSRtimestamp[ssrc]) {
130
+ lastSRtimestamp = this.lastSRtimestamp[ssrc];
131
+ const delaySeconds = (0, utils_1.timestampSeconds)() - this.receiveLastSRTimestamp[ssrc];
132
+ if (delaySeconds > 0 && delaySeconds < 65536) {
133
+ delaySinceLastSR = (0, src_1.int)(delaySeconds * 65536);
124
134
  }
125
135
  }
126
136
  return new src_2.RtcpReceiverInfo({
@@ -129,12 +139,15 @@ class RTCRtpReceiver {
129
139
  packetsLost: stream.packets_lost,
130
140
  highestSequence: stream.max_seq,
131
141
  jitter: stream.jitter,
132
- lsr,
133
- dlsr,
142
+ lsr: lastSRtimestamp,
143
+ dlsr: delaySinceLastSR,
134
144
  });
135
145
  });
136
146
  const packet = new src_2.RtcpRrPacket({ ssrc: this.rtcpSsrc, reports });
137
147
  try {
148
+ if (this.config.debug.receiverReportDelay) {
149
+ await (0, promises_1.setTimeout)(this.config.debug.receiverReportDelay);
150
+ }
138
151
  await this.dtlsTransport.sendRtcp([packet]);
139
152
  }
140
153
  catch (error) {
@@ -166,8 +179,8 @@ class RTCRtpReceiver {
166
179
  case src_2.RtcpSrPacket.type:
167
180
  {
168
181
  const sr = packet;
169
- this.lsr[sr.ssrc] = (0, utils_1.compactNtp)(sr.senderInfo.ntpTimestamp);
170
- this.lsrTime[sr.ssrc] = Date.now() / 1000;
182
+ this.lastSRtimestamp[sr.ssrc] = (0, utils_1.compactNtp)(sr.senderInfo.ntpTimestamp);
183
+ this.receiveLastSRTimestamp[sr.ssrc] = (0, utils_1.timestampSeconds)();
171
184
  const track = this.trackBySSRC[packet.ssrc];
172
185
  if (track) {
173
186
  track.onReceiveRtcp.execute(packet);
@@ -211,16 +224,22 @@ class RTCRtpReceiver {
211
224
  let red;
212
225
  if (codec.name.toLowerCase() === "red") {
213
226
  red = src_2.Red.deSerialize(packet.payload);
227
+ if (!Object.keys(this.codecs).includes(red.header.fields[0].blockPT.toString())) {
228
+ return;
229
+ }
214
230
  }
215
- // todo fix select use or not use nack
216
- if (track?.kind === "video") {
231
+ if (track?.kind === "video" && this.nackEnabled) {
217
232
  this.nack.addPacket(packet);
218
233
  }
219
234
  if (track) {
220
235
  if (red) {
221
- const payloads = this.redHandler.push(red, packet);
222
- for (const packet of payloads) {
223
- track.onReceiveRtp.execute(packet.clone());
236
+ if (track.kind === "audio") {
237
+ const payloads = this.redHandler.push(red, packet);
238
+ for (const packet of payloads) {
239
+ track.onReceiveRtp.execute(packet.clone());
240
+ }
241
+ }
242
+ else {
224
243
  }
225
244
  }
226
245
  else {
@@ -235,10 +254,10 @@ function unwrapRtx(rtx, payloadType, ssrc) {
235
254
  const packet = new src_2.RtpPacket(new src_2.RtpHeader({
236
255
  payloadType,
237
256
  marker: rtx.header.marker,
238
- sequenceNumber: jspack_1.jspack.Unpack("!H", rtx.payload.slice(0, 2))[0],
257
+ sequenceNumber: jspack_1.jspack.Unpack("!H", rtx.payload.subarray(0, 2))[0],
239
258
  timestamp: rtx.header.timestamp,
240
259
  ssrc,
241
- }), rtx.payload.slice(2));
260
+ }), rtx.payload.subarray(2));
242
261
  return packet;
243
262
  }
244
263
  exports.unwrapRtx = unwrapRtx;