werift 0.22.0 → 0.22.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 (179) hide show
  1. package/lib/common/src/binary.d.ts +6 -6
  2. package/lib/common/src/event.d.ts +1 -0
  3. package/lib/common/src/event.js +5 -0
  4. package/lib/common/src/event.js.map +1 -1
  5. package/lib/common/src/log.d.ts +1 -2
  6. package/lib/common/src/transport.d.ts +2 -1
  7. package/lib/common/src/transport.js +28 -14
  8. package/lib/common/src/transport.js.map +1 -1
  9. package/lib/dtls/src/cipher/prf.d.ts +12 -12
  10. package/lib/dtls/src/cipher/suites/aead.d.ts +3 -2
  11. package/lib/dtls/src/cipher/suites/aead.js +31 -38
  12. package/lib/dtls/src/cipher/suites/aead.js.map +1 -1
  13. package/lib/dtls/src/context/cipher.d.ts +4 -4
  14. package/lib/dtls/src/context/cipher.js +21 -10
  15. package/lib/dtls/src/context/cipher.js.map +1 -1
  16. package/lib/dtls/src/context/srtp.d.ts +3 -3
  17. package/lib/dtls/src/context/srtp.js.map +1 -1
  18. package/lib/dtls/src/flight/client/flight5.js.map +1 -1
  19. package/lib/dtls/src/flight/server/flight2.js.map +1 -1
  20. package/lib/dtls/src/handshake/extensions/ellipticCurves.d.ts +1 -1
  21. package/lib/dtls/src/handshake/extensions/renegotiationIndication.d.ts +2 -2
  22. package/lib/dtls/src/handshake/extensions/signature.d.ts +2 -2
  23. package/lib/dtls/src/handshake/extensions/useSrtp.d.ts +1 -1
  24. package/lib/dtls/src/handshake/message/alert.d.ts +1 -1
  25. package/lib/dtls/src/handshake/message/certificate.d.ts +1 -1
  26. package/lib/dtls/src/handshake/message/changeCipherSpec.d.ts +1 -1
  27. package/lib/dtls/src/handshake/message/client/certificateVerify.d.ts +1 -1
  28. package/lib/dtls/src/handshake/message/client/hello.d.ts +1 -1
  29. package/lib/dtls/src/handshake/message/client/keyExchange.d.ts +1 -1
  30. package/lib/dtls/src/handshake/message/finished.d.ts +1 -1
  31. package/lib/dtls/src/handshake/message/server/certificateRequest.d.ts +1 -1
  32. package/lib/dtls/src/handshake/message/server/hello.d.ts +1 -1
  33. package/lib/dtls/src/handshake/message/server/helloDone.d.ts +1 -1
  34. package/lib/dtls/src/handshake/message/server/helloVerifyRequest.d.ts +1 -1
  35. package/lib/dtls/src/handshake/message/server/keyExchange.d.ts +1 -1
  36. package/lib/dtls/src/handshake/random.d.ts +3 -3
  37. package/lib/dtls/src/record/message/fragment.d.ts +1 -1
  38. package/lib/dtls/src/record/message/header.d.ts +2 -19
  39. package/lib/dtls/src/record/message/header.js +1 -60
  40. package/lib/dtls/src/record/message/header.js.map +1 -1
  41. package/lib/dtls/src/record/message/plaintext.d.ts +6 -27
  42. package/lib/dtls/src/record/message/plaintext.js +34 -16
  43. package/lib/dtls/src/record/message/plaintext.js.map +1 -1
  44. package/lib/dtls/src/socket.d.ts +4 -4
  45. package/lib/dtls/src/socket.js.map +1 -1
  46. package/lib/dtls/src/util/binary.d.ts +1 -1
  47. package/lib/ice/src/helper.d.ts +1 -1
  48. package/lib/ice/src/ice.d.ts +4 -3
  49. package/lib/ice/src/ice.js +89 -68
  50. package/lib/ice/src/ice.js.map +1 -1
  51. package/lib/ice/src/iceBase.d.ts +20 -1
  52. package/lib/ice/src/iceBase.js +46 -0
  53. package/lib/ice/src/iceBase.js.map +1 -1
  54. package/lib/ice/src/stun/attributes.d.ts +2 -2
  55. package/lib/ice/src/stun/attributes.js +47 -27
  56. package/lib/ice/src/stun/attributes.js.map +1 -1
  57. package/lib/ice/src/stun/message.d.ts +2 -2
  58. package/lib/ice/src/stun/message.js +21 -23
  59. package/lib/ice/src/stun/message.js.map +1 -1
  60. package/lib/ice/src/stun/protocol.d.ts +2 -2
  61. package/lib/ice/src/turn/protocol.d.ts +2 -2
  62. package/lib/index.mjs +2252 -1474
  63. package/lib/nonstandard/index.mjs +333 -370
  64. package/lib/rtp/src/codec/av1.d.ts +2 -2
  65. package/lib/rtp/src/codec/opus.d.ts +1 -1
  66. package/lib/rtp/src/extra/container/mp4/container.js +18 -8
  67. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  68. package/lib/rtp/src/extra/container/mp4/h264.d.ts +2 -2
  69. package/lib/rtp/src/extra/container/mp4/sps-parser.d.ts +1 -1
  70. package/lib/rtp/src/extra/container/ogg/parser.d.ts +1 -1
  71. package/lib/rtp/src/extra/container/webm/container.d.ts +7 -7
  72. package/lib/rtp/src/extra/container/webm/container.js +17 -7
  73. package/lib/rtp/src/extra/container/webm/container.js.map +1 -1
  74. package/lib/rtp/src/extra/container/webm/ebml/ebml.d.ts +1 -1
  75. package/lib/rtp/src/extra/container/webm/ebml/id.d.ts +222 -222
  76. package/lib/rtp/src/extra/processor/depacketizerCallback.d.ts +1 -1
  77. package/lib/rtp/src/extra/processor/depacketizerTransformer.d.ts +6 -1
  78. package/lib/rtp/src/extra/processor/dtxCallback.d.ts +1 -1
  79. package/lib/rtp/src/extra/processor/interface.d.ts +1 -1
  80. package/lib/rtp/src/extra/processor/jitterBufferCallback.d.ts +1 -1
  81. package/lib/rtp/src/extra/processor/mp4.js +3 -0
  82. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  83. package/lib/rtp/src/extra/processor/nackHandlerCallback.d.ts +1 -1
  84. package/lib/rtp/src/extra/processor/ntpTimeCallback.d.ts +1 -1
  85. package/lib/rtp/src/extra/processor/rtpTimeCallback.d.ts +1 -1
  86. package/lib/rtp/src/extra/processor/webm.d.ts +1 -1
  87. package/lib/rtp/src/extra/processor/webmCallback.d.ts +1 -1
  88. package/lib/rtp/src/extra/processor/webmCallback.js +23 -17
  89. package/lib/rtp/src/extra/processor/webmCallback.js.map +1 -1
  90. package/lib/rtp/src/helper.d.ts +1 -1
  91. package/lib/rtp/src/rtcp/header.d.ts +1 -1
  92. package/lib/rtp/src/rtcp/psfb/fullIntraRequest.d.ts +1 -1
  93. package/lib/rtp/src/rtcp/psfb/index.d.ts +1 -1
  94. package/lib/rtp/src/rtcp/psfb/pictureLossIndication.d.ts +1 -1
  95. package/lib/rtp/src/rtcp/psfb/remb.d.ts +1 -1
  96. package/lib/rtp/src/rtcp/rr.d.ts +2 -2
  97. package/lib/rtp/src/rtcp/rtcp.d.ts +1 -1
  98. package/lib/rtp/src/rtcp/rtpfb/index.d.ts +1 -1
  99. package/lib/rtp/src/rtcp/rtpfb/nack.d.ts +1 -1
  100. package/lib/rtp/src/rtcp/rtpfb/twcc.d.ts +4 -4
  101. package/lib/rtp/src/rtcp/sdes.d.ts +3 -3
  102. package/lib/rtp/src/rtcp/sr.d.ts +2 -2
  103. package/lib/rtp/src/rtp/headerExtension.d.ts +6 -6
  104. package/lib/rtp/src/rtp/red/packet.d.ts +2 -2
  105. package/lib/rtp/src/rtp/rtp.d.ts +2 -2
  106. package/lib/rtp/src/srtp/cipher/ctr.d.ts +4 -4
  107. package/lib/rtp/src/srtp/cipher/gcm.d.ts +4 -4
  108. package/lib/rtp/src/srtp/const.d.ts +3 -3
  109. package/lib/rtp/src/srtp/const.js.map +1 -1
  110. package/lib/rtp/src/srtp/context/context.d.ts +7 -7
  111. package/lib/rtp/src/srtp/context/context.js +10 -4
  112. package/lib/rtp/src/srtp/context/context.js.map +1 -1
  113. package/lib/rtp/src/srtp/context/srtcp.d.ts +3 -3
  114. package/lib/rtp/src/srtp/context/srtcp.js.map +1 -1
  115. package/lib/rtp/src/srtp/context/srtp.d.ts +3 -3
  116. package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
  117. package/lib/rtp/src/srtp/srtcp.d.ts +2 -2
  118. package/lib/rtp/src/srtp/srtp.d.ts +2 -2
  119. package/lib/sctp/src/chunk.d.ts +12 -12
  120. package/lib/sctp/src/chunk.js +87 -66
  121. package/lib/sctp/src/chunk.js.map +1 -1
  122. package/lib/sctp/src/param.d.ts +3 -3
  123. package/lib/sctp/src/sctp.d.ts +3 -1
  124. package/lib/sctp/src/sctp.js +36 -1
  125. package/lib/sctp/src/sctp.js.map +1 -1
  126. package/lib/webrtc/src/dataChannel.d.ts +15 -4
  127. package/lib/webrtc/src/dataChannel.js +42 -7
  128. package/lib/webrtc/src/dataChannel.js.map +1 -1
  129. package/lib/webrtc/src/index.d.ts +1 -0
  130. package/lib/webrtc/src/index.js +1 -0
  131. package/lib/webrtc/src/index.js.map +1 -1
  132. package/lib/webrtc/src/media/index.d.ts +1 -0
  133. package/lib/webrtc/src/media/index.js +1 -0
  134. package/lib/webrtc/src/media/index.js.map +1 -1
  135. package/lib/webrtc/src/media/parameters.d.ts +2 -2
  136. package/lib/webrtc/src/media/parameters.js.map +1 -1
  137. package/lib/webrtc/src/media/router.js +2 -1
  138. package/lib/webrtc/src/media/router.js.map +1 -1
  139. package/lib/webrtc/src/media/rtpReceiver.d.ts +2 -2
  140. package/lib/webrtc/src/media/rtpReceiver.js +51 -2
  141. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  142. package/lib/webrtc/src/media/rtpSender.d.ts +6 -0
  143. package/lib/webrtc/src/media/rtpSender.js +78 -7
  144. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  145. package/lib/webrtc/src/media/rtpTransceiver.d.ts +12 -9
  146. package/lib/webrtc/src/media/rtpTransceiver.js +45 -8
  147. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  148. package/lib/webrtc/src/media/stats.d.ts +279 -0
  149. package/lib/webrtc/src/media/stats.js +35 -1
  150. package/lib/webrtc/src/media/stats.js.map +1 -1
  151. package/lib/webrtc/src/peerConnection.d.ts +34 -64
  152. package/lib/webrtc/src/peerConnection.js +319 -986
  153. package/lib/webrtc/src/peerConnection.js.map +1 -1
  154. package/lib/webrtc/src/sctpManager.d.ts +27 -0
  155. package/lib/webrtc/src/sctpManager.js +147 -0
  156. package/lib/webrtc/src/sctpManager.js.map +1 -0
  157. package/lib/webrtc/src/sdp.d.ts +3 -2
  158. package/lib/webrtc/src/sdp.js +17 -7
  159. package/lib/webrtc/src/sdp.js.map +1 -1
  160. package/lib/webrtc/src/sdpManager.d.ts +78 -0
  161. package/lib/webrtc/src/sdpManager.js +391 -0
  162. package/lib/webrtc/src/sdpManager.js.map +1 -0
  163. package/lib/webrtc/src/secureTransportManager.d.ts +56 -0
  164. package/lib/webrtc/src/secureTransportManager.js +345 -0
  165. package/lib/webrtc/src/secureTransportManager.js.map +1 -0
  166. package/lib/webrtc/src/transceiverManager.d.ts +40 -0
  167. package/lib/webrtc/src/transceiverManager.js +355 -0
  168. package/lib/webrtc/src/transceiverManager.js.map +1 -0
  169. package/lib/webrtc/src/transport/dtls.d.ts +18 -6
  170. package/lib/webrtc/src/transport/dtls.js +119 -11
  171. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  172. package/lib/webrtc/src/transport/ice.d.ts +24 -0
  173. package/lib/webrtc/src/transport/ice.js +86 -0
  174. package/lib/webrtc/src/transport/ice.js.map +1 -1
  175. package/lib/webrtc/src/transport/sctp.js +22 -7
  176. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  177. package/lib/webrtc/src/utils.d.ts +3 -3
  178. package/lib/webrtc/src/utils.js.map +1 -1
  179. package/package.json +15 -21
@@ -0,0 +1,355 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TransceiverManager = void 0;
4
+ const const_1 = require("./const");
5
+ const common_1 = require("./imports/common");
6
+ const media_1 = require("./media");
7
+ const peerConnection_1 = require("./peerConnection");
8
+ const sdp_1 = require("./sdp");
9
+ const utils_1 = require("./utils");
10
+ const log = (0, common_1.debug)("werift:packages/webrtc/src/media/rtpTransceiverManager.ts");
11
+ class TransceiverManager {
12
+ constructor(cname, config, router) {
13
+ Object.defineProperty(this, "cname", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: cname
18
+ });
19
+ Object.defineProperty(this, "config", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: config
24
+ });
25
+ Object.defineProperty(this, "router", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: router
30
+ });
31
+ Object.defineProperty(this, "transceivers", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: []
36
+ });
37
+ Object.defineProperty(this, "onTransceiverAdded", {
38
+ enumerable: true,
39
+ configurable: true,
40
+ writable: true,
41
+ value: new common_1.Event()
42
+ });
43
+ Object.defineProperty(this, "onRemoteTransceiverAdded", {
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true,
47
+ value: new common_1.Event()
48
+ });
49
+ Object.defineProperty(this, "onTrack", {
50
+ enumerable: true,
51
+ configurable: true,
52
+ writable: true,
53
+ value: new common_1.Event()
54
+ });
55
+ Object.defineProperty(this, "onNegotiationNeeded", {
56
+ enumerable: true,
57
+ configurable: true,
58
+ writable: true,
59
+ value: new common_1.Event()
60
+ });
61
+ }
62
+ getTransceivers() {
63
+ return this.transceivers;
64
+ }
65
+ getSenders() {
66
+ return this.getTransceivers().map((t) => t.sender);
67
+ }
68
+ getReceivers() {
69
+ return this.getTransceivers().map((t) => t.receiver);
70
+ }
71
+ getTransceiverByMLineIndex(index) {
72
+ return this.transceivers.find((transceiver) => transceiver.mLineIndex === index);
73
+ }
74
+ pushTransceiver(t) {
75
+ this.transceivers.push(t);
76
+ }
77
+ replaceTransceiver(t, index) {
78
+ this.transceivers[index] = t;
79
+ }
80
+ addTransceiver(trackOrKind, dtlsTransport, options = {}) {
81
+ const kind = typeof trackOrKind === "string" ? trackOrKind : trackOrKind.kind;
82
+ const direction = options.direction || "sendrecv";
83
+ const sender = new media_1.RTCRtpSender(trackOrKind);
84
+ const receiver = new media_1.RTCRtpReceiver(this.config, kind, sender.ssrc);
85
+ const newTransceiver = new media_1.RTCRtpTransceiver(kind, dtlsTransport, receiver, sender, direction);
86
+ newTransceiver.options = options;
87
+ this.router.registerRtpSender(newTransceiver.sender);
88
+ // reuse inactive
89
+ const inactiveTransceiverIndex = this.transceivers.findIndex((t) => t.currentDirection === "inactive");
90
+ const inactiveTransceiver = this.transceivers.find((t) => t.currentDirection === "inactive");
91
+ if (inactiveTransceiverIndex > -1 && inactiveTransceiver) {
92
+ this.replaceTransceiver(newTransceiver, inactiveTransceiverIndex);
93
+ newTransceiver.mLineIndex = inactiveTransceiver.mLineIndex;
94
+ inactiveTransceiver.setCurrentDirection(undefined);
95
+ }
96
+ else {
97
+ this.pushTransceiver(newTransceiver);
98
+ }
99
+ this.onTransceiverAdded.execute(newTransceiver);
100
+ return newTransceiver;
101
+ }
102
+ addTrack(track, ms) {
103
+ if (this.getSenders().find((sender) => sender.track?.uuid === track.uuid)) {
104
+ throw new Error("Track already added");
105
+ }
106
+ const emptyTrackSenderTransceiver = this.transceivers.find((t) => t.sender.track == undefined &&
107
+ t.kind === track.kind &&
108
+ const_1.SenderDirections.includes(t.direction) === true);
109
+ if (emptyTrackSenderTransceiver) {
110
+ const sender = emptyTrackSenderTransceiver.sender;
111
+ sender.registerTrack(track);
112
+ return emptyTrackSenderTransceiver;
113
+ }
114
+ const notSendTransceiver = this.transceivers.find((t) => t.sender.track == undefined &&
115
+ t.kind === track.kind &&
116
+ const_1.SenderDirections.includes(t.direction) === false &&
117
+ !t.usedForSender);
118
+ if (notSendTransceiver) {
119
+ const sender = notSendTransceiver.sender;
120
+ sender.registerTrack(track);
121
+ switch (notSendTransceiver.direction) {
122
+ case "recvonly":
123
+ notSendTransceiver.setDirection("sendrecv");
124
+ break;
125
+ case "inactive":
126
+ notSendTransceiver.setDirection("sendonly");
127
+ break;
128
+ }
129
+ return notSendTransceiver;
130
+ }
131
+ else {
132
+ const transceiver = this.addTransceiver(track, undefined, {
133
+ direction: "sendrecv",
134
+ });
135
+ return transceiver;
136
+ }
137
+ }
138
+ removeTrack(sender) {
139
+ if (!this.getSenders().find(({ ssrc }) => sender.ssrc === ssrc)) {
140
+ throw new Error("Sender does not exist");
141
+ }
142
+ const transceiver = this.transceivers.find(({ sender: { ssrc } }) => sender.ssrc === ssrc);
143
+ if (!transceiver)
144
+ throw new Error("No matching transceiver found");
145
+ sender.stop();
146
+ if (transceiver.currentDirection === "recvonly") {
147
+ this.onNegotiationNeeded.execute();
148
+ return;
149
+ }
150
+ if (transceiver.stopping || transceiver.stopped) {
151
+ transceiver.setDirection("inactive");
152
+ }
153
+ else {
154
+ if (transceiver.direction === "sendrecv") {
155
+ transceiver.setDirection("recvonly");
156
+ }
157
+ else if (transceiver.direction === "sendonly" ||
158
+ transceiver.direction === "recvonly") {
159
+ transceiver.setDirection("inactive");
160
+ }
161
+ }
162
+ }
163
+ assignTransceiverCodecs(transceiver) {
164
+ const codecs = this.config.codecs[transceiver.kind].filter((codecCandidate) => {
165
+ switch (codecCandidate.direction) {
166
+ case "recvonly": {
167
+ if (const_1.ReceiverDirection.includes(transceiver.direction))
168
+ return true;
169
+ return false;
170
+ }
171
+ case "sendonly": {
172
+ if (const_1.SenderDirections.includes(transceiver.direction))
173
+ return true;
174
+ return false;
175
+ }
176
+ case "sendrecv": {
177
+ if ([media_1.Sendrecv, media_1.Recvonly, media_1.Sendonly].includes(transceiver.direction))
178
+ return true;
179
+ return false;
180
+ }
181
+ case "all": {
182
+ return true;
183
+ }
184
+ default:
185
+ return false;
186
+ }
187
+ });
188
+ transceiver.codecs = codecs;
189
+ }
190
+ getLocalRtpParams(transceiver) {
191
+ if (transceiver.mid == undefined)
192
+ throw new Error("mid not assigned");
193
+ const rtp = {
194
+ codecs: transceiver.codecs,
195
+ muxId: transceiver.mid,
196
+ headerExtensions: transceiver.headerExtensions,
197
+ rtcp: { cname: this.cname, ssrc: transceiver.sender.ssrc, mux: true },
198
+ };
199
+ return rtp;
200
+ }
201
+ getRemoteRtpParams(media, transceiver) {
202
+ const receiveParameters = {
203
+ muxId: media.rtp.muxId,
204
+ rtcp: media.rtp.rtcp,
205
+ codecs: transceiver.codecs,
206
+ headerExtensions: transceiver.headerExtensions,
207
+ encodings: Object.values(transceiver.codecs.reduce((acc, codec) => {
208
+ if (codec.name.toLowerCase() === "rtx") {
209
+ const params = (0, sdp_1.codecParametersFromString)(codec.parameters ?? "");
210
+ const apt = acc[params["apt"]];
211
+ if (apt && media.ssrc.length === 2) {
212
+ apt.rtx = new media_1.RTCRtpRtxParameters({ ssrc: media.ssrc[1].ssrc });
213
+ }
214
+ return acc;
215
+ }
216
+ acc[codec.payloadType] = new media_1.RTCRtpCodingParameters({
217
+ ssrc: media.ssrc[0]?.ssrc,
218
+ payloadType: codec.payloadType,
219
+ });
220
+ return acc;
221
+ }, {})),
222
+ };
223
+ return receiveParameters;
224
+ }
225
+ setRemoteRTP(transceiver, remoteMedia, type, mLineIndex) {
226
+ if (!transceiver.mid) {
227
+ transceiver.mid = remoteMedia.rtp.muxId;
228
+ }
229
+ transceiver.mLineIndex = mLineIndex;
230
+ // # negotiate codecs
231
+ transceiver.codecs = remoteMedia.rtp.codecs.filter((remoteCodec) => {
232
+ const localCodecs = this.config.codecs[remoteMedia.kind] || [];
233
+ const existCodec = (0, peerConnection_1.findCodecByMimeType)(localCodecs, remoteCodec);
234
+ if (!existCodec) {
235
+ return false;
236
+ }
237
+ if (existCodec?.name.toLowerCase() === "rtx") {
238
+ const params = (0, sdp_1.codecParametersFromString)(existCodec.parameters ?? "");
239
+ const pt = params["apt"];
240
+ const origin = remoteMedia.rtp.codecs.find((c) => c.payloadType === pt);
241
+ if (!origin) {
242
+ return false;
243
+ }
244
+ return !!(0, peerConnection_1.findCodecByMimeType)(localCodecs, origin);
245
+ }
246
+ return true;
247
+ });
248
+ log("negotiated codecs", transceiver.codecs);
249
+ if (transceiver.codecs.length === 0) {
250
+ throw new Error("negotiate codecs failed.");
251
+ }
252
+ transceiver.headerExtensions = remoteMedia.rtp.headerExtensions.filter((extension) => (this.config.headerExtensions[remoteMedia.kind] ||
253
+ []).find((v) => v.uri === extension.uri));
254
+ // # configure direction
255
+ const mediaDirection = remoteMedia.direction ?? "inactive";
256
+ const direction = (0, utils_1.reverseDirection)(mediaDirection);
257
+ if (["answer", "pranswer"].includes(type)) {
258
+ transceiver.setCurrentDirection(direction);
259
+ }
260
+ else {
261
+ transceiver.offerDirection = direction;
262
+ }
263
+ const localParams = this.getLocalRtpParams(transceiver);
264
+ transceiver.sender.prepareSend(localParams);
265
+ if (["recvonly", "sendrecv"].includes(transceiver.direction)) {
266
+ const remotePrams = this.getRemoteRtpParams(remoteMedia, transceiver);
267
+ // register simulcast receiver
268
+ for (const param of remoteMedia.simulcastParameters) {
269
+ this.router.registerRtpReceiverByRid(transceiver, param, remotePrams);
270
+ }
271
+ transceiver.receiver.prepareReceive(remotePrams);
272
+ // register ssrc receiver
273
+ this.router.registerRtpReceiverBySsrc(transceiver, remotePrams);
274
+ }
275
+ if (["sendonly", "sendrecv"].includes(mediaDirection)) {
276
+ if (remoteMedia.msid) {
277
+ const [streamId, trackId] = remoteMedia.msid.split(" ");
278
+ transceiver.receiver.remoteStreamId = streamId;
279
+ transceiver.receiver.remoteTrackId = trackId;
280
+ }
281
+ this.onTrack.execute({
282
+ track: transceiver.receiver.track,
283
+ transceiver,
284
+ stream: new media_1.MediaStream({
285
+ id: transceiver.receiver.remoteStreamId,
286
+ tracks: [transceiver.receiver.track],
287
+ }),
288
+ });
289
+ }
290
+ if (remoteMedia.ssrc[0]?.ssrc) {
291
+ transceiver.receiver.setupTWCC(remoteMedia.ssrc[0].ssrc);
292
+ }
293
+ }
294
+ async getStats(selector) {
295
+ const stats = [];
296
+ for (const transceiver of this.transceivers) {
297
+ const includeTransceiverStats = !selector ||
298
+ transceiver.sender.track === selector ||
299
+ transceiver.receiver.track === selector;
300
+ if (transceiver.sender) {
301
+ const senderStats = await transceiver.sender.getStats();
302
+ if (senderStats) {
303
+ for (const stat of senderStats) {
304
+ if (stat.type === "outbound-rtp" || stat.type === "media-source") {
305
+ if (includeTransceiverStats) {
306
+ stats.push(stat);
307
+ }
308
+ }
309
+ else {
310
+ stats.push(stat);
311
+ }
312
+ }
313
+ }
314
+ }
315
+ if (transceiver.receiver) {
316
+ const receiverStats = await transceiver.receiver.getStats();
317
+ if (receiverStats) {
318
+ for (const stat of receiverStats) {
319
+ if (stat.type === "inbound-rtp" ||
320
+ stat.type === "remote-outbound-rtp") {
321
+ if (includeTransceiverStats) {
322
+ stats.push(stat);
323
+ }
324
+ }
325
+ else {
326
+ stats.push(stat);
327
+ }
328
+ }
329
+ }
330
+ }
331
+ if (includeTransceiverStats) {
332
+ const codecStats = transceiver.getCodecStats();
333
+ if (codecStats) {
334
+ stats.push(...codecStats);
335
+ }
336
+ }
337
+ }
338
+ return stats;
339
+ }
340
+ /**
341
+ * 全トランシーバーのreceiver/senderのstopを呼ぶcloseメソッド
342
+ */
343
+ close() {
344
+ for (const transceiver of this.transceivers) {
345
+ transceiver.receiver.stop();
346
+ transceiver.sender.stop();
347
+ }
348
+ this.onTransceiverAdded.allUnsubscribe();
349
+ this.onRemoteTransceiverAdded.allUnsubscribe();
350
+ this.onTrack.allUnsubscribe();
351
+ this.onNegotiationNeeded.allUnsubscribe();
352
+ }
353
+ }
354
+ exports.TransceiverManager = TransceiverManager;
355
+ //# sourceMappingURL=transceiverManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transceiverManager.js","sourceRoot":"","sources":["../../../src/transceiverManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { ReceiverDirection, SenderDirections } from \"./const\";\nimport { Event, debug } from \"./imports/common\";\nimport {\n MediaStream,\n type MediaStreamTrack,\n type RTCRtpCodecParameters,\n RTCRtpCodingParameters,\n type RTCRtpParameters,\n type RTCRtpReceiveParameters,\n RTCRtpReceiver,\n RTCRtpRtxParameters,\n RTCRtpSender,\n RTCRtpTransceiver,\n Recvonly,\n type RtpRouter,\n Sendonly,\n Sendrecv,\n type TransceiverOptions,\n} from \"./media\";\nimport type { RTCStats } from \"./media/stats\";\nimport { type PeerConfig, findCodecByMimeType } from \"./peerConnection\";\nimport { type MediaDescription, codecParametersFromString } from \"./sdp\";\nimport type { RTCDtlsTransport } from \"./transport/dtls\";\nimport type { Kind } from \"./types/domain\";\nimport { reverseDirection } from \"./utils\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpTransceiverManager.ts\");\n\nexport class TransceiverManager {\n private readonly transceivers: RTCRtpTransceiver[] = [];\n\n readonly onTransceiverAdded = new Event<[RTCRtpTransceiver]>();\n readonly onRemoteTransceiverAdded = new Event<[RTCRtpTransceiver]>();\n readonly onTrack = new Event<\n [\n {\n track: MediaStreamTrack;\n transceiver: RTCRtpTransceiver;\n stream: MediaStream;\n },\n ]\n >();\n readonly onNegotiationNeeded = new Event<[]>();\n\n constructor(\n private readonly cname: string,\n private readonly config: Required<PeerConfig>,\n private readonly router: RtpRouter,\n ) {}\n\n getTransceivers(): RTCRtpTransceiver[] {\n return this.transceivers;\n }\n\n getSenders(): RTCRtpSender[] {\n return this.getTransceivers().map((t) => t.sender);\n }\n\n getReceivers() {\n return this.getTransceivers().map((t) => t.receiver);\n }\n\n getTransceiverByMLineIndex(index: number): RTCRtpTransceiver | undefined {\n return this.transceivers.find(\n (transceiver) => transceiver.mLineIndex === index,\n );\n }\n\n pushTransceiver(t: RTCRtpTransceiver): void {\n this.transceivers.push(t);\n }\n\n replaceTransceiver(t: RTCRtpTransceiver, index: number): void {\n this.transceivers[index] = t;\n }\n\n addTransceiver(\n trackOrKind: Kind | MediaStreamTrack,\n dtlsTransport?: RTCDtlsTransport,\n options: Partial<TransceiverOptions> = {},\n ): RTCRtpTransceiver {\n const kind =\n typeof trackOrKind === \"string\" ? trackOrKind : trackOrKind.kind;\n\n const direction = options.direction || \"sendrecv\";\n\n const sender = new RTCRtpSender(trackOrKind);\n const receiver = new RTCRtpReceiver(this.config, kind, sender.ssrc);\n const newTransceiver = new RTCRtpTransceiver(\n kind,\n dtlsTransport,\n receiver,\n sender,\n direction,\n );\n newTransceiver.options = options;\n this.router.registerRtpSender(newTransceiver.sender);\n\n // reuse inactive\n const inactiveTransceiverIndex = this.transceivers.findIndex(\n (t) => t.currentDirection === \"inactive\",\n );\n const inactiveTransceiver = this.transceivers.find(\n (t) => t.currentDirection === \"inactive\",\n );\n if (inactiveTransceiverIndex > -1 && inactiveTransceiver) {\n this.replaceTransceiver(newTransceiver, inactiveTransceiverIndex);\n newTransceiver.mLineIndex = inactiveTransceiver.mLineIndex;\n inactiveTransceiver.setCurrentDirection(undefined);\n } else {\n this.pushTransceiver(newTransceiver);\n }\n this.onTransceiverAdded.execute(newTransceiver);\n\n return newTransceiver;\n }\n\n addTrack(track: MediaStreamTrack, ms?: MediaStream): RTCRtpTransceiver {\n if (this.getSenders().find((sender) => sender.track?.uuid === track.uuid)) {\n throw new Error(\"Track already added\");\n }\n\n const emptyTrackSenderTransceiver = this.transceivers.find(\n (t) =>\n t.sender.track == undefined &&\n t.kind === track.kind &&\n SenderDirections.includes(t.direction) === true,\n );\n if (emptyTrackSenderTransceiver) {\n const sender = emptyTrackSenderTransceiver.sender;\n sender.registerTrack(track);\n return emptyTrackSenderTransceiver;\n }\n\n const notSendTransceiver = this.transceivers.find(\n (t) =>\n t.sender.track == undefined &&\n t.kind === track.kind &&\n SenderDirections.includes(t.direction) === false &&\n !t.usedForSender,\n );\n if (notSendTransceiver) {\n const sender = notSendTransceiver.sender;\n sender.registerTrack(track);\n switch (notSendTransceiver.direction) {\n case \"recvonly\":\n notSendTransceiver.setDirection(\"sendrecv\");\n break;\n case \"inactive\":\n notSendTransceiver.setDirection(\"sendonly\");\n break;\n }\n return notSendTransceiver;\n } else {\n const transceiver = this.addTransceiver(track, undefined, {\n direction: \"sendrecv\",\n });\n return transceiver;\n }\n }\n\n removeTrack(sender: RTCRtpSender): void {\n if (!this.getSenders().find(({ ssrc }) => sender.ssrc === ssrc)) {\n throw new Error(\"Sender does not exist\");\n }\n\n const transceiver = this.transceivers.find(\n ({ sender: { ssrc } }) => sender.ssrc === ssrc,\n );\n if (!transceiver) throw new Error(\"No matching transceiver found\");\n\n sender.stop();\n\n if (transceiver.currentDirection === \"recvonly\") {\n this.onNegotiationNeeded.execute();\n return;\n }\n\n if (transceiver.stopping || transceiver.stopped) {\n transceiver.setDirection(\"inactive\");\n } else {\n if (transceiver.direction === \"sendrecv\") {\n transceiver.setDirection(\"recvonly\");\n } else if (\n transceiver.direction === \"sendonly\" ||\n transceiver.direction === \"recvonly\"\n ) {\n transceiver.setDirection(\"inactive\");\n }\n }\n }\n\n assignTransceiverCodecs(transceiver: RTCRtpTransceiver): void {\n const codecs = (\n this.config.codecs[transceiver.kind] as RTCRtpCodecParameters[]\n ).filter((codecCandidate) => {\n switch (codecCandidate.direction) {\n case \"recvonly\": {\n if (ReceiverDirection.includes(transceiver.direction)) return true;\n return false;\n }\n case \"sendonly\": {\n if (SenderDirections.includes(transceiver.direction)) return true;\n return false;\n }\n case \"sendrecv\": {\n if ([Sendrecv, Recvonly, Sendonly].includes(transceiver.direction))\n return true;\n return false;\n }\n case \"all\": {\n return true;\n }\n default:\n return false;\n }\n });\n transceiver.codecs = codecs;\n }\n\n getLocalRtpParams(transceiver: RTCRtpTransceiver): RTCRtpParameters {\n if (transceiver.mid == undefined) throw new Error(\"mid not assigned\");\n\n const rtp: RTCRtpParameters = {\n codecs: transceiver.codecs,\n muxId: transceiver.mid,\n headerExtensions: transceiver.headerExtensions,\n rtcp: { cname: this.cname, ssrc: transceiver.sender.ssrc, mux: true },\n };\n return rtp;\n }\n\n getRemoteRtpParams(\n media: MediaDescription,\n transceiver: RTCRtpTransceiver,\n ): RTCRtpReceiveParameters {\n const receiveParameters: RTCRtpReceiveParameters = {\n muxId: media.rtp.muxId,\n rtcp: media.rtp.rtcp,\n codecs: transceiver.codecs,\n headerExtensions: transceiver.headerExtensions,\n encodings: Object.values(\n transceiver.codecs.reduce(\n (acc: { [pt: number]: RTCRtpCodingParameters }, codec) => {\n if (codec.name.toLowerCase() === \"rtx\") {\n const params = codecParametersFromString(codec.parameters ?? \"\");\n const apt = acc[params[\"apt\"]];\n if (apt && media.ssrc.length === 2) {\n apt.rtx = new RTCRtpRtxParameters({ ssrc: media.ssrc[1].ssrc });\n }\n return acc;\n }\n acc[codec.payloadType] = new RTCRtpCodingParameters({\n ssrc: media.ssrc[0]?.ssrc,\n payloadType: codec.payloadType,\n });\n return acc;\n },\n {},\n ),\n ),\n };\n\n return receiveParameters;\n }\n\n setRemoteRTP(\n transceiver: RTCRtpTransceiver,\n remoteMedia: MediaDescription,\n type: \"offer\" | \"answer\",\n mLineIndex: number,\n ): void {\n if (!transceiver.mid) {\n transceiver.mid = remoteMedia.rtp.muxId;\n }\n transceiver.mLineIndex = mLineIndex;\n\n // # negotiate codecs\n transceiver.codecs = remoteMedia.rtp.codecs.filter((remoteCodec) => {\n const localCodecs = this.config.codecs[remoteMedia.kind] || [];\n\n const existCodec = findCodecByMimeType(localCodecs, remoteCodec);\n if (!existCodec) {\n return false;\n }\n\n if (existCodec?.name.toLowerCase() === \"rtx\") {\n const params = codecParametersFromString(existCodec.parameters ?? \"\");\n const pt = params[\"apt\"];\n const origin = remoteMedia.rtp.codecs.find((c) => c.payloadType === pt);\n if (!origin) {\n return false;\n }\n return !!findCodecByMimeType(localCodecs, origin);\n }\n\n return true;\n });\n\n log(\"negotiated codecs\", transceiver.codecs);\n if (transceiver.codecs.length === 0) {\n throw new Error(\"negotiate codecs failed.\");\n }\n transceiver.headerExtensions = remoteMedia.rtp.headerExtensions.filter(\n (extension) =>\n (\n this.config.headerExtensions[remoteMedia.kind as \"audio\" | \"video\"] ||\n []\n ).find((v) => v.uri === extension.uri),\n );\n\n // # configure direction\n const mediaDirection = remoteMedia.direction ?? \"inactive\";\n const direction = reverseDirection(mediaDirection);\n if ([\"answer\", \"pranswer\"].includes(type)) {\n transceiver.setCurrentDirection(direction);\n } else {\n transceiver.offerDirection = direction;\n }\n const localParams = this.getLocalRtpParams(transceiver);\n transceiver.sender.prepareSend(localParams);\n\n if ([\"recvonly\", \"sendrecv\"].includes(transceiver.direction)) {\n const remotePrams = this.getRemoteRtpParams(remoteMedia, transceiver);\n\n // register simulcast receiver\n for (const param of remoteMedia.simulcastParameters) {\n this.router.registerRtpReceiverByRid(transceiver, param, remotePrams);\n }\n\n transceiver.receiver.prepareReceive(remotePrams);\n // register ssrc receiver\n this.router.registerRtpReceiverBySsrc(transceiver, remotePrams);\n }\n if ([\"sendonly\", \"sendrecv\"].includes(mediaDirection)) {\n if (remoteMedia.msid) {\n const [streamId, trackId] = remoteMedia.msid.split(\" \");\n transceiver.receiver.remoteStreamId = streamId;\n transceiver.receiver.remoteTrackId = trackId;\n }\n\n this.onTrack.execute({\n track: transceiver.receiver.track,\n transceiver,\n stream: new MediaStream({\n id: transceiver.receiver.remoteStreamId,\n tracks: [transceiver.receiver.track],\n }),\n });\n }\n\n if (remoteMedia.ssrc[0]?.ssrc) {\n transceiver.receiver.setupTWCC(remoteMedia.ssrc[0].ssrc);\n }\n }\n\n async getStats(selector?: MediaStreamTrack | null): Promise<RTCStats[]> {\n const stats: RTCStats[] = [];\n\n for (const transceiver of this.transceivers) {\n const includeTransceiverStats =\n !selector ||\n transceiver.sender.track === selector ||\n transceiver.receiver.track === selector;\n\n if (transceiver.sender) {\n const senderStats = await transceiver.sender.getStats();\n if (senderStats) {\n for (const stat of senderStats) {\n if (stat.type === \"outbound-rtp\" || stat.type === \"media-source\") {\n if (includeTransceiverStats) {\n stats.push(stat);\n }\n } else {\n stats.push(stat);\n }\n }\n }\n }\n\n if (transceiver.receiver) {\n const receiverStats = await transceiver.receiver.getStats();\n if (receiverStats) {\n for (const stat of receiverStats) {\n if (\n stat.type === \"inbound-rtp\" ||\n stat.type === \"remote-outbound-rtp\"\n ) {\n if (includeTransceiverStats) {\n stats.push(stat);\n }\n } else {\n stats.push(stat);\n }\n }\n }\n }\n\n if (includeTransceiverStats) {\n const codecStats = transceiver.getCodecStats();\n if (codecStats) {\n stats.push(...codecStats);\n }\n }\n }\n\n return stats;\n }\n\n /**\n * 全トランシーバーのreceiver/senderのstopを呼ぶcloseメソッド\n */\n close() {\n for (const transceiver of this.transceivers) {\n transceiver.receiver.stop();\n transceiver.sender.stop();\n }\n\n this.onTransceiverAdded.allUnsubscribe();\n this.onRemoteTransceiverAdded.allUnsubscribe();\n this.onTrack.allUnsubscribe();\n this.onNegotiationNeeded.allUnsubscribe();\n }\n}\n"]}
@@ -1,13 +1,18 @@
1
1
  import { Event } from "../imports/common";
2
2
  import { type DtlsSocket, type SignatureHash } from "../imports/dtls";
3
- import { type Profile, type RtcpPacket, type RtpHeader, SrtcpSession, SrtpSession } from "../imports/rtp";
4
- import type { RtpRouter } from "../media/router";
3
+ import { type RtcpPacket, type RtpHeader, RtpPacket, SrtcpSession, type SrtpProfile, SrtpSession } from "../imports/rtp";
4
+ import { type RTCStats } from "../media/stats";
5
5
  import type { PeerConfig } from "../peerConnection";
6
6
  import type { RTCIceTransport } from "./ice";
7
- export declare class RTCDtlsTransport {
7
+ export interface DtlsTransportStats {
8
+ bytesSent: number;
9
+ bytesReceived: number;
10
+ packetsSent: number;
11
+ packetsReceived: number;
12
+ }
13
+ export declare class RTCDtlsTransport implements DtlsTransportStats {
8
14
  readonly config: PeerConfig;
9
15
  readonly iceTransport: RTCIceTransport;
10
- readonly router: RtpRouter;
11
16
  localCertificate?: RTCCertificate | undefined;
12
17
  private readonly srtpProfiles;
13
18
  id: string;
@@ -15,15 +20,21 @@ export declare class RTCDtlsTransport {
15
20
  role: DtlsRole;
16
21
  srtpStarted: boolean;
17
22
  transportSequenceNumber: number;
23
+ bytesSent: number;
24
+ bytesReceived: number;
25
+ packetsSent: number;
26
+ packetsReceived: number;
18
27
  dataReceiver: (buf: Buffer) => void;
19
28
  dtls?: DtlsSocket;
20
29
  srtp: SrtpSession;
21
30
  srtcp: SrtcpSession;
22
31
  readonly onStateChange: Event<["closed" | "new" | "connected" | "connecting" | "failed"]>;
32
+ readonly onRtcp: Event<[RtcpPacket]>;
33
+ readonly onRtp: Event<[RtpPacket]>;
23
34
  static localCertificate?: RTCCertificate;
24
35
  static localCertificatePromise?: Promise<RTCCertificate>;
25
36
  private remoteParameters?;
26
- constructor(config: PeerConfig, iceTransport: RTCIceTransport, router: RtpRouter, localCertificate?: RTCCertificate | undefined, srtpProfiles?: Profile[]);
37
+ constructor(config: PeerConfig, iceTransport: RTCIceTransport, localCertificate?: RTCCertificate | undefined, srtpProfiles?: SrtpProfile[]);
27
38
  get localParameters(): RTCDtlsParameters;
28
39
  static SetupCertificate(): Promise<RTCCertificate>;
29
40
  setRemoteParams(remoteParameters: RTCDtlsParameters): void;
@@ -35,6 +46,7 @@ export declare class RTCDtlsTransport {
35
46
  sendRtcp(packets: RtcpPacket[]): Promise<number | undefined>;
36
47
  private setState;
37
48
  stop(): Promise<void>;
49
+ getStats(): Promise<RTCStats[]>;
38
50
  }
39
51
  export declare const DtlsStates: readonly ["new", "connecting", "connected", "closed", "failed"];
40
52
  export type DtlsState = (typeof DtlsStates)[number];
@@ -60,5 +72,5 @@ export declare class RTCDtlsFingerprint {
60
72
  export declare class RTCDtlsParameters {
61
73
  fingerprints: RTCDtlsFingerprint[];
62
74
  role: "auto" | "client" | "server";
63
- constructor(fingerprints: RTCDtlsFingerprint[], role: "auto" | "client" | "server");
75
+ constructor(fingerprints: RTCDtlsFingerprint[] | undefined, role: "auto" | "client" | "server");
64
76
  }
@@ -7,10 +7,11 @@ const uuid_1 = require("uuid");
7
7
  const common_1 = require("../imports/common");
8
8
  const dtls_1 = require("../imports/dtls");
9
9
  const rtp_1 = require("../imports/rtp");
10
+ const stats_1 = require("../media/stats");
10
11
  const utils_1 = require("../utils");
11
12
  const log = (0, rtp_1.debug)("werift:packages/webrtc/src/transport/dtls.ts");
12
13
  class RTCDtlsTransport {
13
- constructor(config, iceTransport, router, localCertificate, srtpProfiles = []) {
14
+ constructor(config, iceTransport, localCertificate, srtpProfiles = []) {
14
15
  Object.defineProperty(this, "config", {
15
16
  enumerable: true,
16
17
  configurable: true,
@@ -23,12 +24,6 @@ class RTCDtlsTransport {
23
24
  writable: true,
24
25
  value: iceTransport
25
26
  });
26
- Object.defineProperty(this, "router", {
27
- enumerable: true,
28
- configurable: true,
29
- writable: true,
30
- value: router
31
- });
32
27
  Object.defineProperty(this, "localCertificate", {
33
28
  enumerable: true,
34
29
  configurable: true,
@@ -71,6 +66,31 @@ class RTCDtlsTransport {
71
66
  writable: true,
72
67
  value: 0
73
68
  });
69
+ // Statistics tracking
70
+ Object.defineProperty(this, "bytesSent", {
71
+ enumerable: true,
72
+ configurable: true,
73
+ writable: true,
74
+ value: 0
75
+ });
76
+ Object.defineProperty(this, "bytesReceived", {
77
+ enumerable: true,
78
+ configurable: true,
79
+ writable: true,
80
+ value: 0
81
+ });
82
+ Object.defineProperty(this, "packetsSent", {
83
+ enumerable: true,
84
+ configurable: true,
85
+ writable: true,
86
+ value: 0
87
+ });
88
+ Object.defineProperty(this, "packetsReceived", {
89
+ enumerable: true,
90
+ configurable: true,
91
+ writable: true,
92
+ value: 0
93
+ });
74
94
  Object.defineProperty(this, "dataReceiver", {
75
95
  enumerable: true,
76
96
  configurable: true,
@@ -101,6 +121,18 @@ class RTCDtlsTransport {
101
121
  writable: true,
102
122
  value: new common_1.Event()
103
123
  });
124
+ Object.defineProperty(this, "onRtcp", {
125
+ enumerable: true,
126
+ configurable: true,
127
+ writable: true,
128
+ value: new common_1.Event()
129
+ });
130
+ Object.defineProperty(this, "onRtp", {
131
+ enumerable: true,
132
+ configurable: true,
133
+ writable: true,
134
+ value: new common_1.Event()
135
+ });
104
136
  Object.defineProperty(this, "remoteParameters", {
105
137
  enumerable: true,
106
138
  configurable: true,
@@ -253,19 +285,29 @@ class RTCDtlsTransport {
253
285
  }
254
286
  if (!(0, rtp_1.isMedia)(data))
255
287
  return;
288
+ // Track received data statistics
289
+ this.bytesReceived += data.length;
290
+ this.packetsReceived++;
256
291
  if ((0, rtp_1.isRtcp)(data)) {
257
292
  const dec = this.srtcp.decrypt(data);
258
- const rtcps = rtp_1.RtcpPacketConverter.deSerialize(dec);
259
- rtcps.forEach((rtcp) => this.router.routeRtcp(rtcp));
293
+ const rtcpPackets = rtp_1.RtcpPacketConverter.deSerialize(dec);
294
+ for (const rtcp of rtcpPackets) {
295
+ try {
296
+ this.onRtcp.execute(rtcp);
297
+ }
298
+ catch (error) {
299
+ log("RTCP error", error);
300
+ }
301
+ }
260
302
  }
261
303
  else {
262
304
  const dec = this.srtp.decrypt(data);
263
305
  const rtp = rtp_1.RtpPacket.deSerialize(dec);
264
306
  try {
265
- this.router.routeRtp(rtp);
307
+ this.onRtp.execute(rtp);
266
308
  }
267
309
  catch (error) {
268
- log("router error", error);
310
+ log("RTP error", error);
269
311
  }
270
312
  }
271
313
  });
@@ -277,6 +319,9 @@ class RTCDtlsTransport {
277
319
  this.config.debug.outboundPacketLoss / 100 < Math.random()) {
278
320
  return enc.length;
279
321
  }
322
+ // Track statistics
323
+ this.bytesSent += enc.length;
324
+ this.packetsSent++;
280
325
  await this.iceTransport.connection.send(enc).catch(() => { });
281
326
  return enc.length;
282
327
  }
@@ -292,6 +337,9 @@ class RTCDtlsTransport {
292
337
  this.config.debug.outboundPacketLoss / 100 < Math.random()) {
293
338
  return enc.length;
294
339
  }
340
+ // Track statistics
341
+ this.bytesSent += enc.length;
342
+ this.packetsSent++;
295
343
  await this.iceTransport.connection.send(enc).catch(() => { });
296
344
  }
297
345
  setState(state) {
@@ -303,6 +351,66 @@ class RTCDtlsTransport {
303
351
  async stop() {
304
352
  this.setState("closed");
305
353
  // todo impl send alert
354
+ await this.iceTransport.stop();
355
+ }
356
+ async getStats() {
357
+ const timestamp = (0, stats_1.getStatsTimestamp)();
358
+ const stats = [];
359
+ const transportId = (0, stats_1.generateStatsId)("transport", this.id);
360
+ // Transport stats
361
+ const transportStats = {
362
+ type: "transport",
363
+ id: transportId,
364
+ timestamp,
365
+ bytesSent: this.bytesSent,
366
+ bytesReceived: this.bytesReceived,
367
+ packetsSent: this.packetsSent,
368
+ packetsReceived: this.packetsReceived,
369
+ dtlsState: this.state,
370
+ iceState: this.iceTransport.state,
371
+ selectedCandidatePairId: this.iceTransport.connection.nominated
372
+ ? (0, stats_1.generateStatsId)("candidate-pair", this.iceTransport.connection.nominated.localCandidate.foundation, this.iceTransport.connection.nominated.remoteCandidate.foundation)
373
+ : undefined,
374
+ localCertificateId: this.localCertificate
375
+ ? (0, stats_1.generateStatsId)("certificate", "local")
376
+ : undefined,
377
+ remoteCertificateId: this.remoteParameters
378
+ ? (0, stats_1.generateStatsId)("certificate", "remote")
379
+ : undefined,
380
+ dtlsRole: this.role === "auto" ? undefined : this.role,
381
+ };
382
+ stats.push(transportStats);
383
+ // Certificate stats
384
+ if (this.localCertificate) {
385
+ const fingerprints = this.localCertificate.getFingerprints();
386
+ if (fingerprints.length > 0) {
387
+ const certStats = {
388
+ type: "certificate",
389
+ id: (0, stats_1.generateStatsId)("certificate", "local"),
390
+ timestamp,
391
+ fingerprint: fingerprints[0].value,
392
+ fingerprintAlgorithm: fingerprints[0].algorithm,
393
+ base64Certificate: Buffer.from(this.localCertificate.certPem).toString("base64"),
394
+ };
395
+ stats.push(certStats);
396
+ }
397
+ }
398
+ if (this.remoteParameters &&
399
+ this.remoteParameters.fingerprints.length > 0) {
400
+ const certStats = {
401
+ type: "certificate",
402
+ id: (0, stats_1.generateStatsId)("certificate", "remote"),
403
+ timestamp,
404
+ fingerprint: this.remoteParameters.fingerprints[0].value,
405
+ fingerprintAlgorithm: this.remoteParameters.fingerprints[0].algorithm,
406
+ base64Certificate: "", // Remote certificate content not available
407
+ };
408
+ stats.push(certStats);
409
+ }
410
+ // Get ICE stats
411
+ const iceStats = await this.iceTransport.getStats();
412
+ stats.push(...iceStats);
413
+ return stats;
306
414
  }
307
415
  }
308
416
  exports.RTCDtlsTransport = RTCDtlsTransport;