werift 0.23.0 → 0.24.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 (145) hide show
  1. package/README.md +46 -0
  2. package/lib/common/src/transport.d.ts +22 -9
  3. package/lib/common/src/transport.js +152 -25
  4. package/lib/common/src/transport.js.map +1 -1
  5. package/lib/ice/src/candidate.d.ts +16 -1
  6. package/lib/ice/src/candidate.js +99 -15
  7. package/lib/ice/src/candidate.js.map +1 -1
  8. package/lib/ice/src/ice.d.ts +2 -0
  9. package/lib/ice/src/ice.js +171 -41
  10. package/lib/ice/src/ice.js.map +1 -1
  11. package/lib/ice/src/iceBase.d.ts +23 -2
  12. package/lib/ice/src/iceBase.js +63 -1
  13. package/lib/ice/src/iceBase.js.map +1 -1
  14. package/lib/ice/src/index.d.ts +2 -0
  15. package/lib/ice/src/index.js +2 -0
  16. package/lib/ice/src/index.js.map +1 -1
  17. package/lib/ice/src/stun/const.d.ts +1 -26
  18. package/lib/ice/src/stun/const.js +15 -54
  19. package/lib/ice/src/stun/const.js.map +1 -1
  20. package/lib/ice/src/stun/message.d.ts +1 -25
  21. package/lib/ice/src/stun/message.js +15 -149
  22. package/lib/ice/src/stun/message.js.map +1 -1
  23. package/lib/ice/src/stun/protocol.d.ts +1 -1
  24. package/lib/ice/src/stun/protocol.js +2 -2
  25. package/lib/ice/src/stun/protocol.js.map +1 -1
  26. package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
  27. package/lib/ice/src/stun/tcpFrame.js +26 -0
  28. package/lib/ice/src/stun/tcpFrame.js.map +1 -0
  29. package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
  30. package/lib/ice/src/stun/tcpProtocol.js +326 -0
  31. package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
  32. package/lib/ice/src/stun/transaction.d.ts +2 -1
  33. package/lib/ice/src/stun/transaction.js +9 -3
  34. package/lib/ice/src/stun/transaction.js.map +1 -1
  35. package/lib/ice/src/turn/frame.d.ts +1 -0
  36. package/lib/ice/src/turn/frame.js +18 -0
  37. package/lib/ice/src/turn/frame.js.map +1 -0
  38. package/lib/ice/src/turn/protocol.d.ts +9 -7
  39. package/lib/ice/src/turn/protocol.js +32 -44
  40. package/lib/ice/src/turn/protocol.js.map +1 -1
  41. package/lib/ice/src/types/model.d.ts +1 -1
  42. package/lib/ice/src/types/model.js.map +1 -1
  43. package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
  44. package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
  45. package/lib/ice-server/src/stun/attributes.js.map +1 -0
  46. package/lib/ice-server/src/stun/const.d.ts +28 -0
  47. package/lib/ice-server/src/stun/const.js +88 -0
  48. package/lib/ice-server/src/stun/const.js.map +1 -0
  49. package/lib/ice-server/src/stun/message.d.ts +37 -0
  50. package/lib/ice-server/src/stun/message.js +190 -0
  51. package/lib/ice-server/src/stun/message.js.map +1 -0
  52. package/lib/ice-server/src/turn/auth.d.ts +1 -0
  53. package/lib/ice-server/src/turn/auth.js +10 -0
  54. package/lib/ice-server/src/turn/auth.js.map +1 -0
  55. package/lib/ice-server/src/turn/frame.d.ts +13 -0
  56. package/lib/ice-server/src/turn/frame.js +69 -0
  57. package/lib/ice-server/src/turn/frame.js.map +1 -0
  58. package/lib/index.mjs +2688 -855
  59. package/lib/nonstandard/index.mjs +1753 -403
  60. package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
  61. package/lib/rtp/src/extra/container/mp4/container.js +258 -173
  62. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  63. package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
  64. package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
  65. package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
  66. package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
  67. package/lib/rtp/src/extra/processor/mp4.js +115 -60
  68. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  69. package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
  70. package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
  71. package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
  72. package/lib/webrtc/src/dataChannel.d.ts +3 -2
  73. package/lib/webrtc/src/dataChannel.js +9 -2
  74. package/lib/webrtc/src/dataChannel.js.map +1 -1
  75. package/lib/webrtc/src/errors.d.ts +3 -0
  76. package/lib/webrtc/src/errors.js +11 -0
  77. package/lib/webrtc/src/errors.js.map +1 -0
  78. package/lib/webrtc/src/helper.d.ts +5 -1
  79. package/lib/webrtc/src/helper.js +33 -1
  80. package/lib/webrtc/src/helper.js.map +1 -1
  81. package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
  82. package/lib/webrtc/src/media/receiver/statistics.js +22 -0
  83. package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
  84. package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
  85. package/lib/webrtc/src/media/rtpReceiver.js +135 -20
  86. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  87. package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
  88. package/lib/webrtc/src/media/rtpSender.js +177 -28
  89. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  90. package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
  91. package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
  92. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  93. package/lib/webrtc/src/media/stats.d.ts +15 -1
  94. package/lib/webrtc/src/media/stats.js +55 -1
  95. package/lib/webrtc/src/media/stats.js.map +1 -1
  96. package/lib/webrtc/src/media/track.d.ts +2 -1
  97. package/lib/webrtc/src/media/track.js +7 -1
  98. package/lib/webrtc/src/media/track.js.map +1 -1
  99. package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
  100. package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
  101. package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
  102. package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
  103. package/lib/webrtc/src/nonstandard/navigator.js +96 -32
  104. package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
  105. package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
  106. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
  107. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
  108. package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
  109. package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
  110. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  111. package/lib/webrtc/src/peerConnection.d.ts +183 -50
  112. package/lib/webrtc/src/peerConnection.js +458 -109
  113. package/lib/webrtc/src/peerConnection.js.map +1 -1
  114. package/lib/webrtc/src/sctpManager.d.ts +1 -1
  115. package/lib/webrtc/src/sctpManager.js +27 -7
  116. package/lib/webrtc/src/sctpManager.js.map +1 -1
  117. package/lib/webrtc/src/sdp.d.ts +10 -7
  118. package/lib/webrtc/src/sdp.js +39 -9
  119. package/lib/webrtc/src/sdp.js.map +1 -1
  120. package/lib/webrtc/src/sdpManager.d.ts +4 -3
  121. package/lib/webrtc/src/sdpManager.js +50 -27
  122. package/lib/webrtc/src/sdpManager.js.map +1 -1
  123. package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
  124. package/lib/webrtc/src/secureTransportManager.js +100 -22
  125. package/lib/webrtc/src/secureTransportManager.js.map +1 -1
  126. package/lib/webrtc/src/transceiverManager.d.ts +5 -4
  127. package/lib/webrtc/src/transceiverManager.js +61 -62
  128. package/lib/webrtc/src/transceiverManager.js.map +1 -1
  129. package/lib/webrtc/src/transport/dtls.d.ts +15 -4
  130. package/lib/webrtc/src/transport/dtls.js +91 -23
  131. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  132. package/lib/webrtc/src/transport/ice.d.ts +21 -3
  133. package/lib/webrtc/src/transport/ice.js +159 -30
  134. package/lib/webrtc/src/transport/ice.js.map +1 -1
  135. package/lib/webrtc/src/transport/sctp.d.ts +1 -0
  136. package/lib/webrtc/src/transport/sctp.js +9 -6
  137. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  138. package/lib/webrtc/src/utils.d.ts +12 -4
  139. package/lib/webrtc/src/utils.js +118 -16
  140. package/lib/webrtc/src/utils.js.map +1 -1
  141. package/package.json +7 -4
  142. package/lib/ice/src/stun/attributes.js.map +0 -1
  143. package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
  144. package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
  145. package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SecureTransportManager = void 0;
4
4
  const const_1 = require("./const");
5
+ const errors_1 = require("./errors");
5
6
  const common_1 = require("./imports/common");
6
7
  const dtls_1 = require("./transport/dtls");
7
8
  const ice_1 = require("./transport/ice");
@@ -80,7 +81,10 @@ class SecureTransportManager {
80
81
  this.sctpManager = sctpManager;
81
82
  if (this.config.dtls) {
82
83
  const { keys } = this.config.dtls;
83
- if (keys) {
84
+ if (this.config.certificates[0]) {
85
+ this.certificate = this.config.certificates[0];
86
+ }
87
+ else if (keys) {
84
88
  this.setupCertificate(keys);
85
89
  }
86
90
  }
@@ -105,8 +109,15 @@ class SecureTransportManager {
105
109
  }
106
110
  createTransport() {
107
111
  const existing = this.iceTransports.find((transport) => transport.state !== "closed");
112
+ const iceServerOptions = (0, utils_1.parseIceServers)(this.config.iceServers);
113
+ const turnTransport = (0, utils_1.resolveTurnTransport)({
114
+ parsedTurnTransport: iceServerOptions.turnTransport,
115
+ configuredTurnTransport: this.config.turnTransport,
116
+ forceTurnTCP: this.config.forceTurnTCP,
117
+ });
108
118
  const iceGatherer = new ice_1.RTCIceGatherer({
109
- ...(0, utils_1.parseIceServers)(this.config.iceServers),
119
+ ...iceServerOptions,
120
+ iceLite: this.config.iceLite,
110
121
  forceTurn: this.config.iceTransportPolicy === "relay",
111
122
  portRange: this.config.icePortRange,
112
123
  interfaceAddresses: this.config.iceInterfaceAddresses,
@@ -116,7 +127,9 @@ class SecureTransportManager {
116
127
  localPasswordPrefix: this.config.icePasswordPrefix,
117
128
  useIpv4: this.config.iceUseIpv4,
118
129
  useIpv6: this.config.iceUseIpv6,
119
- turnTransport: this.config.forceTurnTCP === true ? "tcp" : "udp",
130
+ useTcp: this.config.iceUseTcp,
131
+ turnTransport,
132
+ turnTlsOptions: this.config.turnTlsOptions,
120
133
  useLinkLocalAddress: this.config.iceUseLinkLocalAddress,
121
134
  });
122
135
  if (existing) {
@@ -145,7 +158,7 @@ class SecureTransportManager {
145
158
  else {
146
159
  if (transceiver) {
147
160
  candidate.sdpMLineIndex = transceiver.mLineIndex;
148
- candidate.sdpMid = transceiver.mid;
161
+ candidate.sdpMid = transceiver.mid ?? undefined;
149
162
  }
150
163
  if (sctpTransport) {
151
164
  candidate.sdpMLineIndex = sctpTransport.mLineIndex;
@@ -160,28 +173,90 @@ class SecureTransportManager {
160
173
  return candidate;
161
174
  }
162
175
  async addIceCandidate(sdp, candidateMessage) {
176
+ const candidateText = candidateMessage?.candidate;
177
+ const sdpMid = candidateMessage?.sdpMid;
178
+ const sdpMLineIndex = candidateMessage?.sdpMLineIndex;
179
+ const usernameFragment = candidateMessage?.usernameFragment;
180
+ const isEndOfCandidates = candidateMessage == null || candidateText == null || candidateText === "";
181
+ const mediaIndices = this.resolveCandidateMediaIndices({
182
+ sdp,
183
+ isEndOfCandidates,
184
+ sdpMid,
185
+ sdpMLineIndex,
186
+ usernameFragment,
187
+ });
188
+ if (isEndOfCandidates) {
189
+ const candidateTarget = mediaIndices
190
+ .map((index) => this.getTransportByMLineIndex(sdp, index))
191
+ .filter((iceTransport) => !!iceTransport)
192
+ .reduce((acc, transport) => {
193
+ if (!acc.find(({ id }) => id === transport.id)) {
194
+ acc.push(transport);
195
+ }
196
+ return acc;
197
+ }, []);
198
+ await Promise.all(candidateTarget.map((iceTransport) => iceTransport.addRemoteCandidate(undefined)));
199
+ return {
200
+ kind: "end-of-candidates",
201
+ mediaIndices,
202
+ };
203
+ }
163
204
  const candidate = ice_1.IceCandidate.fromJSON(candidateMessage);
164
205
  if (!candidate) {
165
- return;
206
+ throw (0, errors_1.createWebRtcDomException)("OperationError", "Failed to parse ICE candidate");
166
207
  }
167
- let iceTransport;
168
- if (typeof candidate.sdpMid === "number") {
169
- iceTransport = this.getTransportByMid(candidate.sdpMid);
170
- }
171
- if (!iceTransport && typeof candidate.sdpMLineIndex === "number") {
172
- iceTransport = this.getTransportByMLineIndex(sdp, candidate.sdpMLineIndex);
208
+ const targetMediaIndex = mediaIndices[0];
209
+ const targetMedia = sdp.media[targetMediaIndex];
210
+ if (!targetMedia) {
211
+ throw (0, errors_1.createWebRtcDomException)("OperationError", "ICE media section not found");
173
212
  }
213
+ candidate.sdpMid = targetMedia.rtp.muxId ?? undefined;
214
+ candidate.sdpMLineIndex = targetMediaIndex;
215
+ const iceTransport = this.getTransportByMLineIndex(sdp, targetMediaIndex);
174
216
  if (!iceTransport) {
175
- iceTransport = this.iceTransports[0];
217
+ throw (0, errors_1.createWebRtcDomException)("OperationError", "ICE transport not found for candidate");
218
+ }
219
+ await iceTransport.addRemoteCandidate(candidate);
220
+ return {
221
+ kind: "candidate",
222
+ candidate,
223
+ mediaIndices: [targetMediaIndex],
224
+ };
225
+ }
226
+ resolveCandidateMediaIndices({ sdp, isEndOfCandidates, sdpMid, sdpMLineIndex, usernameFragment, }) {
227
+ let mediaIndices;
228
+ if (typeof sdpMid === "string") {
229
+ const mediaIndex = sdp.media.findIndex((media) => media.rtp.muxId === sdpMid);
230
+ if (mediaIndex < 0) {
231
+ throw (0, errors_1.createWebRtcDomException)("OperationError", "Media section for sdpMid was not found");
232
+ }
233
+ mediaIndices = [mediaIndex];
234
+ }
235
+ else if (typeof sdpMLineIndex === "number") {
236
+ if (sdpMLineIndex < 0 || sdpMLineIndex >= sdp.media.length) {
237
+ throw (0, errors_1.createWebRtcDomException)("OperationError", "Media section for sdpMLineIndex was not found");
238
+ }
239
+ mediaIndices = [sdpMLineIndex];
176
240
  }
177
- if (iceTransport) {
178
- await iceTransport.addRemoteCandidate(candidate);
241
+ else if (isEndOfCandidates) {
242
+ mediaIndices = sdp.media.map((_, index) => index);
179
243
  }
180
244
  else {
181
- log("iceTransport not found for candidate", candidate);
245
+ throw (0, errors_1.createWebRtcTypeError)("sdpMid or sdpMLineIndex must be provided with a candidate");
246
+ }
247
+ if (typeof usernameFragment === "string") {
248
+ const matchingIndices = mediaIndices.filter((index) => sdp.media[index]?.iceParams?.usernameFragment === usernameFragment);
249
+ if (matchingIndices.length === 0) {
250
+ throw (0, errors_1.createWebRtcDomException)("OperationError", "No media section matched the ICE usernameFragment");
251
+ }
252
+ mediaIndices = matchingIndices;
182
253
  }
254
+ return mediaIndices;
183
255
  }
184
256
  getTransportByMid(mid) {
257
+ if (!mid) {
258
+ return;
259
+ }
185
260
  let iceTransport;
186
261
  const transceiver = this.transceiverManager
187
262
  .getTransceivers()
@@ -210,16 +285,19 @@ class SecureTransportManager {
210
285
  setLocalRole({ type, role, }) {
211
286
  for (const dtlsTransport of this.dtlsTransports) {
212
287
  const iceTransport = dtlsTransport.iceTransport;
213
- if (type === "offer") {
288
+ if (iceTransport.connection.iceLite) {
289
+ iceTransport.connection.iceControlling = false;
290
+ }
291
+ else if (iceTransport.connection.remoteIsLite) {
292
+ // RFC 8445 S6.1.1
293
+ iceTransport.connection.iceControlling = true;
294
+ }
295
+ else if (type === "offer") {
214
296
  iceTransport.connection.iceControlling = true;
215
297
  }
216
298
  else {
217
299
  iceTransport.connection.iceControlling = false;
218
300
  }
219
- // RFC 8445 S6.1.1
220
- if (iceTransport.connection.remoteIsLite) {
221
- iceTransport.connection.iceControlling = true;
222
- }
223
301
  // # set DTLS role for mediasoup
224
302
  if (type === "answer") {
225
303
  if (role) {
@@ -314,10 +392,10 @@ class SecureTransportManager {
314
392
  this.connectionState = state;
315
393
  this.connectionStateChange.execute(state);
316
394
  }
317
- async getStats() {
395
+ async getStats(timestamp) {
318
396
  const stats = [];
319
397
  for (const dtlsTransport of this.dtlsTransports) {
320
- const transportStats = await dtlsTransport.getStats();
398
+ const transportStats = await dtlsTransport.getStats(timestamp);
321
399
  if (transportStats) {
322
400
  stats.push(...transportStats);
323
401
  }
@@ -1 +1 @@
1
- {"version":3,"file":"secureTransportManager.js","sourceRoot":"","sources":["../../../src/secureTransportManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { SRTP_PROFILE } from \"./const\";\nimport { Event, debug } from \"./imports/common\";\nimport type { RTCRtpTransceiver, TransceiverManager } from \"./media\";\nimport type { RTCStats } from \"./media/stats\";\nimport type { PeerConfig } from \"./peerConnection\";\nimport type { SctpTransportManager } from \"./sctpManager\";\nimport type { BundlePolicy, MediaDescription, SessionDescription } from \"./sdp\";\nimport {\n type DtlsKeys,\n RTCCertificate,\n RTCDtlsTransport,\n} from \"./transport/dtls\";\nimport { IceCandidate, RTCIceGatherer, RTCIceTransport } from \"./transport/ice\";\nimport type {\n IceGathererState,\n RTCIceCandidate,\n RTCIceCandidateInit,\n RTCIceConnectionState,\n} from \"./transport/ice\";\nimport type { RTCSctpTransport } from \"./transport/sctp\";\nimport type { ConnectionState } from \"./types/domain\";\nimport { parseIceServers } from \"./utils\";\n\nconst log = debug(\n \"werift:packages/webrtc/src/transport/secureTransportManager.ts\",\n);\nexport class SecureTransportManager {\n connectionState: ConnectionState = \"new\";\n iceConnectionState: RTCIceConnectionState = \"new\";\n iceGatheringState: IceGathererState = \"new\";\n certificate?: RTCCertificate;\n\n readonly iceGatheringStateChange = new Event<[IceGathererState]>();\n readonly iceConnectionStateChange = new Event<[RTCIceConnectionState]>();\n readonly onIceCandidate = new Event<[IceCandidate | undefined]>();\n readonly connectionStateChange = new Event<[ConnectionState]>();\n\n private config: PeerConfig;\n private transceiverManager: TransceiverManager;\n private sctpManager: SctpTransportManager;\n\n constructor({\n config,\n transceiverManager,\n sctpManager,\n }: {\n config: PeerConfig;\n transceiverManager: TransceiverManager;\n sctpManager: SctpTransportManager;\n }) {\n this.config = config;\n this.transceiverManager = transceiverManager;\n this.sctpManager = sctpManager;\n\n if (this.config.dtls) {\n const { keys } = this.config.dtls;\n\n if (keys) {\n this.setupCertificate(keys);\n }\n }\n }\n\n get dtlsTransports() {\n const transports = [\n ...this.transceiverManager.getTransceivers().map((t) => t?.dtlsTransport),\n this.sctpManager.sctpTransport?.dtlsTransport,\n ].filter((t) => t != undefined);\n\n return transports.reduce((acc: RTCDtlsTransport[], cur) => {\n if (!acc.map((d) => d.id).includes(cur.id)) {\n acc.push(cur);\n }\n return acc;\n }, []);\n }\n\n get iceTransports() {\n return this.dtlsTransports.map((d) => d.iceTransport);\n }\n\n setupCertificate(keys: DtlsKeys) {\n this.certificate = new RTCCertificate(\n keys.keyPem,\n keys.certPem,\n keys.signatureHash,\n );\n }\n\n createTransport() {\n const existing = this.iceTransports.find(\n (transport) => transport.state !== \"closed\",\n );\n\n const iceGatherer = new RTCIceGatherer({\n ...parseIceServers(this.config.iceServers),\n forceTurn: this.config.iceTransportPolicy === \"relay\",\n portRange: this.config.icePortRange,\n interfaceAddresses: this.config.iceInterfaceAddresses,\n additionalHostAddresses: this.config.iceAdditionalHostAddresses,\n filterStunResponse: this.config.iceFilterStunResponse,\n filterCandidatePair: this.config.iceFilterCandidatePair,\n localPasswordPrefix: this.config.icePasswordPrefix,\n useIpv4: this.config.iceUseIpv4,\n useIpv6: this.config.iceUseIpv6,\n turnTransport: this.config.forceTurnTCP === true ? \"tcp\" : \"udp\",\n useLinkLocalAddress: this.config.iceUseLinkLocalAddress,\n });\n\n if (existing) {\n iceGatherer.connection.localUsername = existing.connection.localUsername;\n iceGatherer.connection.localPassword = existing.connection.localPassword;\n }\n\n iceGatherer.onGatheringStateChange.subscribe(() => {\n this.updateIceGatheringState();\n });\n this.updateIceGatheringState();\n\n const iceTransport = new RTCIceTransport(iceGatherer);\n iceTransport.onStateChange.subscribe(() => {\n this.updateIceConnectionState();\n });\n\n const dtlsTransport = new RTCDtlsTransport(\n this.config,\n iceTransport,\n this.certificate,\n srtpProfiles,\n );\n\n return dtlsTransport;\n }\n\n handleNewIceCandidate({\n candidate,\n media,\n remoteIsBundled,\n transceiver,\n sctpTransport,\n bundlePolicy,\n }: {\n candidate: IceCandidate;\n media?: MediaDescription;\n remoteIsBundled: boolean;\n transceiver?: RTCRtpTransceiver;\n sctpTransport?: RTCSctpTransport;\n bundlePolicy?: BundlePolicy;\n }) {\n // Assign sdpMid and sdpMLineIndex\n if (bundlePolicy === \"max-bundle\" || remoteIsBundled) {\n candidate.sdpMLineIndex = 0;\n if (media) {\n candidate.sdpMid = media.rtp.muxId;\n }\n } else {\n if (transceiver) {\n candidate.sdpMLineIndex = transceiver.mLineIndex;\n candidate.sdpMid = transceiver.mid;\n }\n if (sctpTransport) {\n candidate.sdpMLineIndex = sctpTransport.mLineIndex;\n candidate.sdpMid = sctpTransport.mid;\n }\n }\n\n if (\n candidate.foundation &&\n !candidate.foundation.startsWith(\"candidate:\")\n ) {\n candidate.foundation = \"candidate:\" + candidate.foundation;\n }\n\n this.onIceCandidate.execute(candidate);\n\n return candidate;\n }\n\n async addIceCandidate(\n sdp: SessionDescription,\n candidateMessage: RTCIceCandidate | RTCIceCandidateInit,\n ) {\n const candidate = IceCandidate.fromJSON(candidateMessage);\n if (!candidate) {\n return;\n }\n\n let iceTransport: RTCIceTransport | undefined;\n\n if (typeof candidate.sdpMid === \"number\") {\n iceTransport = this.getTransportByMid(candidate.sdpMid);\n }\n\n if (!iceTransport && typeof candidate.sdpMLineIndex === \"number\") {\n iceTransport = this.getTransportByMLineIndex(\n sdp,\n candidate.sdpMLineIndex,\n );\n }\n\n if (!iceTransport) {\n iceTransport = this.iceTransports[0];\n }\n\n if (iceTransport) {\n await iceTransport.addRemoteCandidate(candidate);\n } else {\n log(\"iceTransport not found for candidate\", candidate);\n }\n }\n\n private getTransportByMid(mid: string) {\n let iceTransport: RTCIceTransport | undefined;\n\n const transceiver = this.transceiverManager\n .getTransceivers()\n .find((t) => t.mid === mid);\n if (transceiver) {\n iceTransport = transceiver.dtlsTransport.iceTransport;\n } else if (!iceTransport && this.sctpManager.sctpTransport?.mid === mid) {\n iceTransport = this.sctpManager.sctpTransport.dtlsTransport.iceTransport;\n }\n\n return iceTransport;\n }\n\n private getTransportByMLineIndex(sdp: SessionDescription, index: number) {\n const media = sdp.media[index];\n if (!media) {\n return;\n }\n const transport = this.getTransportByMid(media.rtp.muxId!);\n\n return transport;\n }\n\n restartIce() {\n for (const transport of this.iceTransports) {\n transport.restart();\n }\n }\n\n setLocalRole({\n type,\n role,\n }: {\n type: \"offer\" | \"answer\";\n role: \"auto\" | \"client\" | \"server\" | undefined;\n }) {\n for (const dtlsTransport of this.dtlsTransports) {\n const iceTransport = dtlsTransport.iceTransport;\n if (type === \"offer\") {\n iceTransport.connection.iceControlling = true;\n } else {\n iceTransport.connection.iceControlling = false;\n }\n // RFC 8445 S6.1.1\n if (iceTransport.connection.remoteIsLite) {\n iceTransport.connection.iceControlling = true;\n }\n\n // # set DTLS role for mediasoup\n if (type === \"answer\") {\n if (role) {\n dtlsTransport.role = role;\n }\n }\n }\n }\n\n // https://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate\n private updateIceGatheringState() {\n const all = this.iceTransports;\n\n function allMatch(...state: IceGathererState[]) {\n return (\n all.filter((check) => state.includes(check.gatheringState)).length ===\n all.length\n );\n }\n\n let newState: IceGathererState;\n\n if (all.length && allMatch(\"complete\")) {\n newState = \"complete\";\n } else if (!all.length || allMatch(\"new\", \"complete\")) {\n newState = \"new\";\n } else if (all.map((check) => check.gatheringState).includes(\"gathering\")) {\n newState = \"gathering\";\n } else {\n newState = \"new\";\n }\n\n if (this.iceGatheringState === newState) {\n return;\n }\n\n this.iceGatheringState = newState;\n this.iceGatheringStateChange.execute(newState);\n }\n\n // https://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate\n updateIceConnectionState() {\n const all = this.iceTransports;\n let newState: RTCIceConnectionState;\n\n function allMatch(...state: RTCIceConnectionState[]) {\n return (\n all.filter((check) => state.includes(check.state)).length === all.length\n );\n }\n\n function anyMatch(...state: RTCIceConnectionState[]) {\n return all.some((check) => state.includes(check.state));\n }\n\n if (this.connectionState === \"closed\") {\n newState = \"closed\";\n } else if (anyMatch(\"failed\")) {\n newState = \"failed\";\n } else if (anyMatch(\"disconnected\")) {\n newState = \"disconnected\";\n } else if (allMatch(\"new\", \"closed\")) {\n newState = \"new\";\n } else if (anyMatch(\"new\", \"checking\")) {\n newState = \"checking\";\n } else if (allMatch(\"completed\", \"closed\")) {\n newState = \"completed\";\n } else if (allMatch(\"connected\", \"completed\", \"closed\")) {\n newState = \"connected\";\n } else {\n // unreachable?\n newState = \"new\";\n }\n\n if (this.iceConnectionState === newState) {\n return;\n }\n\n log(\"iceConnectionStateChange\", newState);\n this.iceConnectionState = newState;\n this.iceConnectionStateChange.execute(newState);\n }\n\n async gatherCandidates(remoteIsBundled: boolean) {\n const connected = this.iceTransports.find(\n (transport) =>\n transport.state === \"connected\" || transport.state === \"completed\",\n );\n if (remoteIsBundled && connected) {\n // no need to gather ice candidates on an existing bundled connection\n log(\"skipping ICE gathering for bundled connection\");\n } else {\n await Promise.allSettled(\n this.iceTransports.map((iceTransport) => iceTransport.gather()),\n ).catch((e) => {\n // エラーハンドリングを追加 (例: ログ出力)\n log(\"gatherCandidates failed\", e);\n });\n }\n }\n\n setConnectionState(state: ConnectionState) {\n log(\"connectionStateChange\", state);\n this.connectionState = state;\n this.connectionStateChange.execute(state);\n }\n\n async getStats(): Promise<RTCStats[]> {\n const stats: RTCStats[] = [];\n\n for (const dtlsTransport of this.dtlsTransports) {\n const transportStats = await dtlsTransport.getStats();\n if (transportStats) {\n stats.push(...transportStats);\n }\n }\n\n return stats;\n }\n\n async ensureCerts() {\n if (!this.certificate) {\n this.certificate = await RTCDtlsTransport.SetupCertificate();\n }\n\n for (const dtlsTransport of this.dtlsTransports) {\n dtlsTransport.localCertificate = this.certificate;\n }\n }\n\n async close() {\n this.setConnectionState(\"closed\");\n\n await Promise.allSettled([...this.dtlsTransports.map((t) => t.stop())]);\n\n this.iceGatheringStateChange.allUnsubscribe();\n this.iceConnectionStateChange.allUnsubscribe();\n this.onIceCandidate.allUnsubscribe();\n this.connectionStateChange.allUnsubscribe();\n }\n}\n\nconst srtpProfiles = [\n SRTP_PROFILE.SRTP_AEAD_AES_128_GCM, // prefer\n SRTP_PROFILE.SRTP_AES128_CM_HMAC_SHA1_80,\n];\n"]}
1
+ {"version":3,"file":"secureTransportManager.js","sourceRoot":"","sources":["../../../src/secureTransportManager.ts"],"names":[],"mappings":"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","sourcesContent":["import { SRTP_PROFILE } from \"./const\";\nimport { createWebRtcDomException, createWebRtcTypeError } from \"./errors\";\nimport { Event, debug } from \"./imports/common\";\nimport type { RTCRtpTransceiver, TransceiverManager } from \"./media\";\nimport type { RTCStats } from \"./media/stats\";\nimport type { PeerConfig } from \"./peerConnection\";\nimport type { SctpTransportManager } from \"./sctpManager\";\nimport type { BundlePolicy, MediaDescription, SessionDescription } from \"./sdp\";\nimport {\n type DtlsKeys,\n RTCCertificate,\n RTCDtlsTransport,\n} from \"./transport/dtls\";\nimport { IceCandidate, RTCIceGatherer, RTCIceTransport } from \"./transport/ice\";\nimport type {\n IceGathererState,\n RTCIceCandidate,\n RTCIceCandidateInit,\n RTCIceConnectionState,\n} from \"./transport/ice\";\nimport type { RTCSctpTransport } from \"./transport/sctp\";\nimport type { ConnectionState } from \"./types/domain\";\nimport { parseIceServers, resolveTurnTransport } from \"./utils\";\n\nconst log = debug(\n \"werift:packages/webrtc/src/transport/secureTransportManager.ts\",\n);\nexport class SecureTransportManager {\n connectionState: ConnectionState = \"new\";\n iceConnectionState: RTCIceConnectionState = \"new\";\n iceGatheringState: IceGathererState = \"new\";\n certificate?: RTCCertificate;\n\n readonly iceGatheringStateChange = new Event<[IceGathererState]>();\n readonly iceConnectionStateChange = new Event<[RTCIceConnectionState]>();\n readonly onIceCandidate = new Event<[IceCandidate | undefined]>();\n readonly connectionStateChange = new Event<[ConnectionState]>();\n\n private config: PeerConfig;\n private transceiverManager: TransceiverManager;\n private sctpManager: SctpTransportManager;\n\n constructor({\n config,\n transceiverManager,\n sctpManager,\n }: {\n config: PeerConfig;\n transceiverManager: TransceiverManager;\n sctpManager: SctpTransportManager;\n }) {\n this.config = config;\n this.transceiverManager = transceiverManager;\n this.sctpManager = sctpManager;\n\n if (this.config.dtls) {\n const { keys } = this.config.dtls;\n\n if (this.config.certificates[0]) {\n this.certificate = this.config.certificates[0];\n } else if (keys) {\n this.setupCertificate(keys);\n }\n }\n }\n\n get dtlsTransports() {\n const transports = [\n ...this.transceiverManager.getTransceivers().map((t) => t?.dtlsTransport),\n this.sctpManager.sctpTransport?.dtlsTransport,\n ].filter((t) => t != undefined);\n\n return transports.reduce((acc: RTCDtlsTransport[], cur) => {\n if (!acc.map((d) => d.id).includes(cur.id)) {\n acc.push(cur);\n }\n return acc;\n }, []);\n }\n\n get iceTransports() {\n return this.dtlsTransports.map((d) => d.iceTransport);\n }\n\n setupCertificate(keys: DtlsKeys) {\n this.certificate = new RTCCertificate(\n keys.keyPem,\n keys.certPem,\n keys.signatureHash,\n );\n }\n\n createTransport() {\n const existing = this.iceTransports.find(\n (transport) => transport.state !== \"closed\",\n );\n const iceServerOptions = parseIceServers(this.config.iceServers);\n const turnTransport = resolveTurnTransport({\n parsedTurnTransport: iceServerOptions.turnTransport,\n configuredTurnTransport: this.config.turnTransport,\n forceTurnTCP: this.config.forceTurnTCP,\n });\n\n const iceGatherer = new RTCIceGatherer({\n ...iceServerOptions,\n iceLite: this.config.iceLite,\n forceTurn: this.config.iceTransportPolicy === \"relay\",\n portRange: this.config.icePortRange,\n interfaceAddresses: this.config.iceInterfaceAddresses,\n additionalHostAddresses: this.config.iceAdditionalHostAddresses,\n filterStunResponse: this.config.iceFilterStunResponse,\n filterCandidatePair: this.config.iceFilterCandidatePair,\n localPasswordPrefix: this.config.icePasswordPrefix,\n useIpv4: this.config.iceUseIpv4,\n useIpv6: this.config.iceUseIpv6,\n useTcp: this.config.iceUseTcp,\n turnTransport,\n turnTlsOptions: this.config.turnTlsOptions,\n useLinkLocalAddress: this.config.iceUseLinkLocalAddress,\n });\n\n if (existing) {\n iceGatherer.connection.localUsername = existing.connection.localUsername;\n iceGatherer.connection.localPassword = existing.connection.localPassword;\n }\n\n iceGatherer.onGatheringStateChange.subscribe(() => {\n this.updateIceGatheringState();\n });\n this.updateIceGatheringState();\n\n const iceTransport = new RTCIceTransport(iceGatherer);\n iceTransport.onStateChange.subscribe(() => {\n this.updateIceConnectionState();\n });\n\n const dtlsTransport = new RTCDtlsTransport(\n this.config,\n iceTransport,\n this.certificate,\n srtpProfiles,\n );\n\n return dtlsTransport;\n }\n\n handleNewIceCandidate({\n candidate,\n media,\n remoteIsBundled,\n transceiver,\n sctpTransport,\n bundlePolicy,\n }: {\n candidate: IceCandidate;\n media?: MediaDescription;\n remoteIsBundled: boolean;\n transceiver?: RTCRtpTransceiver;\n sctpTransport?: RTCSctpTransport;\n bundlePolicy?: BundlePolicy;\n }) {\n // Assign sdpMid and sdpMLineIndex\n if (bundlePolicy === \"max-bundle\" || remoteIsBundled) {\n candidate.sdpMLineIndex = 0;\n if (media) {\n candidate.sdpMid = media.rtp.muxId;\n }\n } else {\n if (transceiver) {\n candidate.sdpMLineIndex = transceiver.mLineIndex;\n candidate.sdpMid = transceiver.mid ?? undefined;\n }\n if (sctpTransport) {\n candidate.sdpMLineIndex = sctpTransport.mLineIndex;\n candidate.sdpMid = sctpTransport.mid;\n }\n }\n\n if (\n candidate.foundation &&\n !candidate.foundation.startsWith(\"candidate:\")\n ) {\n candidate.foundation = \"candidate:\" + candidate.foundation;\n }\n\n this.onIceCandidate.execute(candidate);\n\n return candidate;\n }\n\n async addIceCandidate(\n sdp: SessionDescription,\n candidateMessage: RTCIceCandidate | RTCIceCandidateInit | null,\n ) {\n const candidateText = candidateMessage?.candidate;\n const sdpMid = candidateMessage?.sdpMid;\n const sdpMLineIndex = candidateMessage?.sdpMLineIndex;\n const usernameFragment = candidateMessage?.usernameFragment;\n const isEndOfCandidates =\n candidateMessage == null || candidateText == null || candidateText === \"\";\n const mediaIndices = this.resolveCandidateMediaIndices({\n sdp,\n isEndOfCandidates,\n sdpMid,\n sdpMLineIndex,\n usernameFragment,\n });\n\n if (isEndOfCandidates) {\n const candidateTarget = mediaIndices\n .map((index) => this.getTransportByMLineIndex(sdp, index))\n .filter(\n (iceTransport): iceTransport is RTCIceTransport => !!iceTransport,\n )\n .reduce((acc: RTCIceTransport[], transport) => {\n if (!acc.find(({ id }) => id === transport.id)) {\n acc.push(transport);\n }\n return acc;\n }, []);\n\n await Promise.all(\n candidateTarget.map((iceTransport) =>\n iceTransport.addRemoteCandidate(undefined),\n ),\n );\n return {\n kind: \"end-of-candidates\" as const,\n mediaIndices,\n };\n }\n\n const candidate = IceCandidate.fromJSON(candidateMessage);\n if (!candidate) {\n throw createWebRtcDomException(\n \"OperationError\",\n \"Failed to parse ICE candidate\",\n );\n }\n\n const targetMediaIndex = mediaIndices[0];\n const targetMedia = sdp.media[targetMediaIndex];\n if (!targetMedia) {\n throw createWebRtcDomException(\n \"OperationError\",\n \"ICE media section not found\",\n );\n }\n candidate.sdpMid = targetMedia.rtp.muxId ?? undefined;\n candidate.sdpMLineIndex = targetMediaIndex;\n\n const iceTransport = this.getTransportByMLineIndex(sdp, targetMediaIndex);\n\n if (!iceTransport) {\n throw createWebRtcDomException(\n \"OperationError\",\n \"ICE transport not found for candidate\",\n );\n }\n\n await iceTransport.addRemoteCandidate(candidate);\n return {\n kind: \"candidate\" as const,\n candidate,\n mediaIndices: [targetMediaIndex],\n };\n }\n\n private resolveCandidateMediaIndices({\n sdp,\n isEndOfCandidates,\n sdpMid,\n sdpMLineIndex,\n usernameFragment,\n }: {\n sdp: SessionDescription;\n isEndOfCandidates: boolean;\n sdpMid?: string | null;\n sdpMLineIndex?: number | null;\n usernameFragment?: string | null;\n }) {\n let mediaIndices: number[];\n\n if (typeof sdpMid === \"string\") {\n const mediaIndex = sdp.media.findIndex(\n (media) => media.rtp.muxId === sdpMid,\n );\n if (mediaIndex < 0) {\n throw createWebRtcDomException(\n \"OperationError\",\n \"Media section for sdpMid was not found\",\n );\n }\n mediaIndices = [mediaIndex];\n } else if (typeof sdpMLineIndex === \"number\") {\n if (sdpMLineIndex < 0 || sdpMLineIndex >= sdp.media.length) {\n throw createWebRtcDomException(\n \"OperationError\",\n \"Media section for sdpMLineIndex was not found\",\n );\n }\n mediaIndices = [sdpMLineIndex];\n } else if (isEndOfCandidates) {\n mediaIndices = sdp.media.map((_, index) => index);\n } else {\n throw createWebRtcTypeError(\n \"sdpMid or sdpMLineIndex must be provided with a candidate\",\n );\n }\n\n if (typeof usernameFragment === \"string\") {\n const matchingIndices = mediaIndices.filter(\n (index) =>\n sdp.media[index]?.iceParams?.usernameFragment === usernameFragment,\n );\n if (matchingIndices.length === 0) {\n throw createWebRtcDomException(\n \"OperationError\",\n \"No media section matched the ICE usernameFragment\",\n );\n }\n mediaIndices = matchingIndices;\n }\n\n return mediaIndices;\n }\n\n private getTransportByMid(mid?: string) {\n if (!mid) {\n return;\n }\n let iceTransport: RTCIceTransport | undefined;\n\n const transceiver = this.transceiverManager\n .getTransceivers()\n .find((t) => t.mid === mid);\n if (transceiver) {\n iceTransport = transceiver.dtlsTransport.iceTransport;\n } else if (!iceTransport && this.sctpManager.sctpTransport?.mid === mid) {\n iceTransport = this.sctpManager.sctpTransport.dtlsTransport.iceTransport;\n }\n\n return iceTransport;\n }\n\n private getTransportByMLineIndex(sdp: SessionDescription, index: number) {\n const media = sdp.media[index];\n if (!media) {\n return;\n }\n const transport = this.getTransportByMid(media.rtp.muxId!);\n\n return transport;\n }\n\n restartIce() {\n for (const transport of this.iceTransports) {\n transport.restart();\n }\n }\n\n setLocalRole({\n type,\n role,\n }: {\n type: \"offer\" | \"answer\";\n role: \"auto\" | \"client\" | \"server\" | undefined;\n }) {\n for (const dtlsTransport of this.dtlsTransports) {\n const iceTransport = dtlsTransport.iceTransport;\n if (iceTransport.connection.iceLite) {\n iceTransport.connection.iceControlling = false;\n } else if (iceTransport.connection.remoteIsLite) {\n // RFC 8445 S6.1.1\n iceTransport.connection.iceControlling = true;\n } else if (type === \"offer\") {\n iceTransport.connection.iceControlling = true;\n } else {\n iceTransport.connection.iceControlling = false;\n }\n\n // # set DTLS role for mediasoup\n if (type === \"answer\") {\n if (role) {\n dtlsTransport.role = role;\n }\n }\n }\n }\n\n // https://w3c.github.io/webrtc-pc/#dom-rtcicegatheringstate\n private updateIceGatheringState() {\n const all = this.iceTransports;\n\n function allMatch(...state: IceGathererState[]) {\n return (\n all.filter((check) => state.includes(check.gatheringState)).length ===\n all.length\n );\n }\n\n let newState: IceGathererState;\n\n if (all.length && allMatch(\"complete\")) {\n newState = \"complete\";\n } else if (!all.length || allMatch(\"new\", \"complete\")) {\n newState = \"new\";\n } else if (all.map((check) => check.gatheringState).includes(\"gathering\")) {\n newState = \"gathering\";\n } else {\n newState = \"new\";\n }\n\n if (this.iceGatheringState === newState) {\n return;\n }\n\n this.iceGatheringState = newState;\n this.iceGatheringStateChange.execute(newState);\n }\n\n // https://w3c.github.io/webrtc-pc/#dom-rtciceconnectionstate\n updateIceConnectionState() {\n const all = this.iceTransports;\n let newState: RTCIceConnectionState;\n\n function allMatch(...state: RTCIceConnectionState[]) {\n return (\n all.filter((check) => state.includes(check.state)).length === all.length\n );\n }\n\n function anyMatch(...state: RTCIceConnectionState[]) {\n return all.some((check) => state.includes(check.state));\n }\n\n if (this.connectionState === \"closed\") {\n newState = \"closed\";\n } else if (anyMatch(\"failed\")) {\n newState = \"failed\";\n } else if (anyMatch(\"disconnected\")) {\n newState = \"disconnected\";\n } else if (allMatch(\"new\", \"closed\")) {\n newState = \"new\";\n } else if (anyMatch(\"new\", \"checking\")) {\n newState = \"checking\";\n } else if (allMatch(\"completed\", \"closed\")) {\n newState = \"completed\";\n } else if (allMatch(\"connected\", \"completed\", \"closed\")) {\n newState = \"connected\";\n } else {\n // unreachable?\n newState = \"new\";\n }\n\n if (this.iceConnectionState === newState) {\n return;\n }\n\n log(\"iceConnectionStateChange\", newState);\n this.iceConnectionState = newState;\n this.iceConnectionStateChange.execute(newState);\n }\n\n async gatherCandidates(remoteIsBundled: boolean) {\n const connected = this.iceTransports.find(\n (transport) =>\n transport.state === \"connected\" || transport.state === \"completed\",\n );\n if (remoteIsBundled && connected) {\n // no need to gather ice candidates on an existing bundled connection\n log(\"skipping ICE gathering for bundled connection\");\n } else {\n await Promise.allSettled(\n this.iceTransports.map((iceTransport) => iceTransport.gather()),\n ).catch((e) => {\n // エラーハンドリングを追加 (例: ログ出力)\n log(\"gatherCandidates failed\", e);\n });\n }\n }\n\n setConnectionState(state: ConnectionState) {\n log(\"connectionStateChange\", state);\n this.connectionState = state;\n this.connectionStateChange.execute(state);\n }\n\n async getStats(timestamp?: number): Promise<RTCStats[]> {\n const stats: RTCStats[] = [];\n\n for (const dtlsTransport of this.dtlsTransports) {\n const transportStats = await dtlsTransport.getStats(timestamp);\n if (transportStats) {\n stats.push(...transportStats);\n }\n }\n\n return stats;\n }\n\n async ensureCerts() {\n if (!this.certificate) {\n this.certificate = await RTCDtlsTransport.SetupCertificate();\n }\n\n for (const dtlsTransport of this.dtlsTransports) {\n dtlsTransport.localCertificate = this.certificate;\n }\n }\n\n async close() {\n this.setConnectionState(\"closed\");\n\n await Promise.allSettled([...this.dtlsTransports.map((t) => t.stop())]);\n\n this.iceGatheringStateChange.allUnsubscribe();\n this.iceConnectionStateChange.allUnsubscribe();\n this.onIceCandidate.allUnsubscribe();\n this.connectionStateChange.allUnsubscribe();\n }\n}\n\nconst srtpProfiles = [\n SRTP_PROFILE.SRTP_AEAD_AES_128_GCM, // prefer\n SRTP_PROFILE.SRTP_AES128_CM_HMAC_SHA1_80,\n];\n"]}
@@ -15,7 +15,7 @@ export declare class TransceiverManager {
15
15
  readonly onTrack: Event<[{
16
16
  track: MediaStreamTrack;
17
17
  transceiver: RTCRtpTransceiver;
18
- stream: MediaStream;
18
+ streams: MediaStream[];
19
19
  }]>;
20
20
  readonly onNegotiationNeeded: Event<[]>;
21
21
  constructor(cname: string, config: Required<PeerConfig>, router: RtpRouter);
@@ -26,13 +26,14 @@ export declare class TransceiverManager {
26
26
  pushTransceiver(t: RTCRtpTransceiver): void;
27
27
  replaceTransceiver(t: RTCRtpTransceiver, index: number): void;
28
28
  addTransceiver(trackOrKind: Kind | MediaStreamTrack, dtlsTransport?: RTCDtlsTransport, options?: Partial<TransceiverOptions>): RTCRtpTransceiver;
29
- addTrack(track: MediaStreamTrack, ms?: MediaStream): RTCRtpTransceiver;
29
+ addTrack(track: MediaStreamTrack, streams?: MediaStream[]): RTCRtpTransceiver;
30
30
  removeTrack(sender: RTCRtpSender): void;
31
31
  assignTransceiverCodecs(transceiver: RTCRtpTransceiver): void;
32
32
  getLocalRtpParams(transceiver: RTCRtpTransceiver): RTCRtpParameters;
33
33
  getRemoteRtpParams(media: MediaDescription, transceiver: RTCRtpTransceiver): RTCRtpReceiveParameters;
34
- setRemoteRTP(transceiver: RTCRtpTransceiver, remoteMedia: MediaDescription, type: "offer" | "answer", mLineIndex: number): void;
35
- getStats(selector?: MediaStreamTrack | null): Promise<RTCStats[]>;
34
+ setRemoteRTP(transceiver: RTCRtpTransceiver, remoteMedia: MediaDescription, type: "offer" | "answer" | "pranswer", mLineIndex: number): void;
35
+ collectStats(timestamp: number): RTCStats[];
36
+ getStatsRootIds(selector: MediaStreamTrack | null | undefined): string[];
36
37
  /**
37
38
  * 全トランシーバーのreceiver/senderのstopを呼ぶcloseメソッド
38
39
  */
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TransceiverManager = void 0;
4
4
  const const_1 = require("./const");
5
+ const errors_1 = require("./errors");
5
6
  const common_1 = require("./imports/common");
6
7
  const media_1 = require("./media");
7
8
  const peerConnection_1 = require("./peerConnection");
@@ -84,6 +85,8 @@ class TransceiverManager {
84
85
  const receiver = new media_1.RTCRtpReceiver(this.config, kind, sender.ssrc);
85
86
  const newTransceiver = new media_1.RTCRtpTransceiver(kind, dtlsTransport, receiver, sender, direction);
86
87
  newTransceiver.options = options;
88
+ newTransceiver.sender.setStreams(options.streams ?? []);
89
+ newTransceiver.sender.setSendEncodings((options.sendEncodings ?? []).map((encoding) => ({ ...encoding })));
87
90
  this.router.registerRtpSender(newTransceiver.sender);
88
91
  // reuse inactive
89
92
  const inactiveTransceiverIndex = this.transceivers.findIndex((t) => t.currentDirection === "inactive" && !t.usedForSender);
@@ -100,16 +103,21 @@ class TransceiverManager {
100
103
  this.onTransceiverAdded.execute(newTransceiver);
101
104
  return newTransceiver;
102
105
  }
103
- addTrack(track, ms) {
106
+ addTrack(track, streams = []) {
104
107
  if (this.getSenders().find((sender) => sender.track?.uuid === track.uuid)) {
105
- throw new Error("Track already added");
108
+ throw (0, errors_1.createWebRtcDomException)("InvalidAccessError", "Track already added");
106
109
  }
107
110
  const emptyTrackSenderTransceiver = this.transceivers.find((t) => t.sender.track == undefined &&
108
111
  t.kind === track.kind &&
109
112
  const_1.SenderDirections.includes(t.direction) === true);
110
113
  if (emptyTrackSenderTransceiver) {
111
114
  const sender = emptyTrackSenderTransceiver.sender;
115
+ sender.setStreams(streams);
112
116
  sender.registerTrack(track);
117
+ emptyTrackSenderTransceiver.options = {
118
+ ...emptyTrackSenderTransceiver.options,
119
+ streams,
120
+ };
113
121
  return emptyTrackSenderTransceiver;
114
122
  }
115
123
  const notSendTransceiver = this.transceivers.find((t) => t.sender.track == undefined &&
@@ -118,7 +126,12 @@ class TransceiverManager {
118
126
  !t.usedForSender);
119
127
  if (notSendTransceiver) {
120
128
  const sender = notSendTransceiver.sender;
129
+ sender.setStreams(streams);
121
130
  sender.registerTrack(track);
131
+ notSendTransceiver.options = {
132
+ ...notSendTransceiver.options,
133
+ streams,
134
+ };
122
135
  switch (notSendTransceiver.direction) {
123
136
  case "recvonly":
124
137
  notSendTransceiver.setDirection("sendrecv");
@@ -132,33 +145,32 @@ class TransceiverManager {
132
145
  else {
133
146
  const transceiver = this.addTransceiver(track, undefined, {
134
147
  direction: "sendrecv",
148
+ streams,
135
149
  });
136
150
  return transceiver;
137
151
  }
138
152
  }
139
153
  removeTrack(sender) {
140
154
  if (!this.getSenders().find(({ ssrc }) => sender.ssrc === ssrc)) {
141
- throw new Error("Sender does not exist");
155
+ throw (0, errors_1.createWebRtcDomException)("InvalidAccessError", "Sender does not exist");
142
156
  }
143
157
  const transceiver = this.transceivers.find(({ sender: { ssrc } }) => sender.ssrc === ssrc);
144
158
  if (!transceiver)
145
159
  throw new Error("No matching transceiver found");
160
+ if (transceiver.stopping || transceiver.stopped) {
161
+ return;
162
+ }
146
163
  sender.stop();
147
- if (transceiver.currentDirection === "recvonly") {
164
+ if (["recvonly", "inactive"].includes(transceiver.currentDirection ?? "")) {
148
165
  this.onNegotiationNeeded.execute();
149
166
  return;
150
167
  }
151
- if (transceiver.stopping || transceiver.stopped) {
152
- transceiver.setDirection("inactive");
168
+ if (transceiver.direction === "sendrecv") {
169
+ transceiver.setDirection("recvonly");
153
170
  }
154
- else {
155
- if (transceiver.direction === "sendrecv") {
156
- transceiver.setDirection("recvonly");
157
- }
158
- else if (transceiver.direction === "sendonly" ||
159
- transceiver.direction === "recvonly") {
160
- transceiver.setDirection("inactive");
161
- }
171
+ else if (transceiver.direction === "sendonly" ||
172
+ transceiver.direction === "recvonly") {
173
+ transceiver.setDirection("inactive");
162
174
  }
163
175
  }
164
176
  assignTransceiverCodecs(transceiver) {
@@ -225,7 +237,7 @@ class TransceiverManager {
225
237
  }
226
238
  setRemoteRTP(transceiver, remoteMedia, type, mLineIndex) {
227
239
  if (!transceiver.mid) {
228
- transceiver.mid = remoteMedia.rtp.muxId;
240
+ transceiver.mid = remoteMedia.rtp.muxId ?? null;
229
241
  }
230
242
  transceiver.mLineIndex = mLineIndex;
231
243
  // # negotiate codecs
@@ -273,78 +285,65 @@ class TransceiverManager {
273
285
  // register ssrc receiver
274
286
  this.router.registerRtpReceiverBySsrc(transceiver, remotePrams);
275
287
  }
276
- if (["sendonly", "sendrecv"].includes(mediaDirection)) {
277
- if (remoteMedia.msid) {
278
- const [streamId, trackId] = remoteMedia.msid.split(" ");
279
- transceiver.receiver.remoteStreamId = streamId;
280
- transceiver.receiver.remoteTrackId = trackId;
281
- }
288
+ if (remoteMedia.port !== 0 &&
289
+ ["sendonly", "sendrecv"].includes(mediaDirection)) {
290
+ const remoteStreamIds = [
291
+ ...new Set(remoteMedia.msids.map((msid) => msid.split(" ")[0])),
292
+ ];
293
+ const remoteTrackId = remoteMedia.msids[0]?.split(" ")[1];
294
+ transceiver.receiver.remoteStreamId = remoteStreamIds[0];
295
+ transceiver.receiver.remoteStreamIds = remoteStreamIds;
296
+ transceiver.receiver.remoteTrackId = remoteTrackId;
282
297
  this.onTrack.execute({
283
298
  track: transceiver.receiver.track,
284
299
  transceiver,
285
- stream: new media_1.MediaStream({
286
- id: transceiver.receiver.remoteStreamId,
300
+ streams: remoteStreamIds.map((id) => new media_1.MediaStream({
301
+ id,
287
302
  tracks: [transceiver.receiver.track],
288
- }),
303
+ })),
289
304
  });
290
305
  }
291
306
  if (remoteMedia.ssrc[0]?.ssrc) {
292
307
  transceiver.receiver.setupTWCC(remoteMedia.ssrc[0].ssrc);
293
308
  }
294
309
  }
295
- async getStats(selector) {
310
+ collectStats(timestamp) {
296
311
  const stats = [];
297
312
  for (const transceiver of this.transceivers) {
298
- const includeTransceiverStats = !selector ||
299
- transceiver.sender.track === selector ||
300
- transceiver.receiver.track === selector;
301
313
  if (transceiver.sender) {
302
- const senderStats = await transceiver.sender.getStats();
303
- if (senderStats) {
304
- for (const stat of senderStats) {
305
- if (stat.type === "outbound-rtp" || stat.type === "media-source") {
306
- if (includeTransceiverStats) {
307
- stats.push(stat);
308
- }
309
- }
310
- else {
311
- stats.push(stat);
312
- }
313
- }
314
- }
314
+ stats.push(...transceiver.sender.collectStats(timestamp));
315
315
  }
316
316
  if (transceiver.receiver) {
317
- const receiverStats = await transceiver.receiver.getStats();
318
- if (receiverStats) {
319
- for (const stat of receiverStats) {
320
- if (stat.type === "inbound-rtp" ||
321
- stat.type === "remote-outbound-rtp") {
322
- if (includeTransceiverStats) {
323
- stats.push(stat);
324
- }
325
- }
326
- else {
327
- stats.push(stat);
328
- }
329
- }
330
- }
317
+ stats.push(...transceiver.receiver.collectStats(timestamp));
331
318
  }
332
- if (includeTransceiverStats) {
333
- const codecStats = transceiver.getCodecStats();
334
- if (codecStats) {
335
- stats.push(...codecStats);
336
- }
319
+ const codecStats = transceiver.collectCodecStats(timestamp);
320
+ if (codecStats) {
321
+ stats.push(...codecStats);
337
322
  }
338
323
  }
339
324
  return stats;
340
325
  }
326
+ getStatsRootIds(selector) {
327
+ if (!selector) {
328
+ return [];
329
+ }
330
+ const rootIds = [];
331
+ for (const transceiver of this.transceivers) {
332
+ if (transceiver.sender.track === selector) {
333
+ rootIds.push(...transceiver.sender.getStatsRootIds());
334
+ }
335
+ if (transceiver.receiver.tracks.includes(selector)) {
336
+ rootIds.push(...transceiver.receiver.getStatsRootIds(selector));
337
+ }
338
+ }
339
+ return rootIds;
340
+ }
341
341
  /**
342
342
  * 全トランシーバーのreceiver/senderのstopを呼ぶcloseメソッド
343
343
  */
344
344
  close() {
345
345
  for (const transceiver of this.transceivers) {
346
- transceiver.receiver.stop();
347
- transceiver.sender.stop();
346
+ transceiver.forceStop();
348
347
  }
349
348
  this.onTransceiverAdded.allUnsubscribe();
350
349
  this.onRemoteTransceiverAdded.allUnsubscribe();