werift 0.22.9 → 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 (173) 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/dtls/src/flight/server/flight6.js +12 -2
  6. package/lib/dtls/src/flight/server/flight6.js.map +1 -1
  7. package/lib/dtls/src/server.js +6 -1
  8. package/lib/dtls/src/server.js.map +1 -1
  9. package/lib/dtls/src/socket.d.ts +1 -0
  10. package/lib/dtls/src/socket.js +3 -0
  11. package/lib/dtls/src/socket.js.map +1 -1
  12. package/lib/ice/src/candidate.d.ts +16 -1
  13. package/lib/ice/src/candidate.js +99 -15
  14. package/lib/ice/src/candidate.js.map +1 -1
  15. package/lib/ice/src/ice.d.ts +2 -0
  16. package/lib/ice/src/ice.js +171 -41
  17. package/lib/ice/src/ice.js.map +1 -1
  18. package/lib/ice/src/iceBase.d.ts +23 -2
  19. package/lib/ice/src/iceBase.js +63 -1
  20. package/lib/ice/src/iceBase.js.map +1 -1
  21. package/lib/ice/src/index.d.ts +2 -0
  22. package/lib/ice/src/index.js +2 -0
  23. package/lib/ice/src/index.js.map +1 -1
  24. package/lib/ice/src/stun/const.d.ts +1 -26
  25. package/lib/ice/src/stun/const.js +15 -54
  26. package/lib/ice/src/stun/const.js.map +1 -1
  27. package/lib/ice/src/stun/message.d.ts +1 -25
  28. package/lib/ice/src/stun/message.js +15 -149
  29. package/lib/ice/src/stun/message.js.map +1 -1
  30. package/lib/ice/src/stun/protocol.d.ts +1 -1
  31. package/lib/ice/src/stun/protocol.js +2 -2
  32. package/lib/ice/src/stun/protocol.js.map +1 -1
  33. package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
  34. package/lib/ice/src/stun/tcpFrame.js +26 -0
  35. package/lib/ice/src/stun/tcpFrame.js.map +1 -0
  36. package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
  37. package/lib/ice/src/stun/tcpProtocol.js +326 -0
  38. package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
  39. package/lib/ice/src/stun/transaction.d.ts +2 -1
  40. package/lib/ice/src/stun/transaction.js +9 -3
  41. package/lib/ice/src/stun/transaction.js.map +1 -1
  42. package/lib/ice/src/turn/frame.d.ts +1 -0
  43. package/lib/ice/src/turn/frame.js +18 -0
  44. package/lib/ice/src/turn/frame.js.map +1 -0
  45. package/lib/ice/src/turn/protocol.d.ts +9 -7
  46. package/lib/ice/src/turn/protocol.js +32 -44
  47. package/lib/ice/src/turn/protocol.js.map +1 -1
  48. package/lib/ice/src/types/model.d.ts +1 -1
  49. package/lib/ice/src/types/model.js.map +1 -1
  50. package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
  51. package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
  52. package/lib/ice-server/src/stun/attributes.js.map +1 -0
  53. package/lib/ice-server/src/stun/const.d.ts +28 -0
  54. package/lib/ice-server/src/stun/const.js +88 -0
  55. package/lib/ice-server/src/stun/const.js.map +1 -0
  56. package/lib/ice-server/src/stun/message.d.ts +37 -0
  57. package/lib/ice-server/src/stun/message.js +190 -0
  58. package/lib/ice-server/src/stun/message.js.map +1 -0
  59. package/lib/ice-server/src/turn/auth.d.ts +1 -0
  60. package/lib/ice-server/src/turn/auth.js +10 -0
  61. package/lib/ice-server/src/turn/auth.js.map +1 -0
  62. package/lib/ice-server/src/turn/frame.d.ts +13 -0
  63. package/lib/ice-server/src/turn/frame.js +69 -0
  64. package/lib/ice-server/src/turn/frame.js.map +1 -0
  65. package/lib/index.mjs +3075 -883
  66. package/lib/nonstandard/index.mjs +1964 -447
  67. package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
  68. package/lib/rtp/src/extra/container/mp4/container.js +258 -173
  69. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  70. package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
  71. package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
  72. package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
  73. package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
  74. package/lib/rtp/src/extra/processor/mp4.js +115 -60
  75. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  76. package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
  77. package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
  78. package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
  79. package/lib/rtp/src/index.d.ts +1 -0
  80. package/lib/rtp/src/index.js +1 -0
  81. package/lib/rtp/src/index.js.map +1 -1
  82. package/lib/rtp/src/srtp/cipher/ctr.d.ts +3 -3
  83. package/lib/rtp/src/srtp/cipher/ctr.js +25 -14
  84. package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
  85. package/lib/rtp/src/srtp/cipher/gcm.d.ts +3 -3
  86. package/lib/rtp/src/srtp/cipher/gcm.js +57 -20
  87. package/lib/rtp/src/srtp/cipher/gcm.js.map +1 -1
  88. package/lib/rtp/src/srtp/cipher/index.d.ts +1 -1
  89. package/lib/rtp/src/srtp/cipher/index.js +1 -1
  90. package/lib/rtp/src/srtp/cipher/index.js.map +1 -1
  91. package/lib/rtp/src/srtp/context/srtp.d.ts +2 -1
  92. package/lib/rtp/src/srtp/context/srtp.js +22 -5
  93. package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
  94. package/lib/rtp/src/srtp/error.d.ts +3 -0
  95. package/lib/rtp/src/srtp/error.js +11 -0
  96. package/lib/rtp/src/srtp/error.js.map +1 -0
  97. package/lib/rtp/src/srtp/packet.d.ts +5 -0
  98. package/lib/rtp/src/srtp/packet.js +48 -0
  99. package/lib/rtp/src/srtp/packet.js.map +1 -0
  100. package/lib/webrtc/src/dataChannel.d.ts +4 -2
  101. package/lib/webrtc/src/dataChannel.js +14 -4
  102. package/lib/webrtc/src/dataChannel.js.map +1 -1
  103. package/lib/webrtc/src/errors.d.ts +3 -0
  104. package/lib/webrtc/src/errors.js +11 -0
  105. package/lib/webrtc/src/errors.js.map +1 -0
  106. package/lib/webrtc/src/helper.d.ts +5 -1
  107. package/lib/webrtc/src/helper.js +33 -1
  108. package/lib/webrtc/src/helper.js.map +1 -1
  109. package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
  110. package/lib/webrtc/src/media/receiver/statistics.js +22 -0
  111. package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
  112. package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
  113. package/lib/webrtc/src/media/rtpReceiver.js +135 -20
  114. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  115. package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
  116. package/lib/webrtc/src/media/rtpSender.js +177 -28
  117. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  118. package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
  119. package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
  120. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  121. package/lib/webrtc/src/media/stats.d.ts +15 -1
  122. package/lib/webrtc/src/media/stats.js +55 -1
  123. package/lib/webrtc/src/media/stats.js.map +1 -1
  124. package/lib/webrtc/src/media/track.d.ts +2 -1
  125. package/lib/webrtc/src/media/track.js +7 -1
  126. package/lib/webrtc/src/media/track.js.map +1 -1
  127. package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
  128. package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
  129. package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
  130. package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
  131. package/lib/webrtc/src/nonstandard/navigator.js +96 -32
  132. package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
  133. package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
  134. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
  135. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
  136. package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
  137. package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
  138. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  139. package/lib/webrtc/src/peerConnection.d.ts +185 -49
  140. package/lib/webrtc/src/peerConnection.js +477 -107
  141. package/lib/webrtc/src/peerConnection.js.map +1 -1
  142. package/lib/webrtc/src/sctpManager.d.ts +2 -2
  143. package/lib/webrtc/src/sctpManager.js +30 -9
  144. package/lib/webrtc/src/sctpManager.js.map +1 -1
  145. package/lib/webrtc/src/sdp.d.ts +10 -7
  146. package/lib/webrtc/src/sdp.js +39 -9
  147. package/lib/webrtc/src/sdp.js.map +1 -1
  148. package/lib/webrtc/src/sdpManager.d.ts +5 -4
  149. package/lib/webrtc/src/sdpManager.js +53 -31
  150. package/lib/webrtc/src/sdpManager.js.map +1 -1
  151. package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
  152. package/lib/webrtc/src/secureTransportManager.js +101 -23
  153. package/lib/webrtc/src/secureTransportManager.js.map +1 -1
  154. package/lib/webrtc/src/transceiverManager.d.ts +5 -4
  155. package/lib/webrtc/src/transceiverManager.js +64 -64
  156. package/lib/webrtc/src/transceiverManager.js.map +1 -1
  157. package/lib/webrtc/src/transport/dtls.d.ts +16 -4
  158. package/lib/webrtc/src/transport/dtls.js +208 -35
  159. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  160. package/lib/webrtc/src/transport/ice.d.ts +21 -3
  161. package/lib/webrtc/src/transport/ice.js +159 -30
  162. package/lib/webrtc/src/transport/ice.js.map +1 -1
  163. package/lib/webrtc/src/transport/sctp.d.ts +10 -3
  164. package/lib/webrtc/src/transport/sctp.js +44 -13
  165. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  166. package/lib/webrtc/src/utils.d.ts +14 -4
  167. package/lib/webrtc/src/utils.js +138 -16
  168. package/lib/webrtc/src/utils.js.map +1 -1
  169. package/package.json +7 -4
  170. package/lib/ice/src/stun/attributes.js.map +0 -1
  171. package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
  172. package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
  173. package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rtpSender.js","sourceRoot":"","sources":["../../../../src/media/rtpSender.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n [10 Nov 1995 11:33:25.125 UTC] [10 Nov 1995 11:33:36.5 UTC]\n n SR(n) A=b710:8000 (46864.500 s)\n ---------------------------------------------------------------->\n v ^\n ntp_sec =0xb44db705 v ^ dlsr=0x0005:4000 ( 5.250s)\n ntp_frac=0x20000000 v ^ lsr =0xb705:2000 (46853.125s)\n (3024992005.125 s) v ^\n r v ^ RR(n)\n ---------------------------------------------------------------->\n |<-DLSR->|\n (5.250 s)\n \n A 0xb710:8000 (46864.500 s)\n DLSR -0x0005:4000 ( 5.250 s)\n LSR -0xb705:2000 (46853.125 s)\n -------------------------------\n delay 0x0006:2000 ( 6.125 s)\n \nFigure 2: Example for round-trip time computation\n */\n\nimport { randomBytes } from \"crypto\";\nimport { jspack } from \"@shinyoshiaki/jspack\";\n\nimport { randomUUID } from \"crypto\";\nimport { setTimeout } from \"timers/promises\";\nimport { Event, random16, uint16Add, uint32Add } from \"../imports/common\";\n\nimport { codecParametersFromString } from \"..\";\nimport {\n type Extension,\n GenericNack,\n PictureLossIndication,\n RTP_EXTENSION_URI,\n ReceiverEstimatedMaxBitrate,\n RedEncoder,\n type RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSenderInfo,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n type RtpHeader,\n RtpPacket,\n SourceDescriptionChunk,\n SourceDescriptionItem,\n TransportWideCC,\n debug,\n serializeAbsSendTime,\n serializeRepairedRtpStreamId,\n serializeSdesMid,\n serializeSdesRTPStreamID,\n serializeTransportWideCC,\n wrapRtx,\n} from \"../imports/rtp\";\nimport type { RTCDtlsTransport } from \"../transport/dtls\";\nimport type { Kind } from \"../types/domain\";\nimport { compactNtp, milliTime, ntpTime, timestampSeconds } from \"../utils\";\nimport type {\n RTCRtpCodecParameters,\n RTCRtpHeaderExtensionParameters,\n RTCRtpSendParameters,\n} from \"./parameters\";\nimport { SenderBandwidthEstimator, type SentInfo } from \"./sender/senderBWE\";\nimport {\n type RTCMediaSourceStats,\n type RTCOutboundRtpStreamStats,\n type RTCRemoteInboundRtpStreamStats,\n type RTCStats,\n generateStatsId,\n getStatsTimestamp,\n} from \"./stats\";\nimport type { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpSender.ts\");\n\nconst RTP_HISTORY_SIZE = 128;\nconst RTT_ALPHA = 0.85;\n\nexport class RTCRtpSender {\n readonly type = \"sender\";\n readonly kind: Kind;\n readonly ssrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n readonly rtxSsrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n streamId = randomUUID().toString();\n readonly trackId = randomUUID().toString();\n readonly onReady = new Event();\n readonly onRtcp = new Event<[RtcpPacket]>();\n readonly onPictureLossIndication = new Event<[]>();\n readonly onGenericNack = new Event<[GenericNack]>();\n readonly senderBWE = new SenderBandwidthEstimator();\n\n private cname?: string;\n private mid?: string;\n private rtpStreamId?: string;\n private repairedRtpStreamId?: string;\n private rtxPayloadType?: number;\n private rtxSequenceNumber = random16();\n redRedundantPayloadType?: number;\n private _redDistance = 2;\n redEncoder = new RedEncoder(this._redDistance);\n private headerExtensions: RTCRtpHeaderExtensionParameters[] = [];\n private disposeTrack?: () => void;\n\n // # stats\n private lastSRtimestamp?: number;\n private lastSentSRTimestamp?: number;\n private ntpTimestamp = 0n;\n private rtpTimestamp = 0;\n private octetCount = 0;\n private packetCount = 0;\n private rtt?: number;\n receiverEstimatedMaxBitrate = 0n;\n\n // rtp\n private sequenceNumber?: number;\n private timestamp?: number;\n private timestampOffset = 0;\n private seqOffset = 0;\n private rtpCache: RtpPacket[] = [];\n codec?: RTCRtpCodecParameters;\n public dtlsTransport!: RTCDtlsTransport;\n private dtlsDisposer: (() => void)[] = [];\n\n track?: MediaStreamTrack;\n stopped = false;\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n\n constructor(public trackOrKind: Kind | MediaStreamTrack) {\n this.kind =\n typeof this.trackOrKind === \"string\"\n ? this.trackOrKind\n : this.trackOrKind.kind;\n if (typeof trackOrKind !== \"string\") {\n if (trackOrKind.streamId) {\n this.streamId = trackOrKind.streamId;\n }\n this.registerTrack(trackOrKind);\n }\n }\n\n setDtlsTransport(dtlsTransport: RTCDtlsTransport) {\n if (this.dtlsTransport) {\n this.dtlsDisposer.forEach((dispose) => dispose());\n }\n\n this.dtlsTransport = dtlsTransport;\n this.dtlsDisposer = [\n this.dtlsTransport.onStateChange.subscribe((state) => {\n if (state === \"connected\") {\n this.onReady.execute();\n }\n }).unSubscribe,\n ];\n }\n\n get redDistance() {\n return this._redDistance;\n }\n set redDistance(n: number) {\n this._redDistance = n;\n this.redEncoder.distance = n;\n }\n\n prepareSend(params: RTCRtpSendParameters) {\n this.cname = params.rtcp?.cname;\n this.mid = params.muxId;\n this.headerExtensions = params.headerExtensions;\n this.rtpStreamId = params.rtpStreamId;\n this.repairedRtpStreamId = params.repairedRtpStreamId;\n\n this.codec = params.codecs[0];\n if (this.track) {\n this.track.codec = this.codec;\n }\n\n params.codecs.forEach((codec) => {\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n if (\n codec.name.toLowerCase() === \"rtx\" &&\n codecParams[\"apt\"] === this.codec?.payloadType\n ) {\n this.rtxPayloadType = codec.payloadType;\n }\n if (codec.name.toLowerCase() === \"red\") {\n this.redRedundantPayloadType = Number(\n (codec.parameters ?? \"\").split(\"/\")[0],\n );\n }\n });\n }\n\n registerTrack(track: MediaStreamTrack) {\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n\n track.id = this.trackId;\n\n const { unSubscribe } = track.onReceiveRtp.subscribe(async (rtp) => {\n await this.sendRtp(rtp);\n });\n this.track = track;\n this.disposeTrack = unSubscribe;\n\n if (this.codec) {\n track.codec = this.codec;\n }\n\n track.onSourceChanged.subscribe((header) => {\n this.replaceRTP(header);\n });\n }\n\n async replaceTrack(track: MediaStreamTrack | null) {\n if (track === null) {\n // todo impl\n return;\n }\n\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.sequenceNumber != undefined) {\n const header =\n track.header || (await track.onReceiveRtp.asPromise())[0].header;\n\n this.replaceRTP(header);\n }\n\n this.registerTrack(track);\n log(\"replaceTrack\", \"ssrc\", track.ssrc, \"rid\", track.rid);\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n this.track = undefined;\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const packets: RtcpPacket[] = [\n new RtcpSrPacket({\n ssrc: this.ssrc,\n senderInfo: new RtcpSenderInfo({\n ntpTimestamp: this.ntpTimestamp,\n rtpTimestamp: this.rtpTimestamp,\n packetCount: this.packetCount,\n octetCount: this.octetCount,\n }),\n }),\n ];\n this.lastSRtimestamp = compactNtp(this.ntpTimestamp);\n this.lastSentSRTimestamp = timestampSeconds();\n\n if (this.cname) {\n packets.push(\n new RtcpSourceDescriptionPacket({\n chunks: [\n new SourceDescriptionChunk({\n source: this.ssrc,\n items: [\n new SourceDescriptionItem({ type: 1, text: this.cname }),\n ],\n }),\n ],\n }),\n );\n }\n\n try {\n await this.dtlsTransport.sendRtcp(packets);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n replaceRTP(\n {\n sequenceNumber,\n timestamp,\n }: Pick<RtpHeader, \"sequenceNumber\" | \"timestamp\">,\n discontinuity = false,\n ) {\n if (this.sequenceNumber != undefined) {\n this.seqOffset = uint16Add(this.sequenceNumber, -sequenceNumber);\n if (discontinuity) {\n this.seqOffset = uint16Add(this.seqOffset, 2);\n }\n }\n if (this.timestamp != undefined) {\n this.timestampOffset = uint32Add(this.timestamp, -timestamp);\n if (discontinuity) {\n this.timestampOffset = uint16Add(this.timestampOffset, 1);\n }\n }\n this.rtpCache = [];\n log(\"replaceRTP\", this.sequenceNumber, sequenceNumber, this.seqOffset);\n }\n\n async sendRtp(rtp: Buffer | RtpPacket) {\n if (this.dtlsTransport.state !== \"connected\" || !this.codec) {\n return;\n }\n\n rtp = Buffer.isBuffer(rtp) ? RtpPacket.deSerialize(rtp) : rtp;\n\n const { header, payload } = rtp;\n header.ssrc = this.ssrc;\n header.payloadType = this.codec.payloadType;\n header.timestamp = uint32Add(header.timestamp, this.timestampOffset);\n header.sequenceNumber = uint16Add(header.sequenceNumber, this.seqOffset);\n this.timestamp = header.timestamp;\n this.sequenceNumber = header.sequenceNumber;\n\n const ntpTimestamp = ntpTime();\n\n const originalHeaderExtensions = [...header.extensions];\n header.extensions = this.headerExtensions\n .map((extension) => {\n const payload = (() => {\n switch (extension.uri) {\n case RTP_EXTENSION_URI.sdesMid:\n if (this.mid) {\n return serializeSdesMid(this.mid);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n if (this.rtpStreamId) {\n return serializeSdesRTPStreamID(this.rtpStreamId);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n if (this.repairedRtpStreamId) {\n return serializeRepairedRtpStreamId(this.repairedRtpStreamId);\n }\n return;\n case RTP_EXTENSION_URI.transportWideCC:\n this.dtlsTransport.transportSequenceNumber = uint16Add(\n this.dtlsTransport.transportSequenceNumber,\n 1,\n );\n return serializeTransportWideCC(\n this.dtlsTransport.transportSequenceNumber,\n );\n case RTP_EXTENSION_URI.absSendTime:\n return serializeAbsSendTime(ntpTimestamp);\n }\n })();\n\n if (payload) return { id: extension.id, payload };\n })\n .filter((v) => v) as Extension[];\n for (const ext of originalHeaderExtensions) {\n const exist = header.extensions.find((v) => v.id === ext.id);\n if (exist) {\n exist.payload = ext.payload;\n } else {\n header.extensions.push(ext);\n }\n }\n header.extensions = header.extensions.sort((a, b) => a.id - b.id);\n\n this.ntpTimestamp = ntpTimestamp;\n this.rtpTimestamp = header.timestamp;\n this.octetCount += payload.length;\n this.packetCount = uint32Add(this.packetCount, 1);\n\n this.rtpCache[header.sequenceNumber % RTP_HISTORY_SIZE] = rtp;\n\n let rtpPayload = payload;\n\n if (this.redRedundantPayloadType) {\n this.redEncoder.push({\n block: rtpPayload,\n timestamp: header.timestamp,\n blockPT: this.redRedundantPayloadType,\n });\n const red = this.redEncoder.build();\n rtpPayload = red.serialize();\n }\n\n const size = await this.dtlsTransport.sendRtp(rtpPayload, header);\n\n this.runRtcp();\n const millitime = milliTime();\n const sentInfo: SentInfo = {\n wideSeq: this.dtlsTransport.transportSequenceNumber,\n size,\n sendingAtMs: millitime,\n sentAtMs: millitime,\n };\n this.senderBWE.rtpPacketSent(sentInfo);\n }\n\n handleRtcpPacket(rtcpPacket: RtcpPacket) {\n switch (rtcpPacket.type) {\n case RtcpSrPacket.type:\n case RtcpRrPacket.type:\n {\n const packet = rtcpPacket as RtcpSrPacket | RtcpRrPacket;\n packet.reports\n .filter((report) => report.ssrc === this.ssrc)\n .forEach((report) => {\n if (this.lastSRtimestamp === report.lsr && report.dlsr) {\n if (this.lastSentSRTimestamp) {\n const rtt =\n timestampSeconds() -\n this.lastSentSRTimestamp -\n report.dlsr / 65536;\n if (this.rtt === undefined) {\n this.rtt = rtt;\n } else {\n this.rtt = RTT_ALPHA * this.rtt + (1 - RTT_ALPHA) * rtt;\n }\n }\n }\n });\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const packet = rtcpPacket as RtcpTransportLayerFeedback;\n switch (packet.feedback.count) {\n case TransportWideCC.count:\n {\n const feedback = packet.feedback as TransportWideCC;\n this.senderBWE.receiveTWCC(feedback);\n }\n break;\n case GenericNack.count:\n {\n const feedback = packet.feedback as GenericNack;\n feedback.lost.forEach(async (seqNum) => {\n let packet: RtpPacket | undefined =\n this.rtpCache[seqNum % RTP_HISTORY_SIZE];\n if (packet && packet.header.sequenceNumber !== seqNum) {\n packet = undefined;\n }\n if (packet) {\n if (this.rtxPayloadType != undefined) {\n packet = wrapRtx(\n packet,\n this.rtxPayloadType,\n this.rtxSequenceNumber,\n this.rtxSsrc,\n );\n this.rtxSequenceNumber = uint16Add(\n this.rtxSequenceNumber,\n 1,\n );\n }\n await this.dtlsTransport.sendRtp(\n packet.payload,\n packet.header,\n );\n }\n });\n this.onGenericNack.execute(feedback);\n }\n break;\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const packet = rtcpPacket as RtcpPayloadSpecificFeedback;\n switch (packet.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n {\n const feedback = packet.feedback as ReceiverEstimatedMaxBitrate;\n this.receiverEstimatedMaxBitrate = feedback.bitrate;\n }\n break;\n case PictureLossIndication.count:\n {\n this.onPictureLossIndication.execute();\n }\n break;\n }\n }\n break;\n }\n this.onRtcp.execute(rtcpPacket);\n }\n\n // todo impl\n getParameters() {\n return {\n encodings: [],\n };\n }\n\n // todo impl\n setParameters(params: any) {}\n\n async getStats(): Promise<RTCStats[]> {\n const timestamp = getStatsTimestamp();\n const stats: RTCStats[] = [];\n\n if (!this.dtlsTransport) {\n return stats;\n }\n\n const transportId = generateStatsId(\"transport\", this.dtlsTransport.id);\n\n // Outbound RTP stats\n const outboundRtpStats: RTCOutboundRtpStreamStats = {\n type: \"outbound-rtp\",\n id: generateStatsId(\"outbound-rtp\", this.ssrc),\n timestamp,\n ssrc: this.ssrc,\n kind: this.kind,\n transportId,\n codecId: this.codec\n ? generateStatsId(\"codec\", this.codec.payloadType, transportId)\n : undefined,\n mid: this.mid,\n packetsSent: this.packetCount,\n bytesSent: this.octetCount,\n rtxSsrc: this.rtxPayloadType ? this.rtxSsrc : undefined,\n };\n stats.push(outboundRtpStats);\n\n // Media source stats\n if (this.track) {\n const mediaSourceStats: RTCMediaSourceStats = {\n type: \"media-source\",\n id: generateStatsId(\"media-source\", this.trackId),\n timestamp,\n trackIdentifier: this.trackId,\n kind: this.kind,\n };\n stats.push(mediaSourceStats);\n }\n\n // Remote inbound RTP stats (if we have RTT)\n if (this.rtt !== undefined) {\n const remoteInboundStats: RTCRemoteInboundRtpStreamStats = {\n type: \"remote-inbound-rtp\",\n id: generateStatsId(\"remote-inbound-rtp\", this.ssrc),\n timestamp,\n ssrc: this.ssrc,\n kind: this.kind,\n transportId,\n codecId: outboundRtpStats.codecId,\n localId: outboundRtpStats.id,\n roundTripTime: this.rtt,\n };\n stats.push(remoteInboundStats);\n }\n\n return stats;\n }\n}\n"]}
1
+ {"version":3,"file":"rtpSender.js","sourceRoot":"","sources":["../../../../src/media/rtpSender.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n [10 Nov 1995 11:33:25.125 UTC] [10 Nov 1995 11:33:36.5 UTC]\n n SR(n) A=b710:8000 (46864.500 s)\n ---------------------------------------------------------------->\n v ^\n ntp_sec =0xb44db705 v ^ dlsr=0x0005:4000 ( 5.250s)\n ntp_frac=0x20000000 v ^ lsr =0xb705:2000 (46853.125s)\n (3024992005.125 s) v ^\n r v ^ RR(n)\n ---------------------------------------------------------------->\n |<-DLSR->|\n (5.250 s)\n \n A 0xb710:8000 (46864.500 s)\n DLSR -0x0005:4000 ( 5.250 s)\n LSR -0xb705:2000 (46853.125 s)\n -------------------------------\n delay 0x0006:2000 ( 6.125 s)\n \nFigure 2: Example for round-trip time computation\n */\n\nimport { randomBytes } from \"crypto\";\nimport { jspack } from \"@shinyoshiaki/jspack\";\n\nimport { randomUUID } from \"crypto\";\nimport { setTimeout } from \"timers/promises\";\nimport { Event, random16, uint16Add, uint32Add } from \"../imports/common\";\n\nimport { codecParametersFromString } from \"..\";\nimport {\n type Extension,\n GenericNack,\n PictureLossIndication,\n RTP_EXTENSION_URI,\n ReceiverEstimatedMaxBitrate,\n RedEncoder,\n type RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSenderInfo,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n type RtpHeader,\n RtpPacket,\n SourceDescriptionChunk,\n SourceDescriptionItem,\n TransportWideCC,\n debug,\n serializeAbsSendTime,\n serializeRepairedRtpStreamId,\n serializeSdesMid,\n serializeSdesRTPStreamID,\n serializeTransportWideCC,\n wrapRtx,\n} from \"../imports/rtp\";\nimport type { RTCDtlsTransport } from \"../transport/dtls\";\nimport type { Kind } from \"../types/domain\";\nimport { compactNtp, milliTime, ntpTime, timestampSeconds } from \"../utils\";\nimport type {\n RTCRtpCodecParameters,\n RTCRtpHeaderExtensionParameters,\n RTCRtpSendParameters,\n} from \"./parameters\";\nimport { SenderBandwidthEstimator, type SentInfo } from \"./sender/senderBWE\";\nimport {\n type RTCCodecStats,\n type RTCMediaSourceStats,\n type RTCOutboundRtpStreamStats,\n type RTCRemoteInboundRtpStreamStats,\n type RTCStats,\n type RTCStatsReport,\n buildStatsReport,\n generateCodecStatsId,\n generateStatsId,\n getStatsTimestamp,\n} from \"./stats\";\nimport type { MediaStream, MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpSender.ts\");\n\nconst RTP_HISTORY_SIZE = 128;\nconst RTT_ALPHA = 0.85;\n\nexport class RTCRtpSender {\n readonly type = \"sender\";\n readonly kind: Kind;\n readonly ssrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n readonly rtxSsrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n readonly trackId = randomUUID().toString();\n readonly onReady = new Event();\n readonly onRtcp = new Event<[RtcpPacket]>();\n readonly onPictureLossIndication = new Event<[]>();\n readonly onGenericNack = new Event<[GenericNack]>();\n readonly senderBWE = new SenderBandwidthEstimator();\n\n private cname?: string;\n private mid?: string;\n private rtpStreamId?: string;\n private repairedRtpStreamId?: string;\n private rtxPayloadType?: number;\n private rtxSequenceNumber = random16();\n redRedundantPayloadType?: number;\n private _redDistance = 2;\n redEncoder = new RedEncoder(this._redDistance);\n private headerExtensions: RTCRtpHeaderExtensionParameters[] = [];\n private disposeTrack?: () => void;\n private sendEncodings: Array<Record<string, unknown>> = [{}];\n\n // # stats\n private lastSRtimestamp?: number;\n private lastSentSRTimestamp?: number;\n private ntpTimestamp = 0n;\n private rtpTimestamp = 0;\n private octetCount = 0;\n private packetCount = 0;\n private headerBytesSent = 0;\n private rtt?: number;\n private totalRoundTripTime = 0;\n private roundTripTimeMeasurements = 0;\n private retransmittedPacketsSent = 0;\n private retransmittedBytesSent = 0;\n private nackCount = 0;\n private pliCount = 0;\n private firCount = 0;\n private remotePacketsLost?: number;\n private remoteFractionLost?: number;\n receiverEstimatedMaxBitrate = 0n;\n\n // rtp\n private sequenceNumber?: number;\n private timestamp?: number;\n private timestampOffset = 0;\n private seqOffset = 0;\n private rtpCache: RtpPacket[] = [];\n codec?: RTCRtpCodecParameters;\n public dtlsTransport!: RTCDtlsTransport;\n private dtlsDisposer: (() => void)[] = [];\n\n track: MediaStreamTrack | null = null;\n streamIds: string[] = [];\n stopped = false;\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n\n constructor(public trackOrKind: Kind | MediaStreamTrack) {\n this.kind =\n typeof this.trackOrKind === \"string\"\n ? this.trackOrKind\n : this.trackOrKind.kind;\n if (typeof trackOrKind !== \"string\") {\n this.registerTrack(trackOrKind);\n }\n }\n\n get transport() {\n return this.dtlsTransport ?? null;\n }\n\n get streamId() {\n return this.streamIds[0];\n }\n\n set streamId(value: string | undefined) {\n this.streamIds = value ? [value] : [];\n }\n\n setDtlsTransport(dtlsTransport: RTCDtlsTransport) {\n if (this.dtlsTransport) {\n this.dtlsDisposer.forEach((dispose) => dispose());\n }\n\n this.dtlsTransport = dtlsTransport;\n this.dtlsDisposer = [\n this.dtlsTransport.onStateChange.subscribe((state) => {\n if (state === \"connected\") {\n this.onReady.execute();\n }\n }).unSubscribe,\n ];\n }\n\n get redDistance() {\n return this._redDistance;\n }\n set redDistance(n: number) {\n this._redDistance = n;\n this.redEncoder.distance = n;\n }\n\n prepareSend(params: RTCRtpSendParameters) {\n this.cname = params.rtcp?.cname;\n this.mid = params.muxId;\n this.headerExtensions = params.headerExtensions;\n this.rtpStreamId = params.rtpStreamId;\n this.repairedRtpStreamId = params.repairedRtpStreamId;\n\n this.codec = params.codecs[0];\n if (this.track) {\n this.track.codec = this.codec;\n }\n\n params.codecs.forEach((codec) => {\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n if (\n codec.name.toLowerCase() === \"rtx\" &&\n codecParams[\"apt\"] === this.codec?.payloadType\n ) {\n this.rtxPayloadType = codec.payloadType;\n }\n if (codec.name.toLowerCase() === \"red\") {\n this.redRedundantPayloadType = Number(\n (codec.parameters ?? \"\").split(\"/\")[0],\n );\n }\n });\n }\n\n registerTrack(track: MediaStreamTrack) {\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n\n track.id = this.trackId;\n\n const { unSubscribe } = track.onReceiveRtp.subscribe(async (rtp) => {\n await this.sendRtp(rtp);\n });\n this.track = track;\n this.disposeTrack = unSubscribe;\n\n if (this.codec) {\n track.codec = this.codec;\n }\n\n track.onSourceChanged.subscribe((header) => {\n this.replaceRTP(header);\n });\n }\n\n setStreams(streams: MediaStream[] = []) {\n this.streamIds = [...new Set(streams.map((stream) => stream.id))];\n }\n\n setSendEncodings(encodings: Array<Record<string, unknown>> = []) {\n this.sendEncodings =\n encodings.length > 0\n ? encodings.map((encoding) => ({ ...encoding }))\n : [{}];\n }\n\n async replaceTrack(track: MediaStreamTrack | null) {\n if (track === null) {\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n this.track = null;\n return;\n }\n\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.sequenceNumber != undefined) {\n const header =\n track.header || (await track.onReceiveRtp.asPromise())[0].header;\n\n this.replaceRTP(header);\n }\n\n this.registerTrack(track);\n log(\"replaceTrack\", \"ssrc\", track.ssrc, \"rid\", track.rid);\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n this.track = null;\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const packets: RtcpPacket[] = [\n new RtcpSrPacket({\n ssrc: this.ssrc,\n senderInfo: new RtcpSenderInfo({\n ntpTimestamp: this.ntpTimestamp,\n rtpTimestamp: this.rtpTimestamp,\n packetCount: this.packetCount,\n octetCount: this.octetCount,\n }),\n }),\n ];\n this.lastSRtimestamp = compactNtp(this.ntpTimestamp);\n this.lastSentSRTimestamp = timestampSeconds();\n\n if (this.cname) {\n packets.push(\n new RtcpSourceDescriptionPacket({\n chunks: [\n new SourceDescriptionChunk({\n source: this.ssrc,\n items: [\n new SourceDescriptionItem({ type: 1, text: this.cname }),\n ],\n }),\n ],\n }),\n );\n }\n\n try {\n await this.dtlsTransport.sendRtcp(packets);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n replaceRTP(\n {\n sequenceNumber,\n timestamp,\n }: Pick<RtpHeader, \"sequenceNumber\" | \"timestamp\">,\n discontinuity = false,\n ) {\n if (this.sequenceNumber != undefined) {\n this.seqOffset = uint16Add(this.sequenceNumber, -sequenceNumber);\n if (discontinuity) {\n this.seqOffset = uint16Add(this.seqOffset, 2);\n }\n }\n if (this.timestamp != undefined) {\n this.timestampOffset = uint32Add(this.timestamp, -timestamp);\n if (discontinuity) {\n this.timestampOffset = uint16Add(this.timestampOffset, 1);\n }\n }\n this.rtpCache = [];\n log(\"replaceRTP\", this.sequenceNumber, sequenceNumber, this.seqOffset);\n }\n\n async sendRtp(rtp: Buffer | RtpPacket) {\n if (this.dtlsTransport.state !== \"connected\" || !this.codec) {\n return;\n }\n\n rtp = Buffer.isBuffer(rtp) ? RtpPacket.deSerialize(rtp) : rtp;\n\n const { header, payload } = rtp;\n header.ssrc = this.ssrc;\n header.payloadType = this.codec.payloadType;\n header.timestamp = uint32Add(header.timestamp, this.timestampOffset);\n header.sequenceNumber = uint16Add(header.sequenceNumber, this.seqOffset);\n this.timestamp = header.timestamp;\n this.sequenceNumber = header.sequenceNumber;\n\n const ntpTimestamp = ntpTime();\n\n const originalHeaderExtensions = [...header.extensions];\n header.extensions = this.headerExtensions\n .map((extension) => {\n const payload = (() => {\n switch (extension.uri) {\n case RTP_EXTENSION_URI.sdesMid:\n if (this.mid) {\n return serializeSdesMid(this.mid);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n if (this.rtpStreamId) {\n return serializeSdesRTPStreamID(this.rtpStreamId);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n if (this.repairedRtpStreamId) {\n return serializeRepairedRtpStreamId(this.repairedRtpStreamId);\n }\n return;\n case RTP_EXTENSION_URI.transportWideCC:\n this.dtlsTransport.transportSequenceNumber = uint16Add(\n this.dtlsTransport.transportSequenceNumber,\n 1,\n );\n return serializeTransportWideCC(\n this.dtlsTransport.transportSequenceNumber,\n );\n case RTP_EXTENSION_URI.absSendTime:\n return serializeAbsSendTime(ntpTimestamp);\n }\n })();\n\n if (payload) return { id: extension.id, payload };\n })\n .filter((v) => v) as Extension[];\n for (const ext of originalHeaderExtensions) {\n const exist = header.extensions.find((v) => v.id === ext.id);\n if (exist) {\n exist.payload = ext.payload;\n } else {\n header.extensions.push(ext);\n }\n }\n header.extensions = header.extensions.sort((a, b) => a.id - b.id);\n\n this.ntpTimestamp = ntpTimestamp;\n this.rtpTimestamp = header.timestamp;\n this.octetCount += payload.length;\n this.headerBytesSent += header.serializeSize;\n this.packetCount = uint32Add(this.packetCount, 1);\n\n this.rtpCache[header.sequenceNumber % RTP_HISTORY_SIZE] = rtp;\n\n let rtpPayload = payload;\n\n if (this.redRedundantPayloadType) {\n this.redEncoder.push({\n block: rtpPayload,\n timestamp: header.timestamp,\n blockPT: this.redRedundantPayloadType,\n });\n const red = this.redEncoder.build();\n rtpPayload = red.serialize();\n }\n\n const size = await this.dtlsTransport.sendRtp(rtpPayload, header);\n\n this.runRtcp();\n const millitime = milliTime();\n const sentInfo: SentInfo = {\n wideSeq: this.dtlsTransport.transportSequenceNumber,\n size,\n sendingAtMs: millitime,\n sentAtMs: millitime,\n };\n this.senderBWE.rtpPacketSent(sentInfo);\n }\n\n handleRtcpPacket(rtcpPacket: RtcpPacket) {\n switch (rtcpPacket.type) {\n case RtcpSrPacket.type:\n case RtcpRrPacket.type:\n {\n const packet = rtcpPacket as RtcpSrPacket | RtcpRrPacket;\n packet.reports\n .filter((report) => report.ssrc === this.ssrc)\n .forEach((report) => {\n this.remotePacketsLost = report.packetsLost;\n this.remoteFractionLost = report.fractionLost / 256;\n if (this.lastSRtimestamp === report.lsr && report.dlsr) {\n if (this.lastSentSRTimestamp) {\n const rtt =\n timestampSeconds() -\n this.lastSentSRTimestamp -\n report.dlsr / 65536;\n this.totalRoundTripTime += rtt;\n this.roundTripTimeMeasurements++;\n if (this.rtt === undefined) {\n this.rtt = rtt;\n } else {\n this.rtt = RTT_ALPHA * this.rtt + (1 - RTT_ALPHA) * rtt;\n }\n }\n }\n });\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const packet = rtcpPacket as RtcpTransportLayerFeedback;\n switch (packet.feedback.count) {\n case TransportWideCC.count:\n {\n const feedback = packet.feedback as TransportWideCC;\n this.senderBWE.receiveTWCC(feedback);\n }\n break;\n case GenericNack.count:\n {\n const feedback = packet.feedback as GenericNack;\n this.nackCount++;\n feedback.lost.forEach(async (seqNum) => {\n let packet: RtpPacket | undefined =\n this.rtpCache[seqNum % RTP_HISTORY_SIZE];\n if (packet && packet.header.sequenceNumber !== seqNum) {\n packet = undefined;\n }\n if (packet) {\n if (this.rtxPayloadType != undefined) {\n packet = wrapRtx(\n packet,\n this.rtxPayloadType,\n this.rtxSequenceNumber,\n this.rtxSsrc,\n );\n this.rtxSequenceNumber = uint16Add(\n this.rtxSequenceNumber,\n 1,\n );\n }\n this.retransmittedPacketsSent++;\n this.retransmittedBytesSent += packet.payload.length;\n this.headerBytesSent += packet.header.serializeSize;\n await this.dtlsTransport.sendRtp(\n packet.payload,\n packet.header,\n );\n }\n });\n this.onGenericNack.execute(feedback);\n }\n break;\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const packet = rtcpPacket as RtcpPayloadSpecificFeedback;\n switch (packet.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n {\n const feedback = packet.feedback as ReceiverEstimatedMaxBitrate;\n this.receiverEstimatedMaxBitrate = feedback.bitrate;\n }\n break;\n case PictureLossIndication.count:\n {\n this.pliCount++;\n this.onPictureLossIndication.execute();\n }\n break;\n }\n }\n break;\n }\n this.onRtcp.execute(rtcpPacket);\n }\n\n // todo impl\n getParameters() {\n return {\n encodings: this.sendEncodings.map((encoding) => ({ ...encoding })),\n };\n }\n\n // todo impl\n setParameters(params: { encodings?: Array<Record<string, unknown>> }) {\n if (params.encodings) {\n this.setSendEncodings(params.encodings);\n }\n }\n\n private get outboundRtpStatsId() {\n return generateStatsId(\"outbound-rtp\", this.trackId);\n }\n\n private get mediaSourceStatsId() {\n return generateStatsId(\"media-source\", this.trackId);\n }\n\n private get remoteInboundRtpStatsId() {\n return generateStatsId(\"remote-inbound-rtp\", this.trackId);\n }\n\n getStatsRootIds() {\n return [this.outboundRtpStatsId];\n }\n\n collectStats(timestamp: number): RTCStats[] {\n const stats: RTCStats[] = [];\n const transportId = this.dtlsTransport\n ? generateStatsId(\"transport\", this.dtlsTransport.id)\n : undefined;\n const codecId =\n this.codec && transportId\n ? generateCodecStatsId(\n transportId,\n this.codec.payloadType,\n this.trackId,\n )\n : undefined;\n\n // Outbound RTP stats\n const outboundRtpStats: RTCOutboundRtpStreamStats = {\n type: \"outbound-rtp\",\n id: this.outboundRtpStatsId,\n timestamp,\n ssrc: this.ssrc,\n kind: this.kind,\n transportId,\n codecId,\n mid: this.mid,\n packetsSent: this.packetCount,\n bytesSent: this.octetCount,\n headerBytesSent: this.headerBytesSent,\n retransmittedPacketsSent: this.retransmittedPacketsSent || undefined,\n retransmittedBytesSent: this.retransmittedBytesSent || undefined,\n rtxSsrc: this.rtxPayloadType ? this.rtxSsrc : undefined,\n mediaSourceId: this.track ? this.mediaSourceStatsId : undefined,\n remoteId:\n this.rtt !== undefined ||\n this.remotePacketsLost !== undefined ||\n this.remoteFractionLost !== undefined\n ? this.remoteInboundRtpStatsId\n : undefined,\n nackCount: this.nackCount || undefined,\n pliCount: this.pliCount || undefined,\n firCount: this.firCount || undefined,\n };\n stats.push(outboundRtpStats);\n\n // Media source stats\n if (this.track) {\n const mediaSourceStats: RTCMediaSourceStats = {\n type: \"media-source\",\n id: this.mediaSourceStatsId,\n timestamp,\n trackIdentifier: this.track.id ?? this.trackId,\n kind: this.kind,\n };\n stats.push(mediaSourceStats);\n }\n\n if (this.codec && transportId) {\n const codecStats: RTCCodecStats = {\n type: \"codec\",\n id: codecId!,\n timestamp,\n payloadType: this.codec.payloadType,\n transportId,\n mimeType: this.codec.mimeType,\n clockRate: this.codec.clockRate,\n channels: this.codec.channels,\n sdpFmtpLine: this.codec.parameters,\n };\n stats.push(codecStats);\n }\n\n // Remote inbound RTP stats (if we have RTT)\n if (\n this.rtt !== undefined ||\n this.remotePacketsLost !== undefined ||\n this.remoteFractionLost !== undefined\n ) {\n const remoteInboundStats: RTCRemoteInboundRtpStreamStats = {\n type: \"remote-inbound-rtp\",\n id: this.remoteInboundRtpStatsId,\n timestamp,\n ssrc: this.ssrc,\n kind: this.kind,\n transportId,\n codecId: outboundRtpStats.codecId,\n localId: outboundRtpStats.id,\n roundTripTime: this.rtt,\n totalRoundTripTime: this.totalRoundTripTime,\n roundTripTimeMeasurements: this.roundTripTimeMeasurements,\n packetsLost: this.remotePacketsLost,\n fractionLost: this.remoteFractionLost,\n };\n stats.push(remoteInboundStats);\n }\n\n return stats;\n }\n\n async getStats(): Promise<RTCStatsReport> {\n const timestamp = getStatsTimestamp();\n const stats = this.collectStats(timestamp);\n\n if (this.dtlsTransport) {\n stats.push(...(await this.dtlsTransport.getStats(timestamp)));\n }\n\n return buildStatsReport(stats, this.getStatsRootIds());\n }\n}\n"]}
@@ -14,7 +14,7 @@ export declare class RTCRtpTransceiver {
14
14
  private _direction;
15
15
  readonly id: string;
16
16
  readonly onTrack: Event<[MediaStreamTrack, RTCRtpTransceiver]>;
17
- mid?: string;
17
+ mid: string | null;
18
18
  mLineIndex?: number;
19
19
  /**should not be reused because it has been used for sending before. */
20
20
  usedForSender: boolean;
@@ -32,17 +32,21 @@ export declare class RTCRtpTransceiver {
32
32
  _direction: MediaDirection);
33
33
  get dtlsTransport(): RTCDtlsTransport;
34
34
  /**RFC 8829 4.2.4. setDirectionに渡された最後の値を示します */
35
- get direction(): "inactive" | "sendonly" | "recvonly" | "sendrecv";
35
+ get direction(): MediaDirection;
36
+ set direction(direction: MediaDirection);
36
37
  setDirection(direction: MediaDirection): void;
37
38
  /**RFC 8829 4.2.5. last negotiated direction */
38
- get currentDirection(): MediaDirection | undefined;
39
- setCurrentDirection(direction: MediaDirection | undefined): void;
39
+ get currentDirection(): CurrentDirection | null;
40
+ setCurrentDirection(direction: CurrentDirection | undefined): void;
40
41
  setDtlsTransport(dtls: RTCDtlsTransport): void;
41
42
  get msid(): string;
43
+ get msids(): string[];
42
44
  addTrack(track: MediaStreamTrack): void;
43
45
  stop(): void;
46
+ forceStop(): void;
44
47
  getPayloadType(mimeType: string): number | undefined;
45
48
  getCodecStats(): RTCStats[];
49
+ collectCodecStats(timestamp: number): RTCStats[];
46
50
  }
47
51
  export declare const Inactive = "inactive";
48
52
  export declare const Sendonly = "sendonly";
@@ -50,9 +54,14 @@ export declare const Recvonly = "recvonly";
50
54
  export declare const Sendrecv = "sendrecv";
51
55
  export declare const Directions: readonly ["inactive", "sendonly", "recvonly", "sendrecv"];
52
56
  export type MediaDirection = (typeof Directions)[number];
57
+ export type CurrentDirection = MediaDirection | "stopped";
53
58
  type SimulcastDirection = "send" | "recv";
59
+ export interface RTCRtpEncodingParameters {
60
+ active?: boolean;
61
+ }
54
62
  export interface TransceiverOptions {
55
63
  direction: MediaDirection;
64
+ sendEncodings: RTCRtpEncodingParameters[];
56
65
  simulcast: {
57
66
  direction: SimulcastDirection;
58
67
  rid: string;
@@ -55,7 +55,7 @@ class RTCRtpTransceiver {
55
55
  enumerable: true,
56
56
  configurable: true,
57
57
  writable: true,
58
- value: void 0
58
+ value: null
59
59
  });
60
60
  Object.defineProperty(this, "mLineIndex", {
61
61
  enumerable: true,
@@ -123,15 +123,20 @@ class RTCRtpTransceiver {
123
123
  get direction() {
124
124
  return this._direction;
125
125
  }
126
+ set direction(direction) {
127
+ this.setDirection(direction);
128
+ }
126
129
  setDirection(direction) {
127
130
  this._direction = direction;
128
- if (const_1.SenderDirections.includes(this._currentDirection ?? "")) {
131
+ if (this._currentDirection &&
132
+ this._currentDirection !== "stopped" &&
133
+ const_1.SenderDirections.includes(this._currentDirection)) {
129
134
  this.usedForSender = true;
130
135
  }
131
136
  }
132
137
  /**RFC 8829 4.2.5. last negotiated direction */
133
138
  get currentDirection() {
134
- return this._currentDirection;
139
+ return this._currentDirection ?? null;
135
140
  }
136
141
  setCurrentDirection(direction) {
137
142
  this._currentDirection = direction;
@@ -141,7 +146,10 @@ class RTCRtpTransceiver {
141
146
  this.sender.setDtlsTransport(dtls);
142
147
  }
143
148
  get msid() {
144
- return `${this.sender.streamId} ${this.sender.trackId}`;
149
+ return this.msids[0];
150
+ }
151
+ get msids() {
152
+ return this.sender.streamIds.map((streamId) => `${streamId} ${this.sender.trackId}`);
145
153
  }
146
154
  addTrack(track) {
147
155
  const res = this.receiver.addTrack(track);
@@ -158,11 +166,24 @@ class RTCRtpTransceiver {
158
166
  // todo Stop sending and receiving with transceiver.
159
167
  this.stopping = true;
160
168
  }
169
+ forceStop() {
170
+ if (this.stopped) {
171
+ return;
172
+ }
173
+ this.stopping = true;
174
+ this.stopped = true;
175
+ this.setCurrentDirection("stopped");
176
+ this.receiver.stop();
177
+ this.sender.stop();
178
+ }
161
179
  getPayloadType(mimeType) {
162
180
  return this.codecs.find((codec) => codec.mimeType.toLowerCase().includes(mimeType.toLowerCase()))?.payloadType;
163
181
  }
164
182
  getCodecStats() {
165
183
  const timestamp = (0, stats_1.getStatsTimestamp)();
184
+ return this.collectCodecStats(timestamp);
185
+ }
186
+ collectCodecStats(timestamp) {
166
187
  const stats = [];
167
188
  if (!this.dtlsTransport) {
168
189
  return stats;
@@ -172,7 +193,7 @@ class RTCRtpTransceiver {
172
193
  for (const codec of this.codecs) {
173
194
  const codecStats = {
174
195
  type: "codec",
175
- id: (0, stats_1.generateStatsId)("codec", codec.payloadType, transportId),
196
+ id: (0, stats_1.generateCodecStatsId)(transportId, codec.payloadType, this.id),
176
197
  timestamp,
177
198
  payloadType: codec.payloadType,
178
199
  transportId,
@@ -1 +1 @@
1
- {"version":3,"file":"rtpTransceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpTransceiver.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { Event } from \"../imports/common\";\n\nimport type { RTCDtlsTransport } from \"..\";\nimport { SenderDirections } from \"../const\";\nimport type { Kind } from \"../types/domain\";\nimport type {\n RTCRtpCodecParameters,\n RTCRtpHeaderExtensionParameters,\n} from \"./parameters\";\nimport type { RTCRtpReceiver } from \"./rtpReceiver\";\nimport type { RTCRtpSender } from \"./rtpSender\";\nimport {\n type RTCCodecStats,\n type RTCStats,\n generateStatsId,\n getStatsTimestamp,\n} from \"./stats\";\nimport type { MediaStream, MediaStreamTrack } from \"./track\";\n\nexport class RTCRtpTransceiver {\n readonly id = randomUUID().toString();\n readonly onTrack = new Event<[MediaStreamTrack, RTCRtpTransceiver]>();\n mid?: string;\n mLineIndex?: number;\n /**should not be reused because it has been used for sending before. */\n usedForSender = false;\n private _currentDirection?: MediaDirection;\n offerDirection!: MediaDirection;\n _codecs: RTCRtpCodecParameters[] = [];\n set codecs(codecs: RTCRtpCodecParameters[]) {\n this._codecs = codecs;\n }\n get codecs() {\n return this._codecs;\n }\n headerExtensions: RTCRtpHeaderExtensionParameters[] = [];\n options: Partial<TransceiverOptions> = {};\n stopping = false;\n stopped = false;\n\n constructor(\n public readonly kind: Kind,\n dtlsTransport: RTCDtlsTransport | undefined,\n public receiver: RTCRtpReceiver,\n public sender: RTCRtpSender,\n /**RFC 8829 4.2.4. direction the transceiver was initialized with */\n private _direction: MediaDirection,\n ) {\n if (dtlsTransport) {\n this.setDtlsTransport(dtlsTransport);\n }\n }\n\n get dtlsTransport() {\n return this.receiver.dtlsTransport;\n }\n\n /**RFC 8829 4.2.4. setDirectionに渡された最後の値を示します */\n get direction() {\n return this._direction;\n }\n\n setDirection(direction: MediaDirection) {\n this._direction = direction;\n if (SenderDirections.includes(this._currentDirection ?? \"\")) {\n this.usedForSender = true;\n }\n }\n\n /**RFC 8829 4.2.5. last negotiated direction */\n get currentDirection(): MediaDirection | undefined {\n return this._currentDirection;\n }\n\n setCurrentDirection(direction: MediaDirection | undefined) {\n this._currentDirection = direction;\n }\n\n setDtlsTransport(dtls: RTCDtlsTransport) {\n this.receiver.setDtlsTransport(dtls);\n this.sender.setDtlsTransport(dtls);\n }\n\n get msid() {\n return `${this.sender.streamId} ${this.sender.trackId}`;\n }\n\n addTrack(track: MediaStreamTrack) {\n const res = this.receiver.addTrack(track);\n if (res) {\n this.onTrack.execute(track, this);\n }\n }\n\n // todo impl\n // https://www.w3.org/TR/webrtc/#methods-8\n stop() {\n if (this.stopping) {\n return;\n }\n\n // todo Stop sending and receiving with transceiver.\n\n this.stopping = true;\n }\n\n getPayloadType(mimeType: string) {\n return this.codecs.find((codec) =>\n codec.mimeType.toLowerCase().includes(mimeType.toLowerCase()),\n )?.payloadType;\n }\n\n getCodecStats(): RTCStats[] {\n const timestamp = getStatsTimestamp();\n const stats: RTCStats[] = [];\n\n if (!this.dtlsTransport) {\n return stats;\n }\n\n const transportId = generateStatsId(\"transport\", this.dtlsTransport.id);\n\n // Add codec stats for each codec\n for (const codec of this.codecs) {\n const codecStats: RTCCodecStats = {\n type: \"codec\",\n id: generateStatsId(\"codec\", codec.payloadType, transportId),\n timestamp,\n payloadType: codec.payloadType,\n transportId,\n mimeType: codec.mimeType,\n clockRate: codec.clockRate,\n channels: codec.channels,\n sdpFmtpLine: codec.parameters,\n };\n stats.push(codecStats);\n }\n\n return stats;\n }\n}\n\nexport const Inactive = \"inactive\";\nexport const Sendonly = \"sendonly\";\nexport const Recvonly = \"recvonly\";\nexport const Sendrecv = \"sendrecv\";\n\nexport const Directions = [Inactive, Sendonly, Recvonly, Sendrecv] as const;\n\nexport type MediaDirection = (typeof Directions)[number];\n\ntype SimulcastDirection = \"send\" | \"recv\";\n\nexport interface TransceiverOptions {\n direction: MediaDirection;\n simulcast: { direction: SimulcastDirection; rid: string }[];\n streams: MediaStream[];\n}\n"]}
1
+ {"version":3,"file":"rtpTransceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpTransceiver.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { Event } from \"../imports/common\";\n\nimport type { RTCDtlsTransport } from \"..\";\nimport { SenderDirections } from \"../const\";\nimport type { Kind } from \"../types/domain\";\nimport type {\n RTCRtpCodecParameters,\n RTCRtpHeaderExtensionParameters,\n} from \"./parameters\";\nimport type { RTCRtpReceiver } from \"./rtpReceiver\";\nimport type { RTCRtpSender } from \"./rtpSender\";\nimport {\n type RTCCodecStats,\n type RTCStats,\n generateCodecStatsId,\n generateStatsId,\n getStatsTimestamp,\n} from \"./stats\";\nimport type { MediaStream, MediaStreamTrack } from \"./track\";\n\nexport class RTCRtpTransceiver {\n readonly id = randomUUID().toString();\n readonly onTrack = new Event<[MediaStreamTrack, RTCRtpTransceiver]>();\n mid: string | null = null;\n mLineIndex?: number;\n /**should not be reused because it has been used for sending before. */\n usedForSender = false;\n private _currentDirection?: CurrentDirection;\n offerDirection!: MediaDirection;\n _codecs: RTCRtpCodecParameters[] = [];\n set codecs(codecs: RTCRtpCodecParameters[]) {\n this._codecs = codecs;\n }\n get codecs() {\n return this._codecs;\n }\n headerExtensions: RTCRtpHeaderExtensionParameters[] = [];\n options: Partial<TransceiverOptions> = {};\n stopping = false;\n stopped = false;\n\n constructor(\n public readonly kind: Kind,\n dtlsTransport: RTCDtlsTransport | undefined,\n public receiver: RTCRtpReceiver,\n public sender: RTCRtpSender,\n /**RFC 8829 4.2.4. direction the transceiver was initialized with */\n private _direction: MediaDirection,\n ) {\n if (dtlsTransport) {\n this.setDtlsTransport(dtlsTransport);\n }\n }\n\n get dtlsTransport() {\n return this.receiver.dtlsTransport;\n }\n\n /**RFC 8829 4.2.4. setDirectionに渡された最後の値を示します */\n get direction() {\n return this._direction;\n }\n\n set direction(direction: MediaDirection) {\n this.setDirection(direction);\n }\n\n setDirection(direction: MediaDirection) {\n this._direction = direction;\n if (\n this._currentDirection &&\n this._currentDirection !== \"stopped\" &&\n SenderDirections.includes(this._currentDirection)\n ) {\n this.usedForSender = true;\n }\n }\n\n /**RFC 8829 4.2.5. last negotiated direction */\n get currentDirection(): CurrentDirection | null {\n return this._currentDirection ?? null;\n }\n\n setCurrentDirection(direction: CurrentDirection | undefined) {\n this._currentDirection = direction;\n }\n\n setDtlsTransport(dtls: RTCDtlsTransport) {\n this.receiver.setDtlsTransport(dtls);\n this.sender.setDtlsTransport(dtls);\n }\n\n get msid() {\n return this.msids[0];\n }\n\n get msids() {\n return this.sender.streamIds.map(\n (streamId) => `${streamId} ${this.sender.trackId}`,\n );\n }\n\n addTrack(track: MediaStreamTrack) {\n const res = this.receiver.addTrack(track);\n if (res) {\n this.onTrack.execute(track, this);\n }\n }\n\n // todo impl\n // https://www.w3.org/TR/webrtc/#methods-8\n stop() {\n if (this.stopping) {\n return;\n }\n\n // todo Stop sending and receiving with transceiver.\n\n this.stopping = true;\n }\n\n forceStop() {\n if (this.stopped) {\n return;\n }\n\n this.stopping = true;\n this.stopped = true;\n this.setCurrentDirection(\"stopped\");\n this.receiver.stop();\n this.sender.stop();\n }\n\n getPayloadType(mimeType: string) {\n return this.codecs.find((codec) =>\n codec.mimeType.toLowerCase().includes(mimeType.toLowerCase()),\n )?.payloadType;\n }\n\n getCodecStats(): RTCStats[] {\n const timestamp = getStatsTimestamp();\n return this.collectCodecStats(timestamp);\n }\n\n collectCodecStats(timestamp: number): RTCStats[] {\n const stats: RTCStats[] = [];\n\n if (!this.dtlsTransport) {\n return stats;\n }\n\n const transportId = generateStatsId(\"transport\", this.dtlsTransport.id);\n\n // Add codec stats for each codec\n for (const codec of this.codecs) {\n const codecStats: RTCCodecStats = {\n type: \"codec\",\n id: generateCodecStatsId(transportId, codec.payloadType, this.id),\n timestamp,\n payloadType: codec.payloadType,\n transportId,\n mimeType: codec.mimeType,\n clockRate: codec.clockRate,\n channels: codec.channels,\n sdpFmtpLine: codec.parameters,\n };\n stats.push(codecStats);\n }\n\n return stats;\n }\n}\n\nexport const Inactive = \"inactive\";\nexport const Sendonly = \"sendonly\";\nexport const Recvonly = \"recvonly\";\nexport const Sendrecv = \"sendrecv\";\n\nexport const Directions = [Inactive, Sendonly, Recvonly, Sendrecv] as const;\n\nexport type MediaDirection = (typeof Directions)[number];\nexport type CurrentDirection = MediaDirection | \"stopped\";\n\ntype SimulcastDirection = \"send\" | \"recv\";\n\nexport interface RTCRtpEncodingParameters {\n active?: boolean;\n}\n\nexport interface TransceiverOptions {\n direction: MediaDirection;\n sendEncodings: RTCRtpEncodingParameters[];\n simulcast: { direction: SimulcastDirection; rid: string }[];\n streams: MediaStream[];\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  * WebRTC Statistics API implementation
3
3
  * Based on: https://www.w3.org/TR/webrtc-stats/
4
4
  */
5
- export type RTCStatsType = "codec" | "inbound-rtp" | "outbound-rtp" | "remote-inbound-rtp" | "remote-outbound-rtp" | "media-source" | "peer-connection" | "data-channel" | "transport" | "candidate-pair" | "local-candidate" | "remote-candidate" | "certificate";
5
+ export type RTCStatsType = "codec" | "inbound-rtp" | "outbound-rtp" | "remote-inbound-rtp" | "remote-outbound-rtp" | "media-source" | "media-playout" | "peer-connection" | "data-channel" | "transport" | "candidate-pair" | "local-candidate" | "remote-candidate" | "certificate";
6
6
  export interface RTCStats {
7
7
  timestamp: number;
8
8
  type: RTCStatsType;
@@ -16,6 +16,7 @@ export interface RTCRtpStreamStats extends RTCStats {
16
16
  }
17
17
  export interface RTCReceivedRtpStreamStats extends RTCRtpStreamStats {
18
18
  packetsReceived?: number;
19
+ bytesReceived?: number;
19
20
  packetsLost?: number;
20
21
  jitter?: number;
21
22
  packetsDiscarded?: number;
@@ -148,6 +149,15 @@ export interface RTCVideoSourceStats extends RTCMediaSourceStats {
148
149
  frames?: number;
149
150
  framesPerSecond?: number;
150
151
  }
152
+ export interface RTCAudioPlayoutStats extends RTCStats {
153
+ type: "media-playout";
154
+ kind: "audio";
155
+ synthesizedSamplesDuration?: number;
156
+ synthesizedSamplesEvents?: number;
157
+ totalSamplesDuration?: number;
158
+ totalPlayoutDelay?: number;
159
+ totalSamplesCount?: number;
160
+ }
151
161
  export interface RTCAudioSourceStats extends RTCMediaSourceStats {
152
162
  audioLevel?: number;
153
163
  totalAudioEnergy?: number;
@@ -226,6 +236,7 @@ export interface RTCIceCandidatePairStats extends RTCStats {
226
236
  lastPacketReceivedTimestamp?: number;
227
237
  totalRoundTripTime?: number;
228
238
  currentRoundTripTime?: number;
239
+ roundTripTimeMeasurements?: number;
229
240
  availableOutgoingBitrate?: number;
230
241
  availableIncomingBitrate?: number;
231
242
  requestsReceived?: number;
@@ -273,7 +284,10 @@ export declare class RTCStatsReport extends Map<string, RTCStats> {
273
284
  * Generate a unique ID for a statistics object
274
285
  */
275
286
  export declare function generateStatsId(type: string, ...parts: (string | number | undefined)[]): string;
287
+ export declare function generateCodecStatsId(transportId: string, payloadType: number, scopeId: string): string;
276
288
  /**
277
289
  * Get current timestamp in milliseconds (DOMHighResTimeStamp)
278
290
  */
279
291
  export declare function getStatsTimestamp(): number;
292
+ export declare function getReferencedStatsIds(stat: RTCStats): string[];
293
+ export declare function buildStatsReport(stats: Iterable<RTCStats>, rootIds?: Iterable<string>): RTCStatsReport;
@@ -6,7 +6,10 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.RTCStatsReport = void 0;
8
8
  exports.generateStatsId = generateStatsId;
9
+ exports.generateCodecStatsId = generateCodecStatsId;
9
10
  exports.getStatsTimestamp = getStatsTimestamp;
11
+ exports.getReferencedStatsIds = getReferencedStatsIds;
12
+ exports.buildStatsReport = buildStatsReport;
10
13
  /**
11
14
  * RTCStatsReport is a Map-like object that holds WebRTC statistics
12
15
  */
@@ -28,10 +31,61 @@ function generateStatsId(type, ...parts) {
28
31
  const validParts = parts.filter((p) => p !== undefined);
29
32
  return `${type}_${validParts.join("_")}`;
30
33
  }
34
+ function generateCodecStatsId(transportId, payloadType, scopeId) {
35
+ return generateStatsId("codec", transportId, payloadType, scopeId);
36
+ }
31
37
  /**
32
38
  * Get current timestamp in milliseconds (DOMHighResTimeStamp)
33
39
  */
34
40
  function getStatsTimestamp() {
35
- return performance.now();
41
+ return performance.timeOrigin + performance.now();
42
+ }
43
+ function getReferencedStatsIds(stat) {
44
+ const references = [];
45
+ for (const [key, value] of Object.entries(stat)) {
46
+ if (key === "id") {
47
+ continue;
48
+ }
49
+ if (key.endsWith("Id")) {
50
+ if (typeof value === "string") {
51
+ references.push(value);
52
+ }
53
+ continue;
54
+ }
55
+ if (key.endsWith("Ids") && Array.isArray(value)) {
56
+ for (const entry of value) {
57
+ if (typeof entry === "string") {
58
+ references.push(entry);
59
+ }
60
+ }
61
+ }
62
+ }
63
+ return references;
64
+ }
65
+ function buildStatsReport(stats, rootIds) {
66
+ const index = new Map();
67
+ for (const stat of stats) {
68
+ index.set(stat.id, stat);
69
+ }
70
+ if (!rootIds) {
71
+ return new RTCStatsReport([...index.values()]);
72
+ }
73
+ const includedIds = new Set();
74
+ const queue = [...new Set(Array.from(rootIds))];
75
+ while (queue.length > 0) {
76
+ const id = queue.shift();
77
+ if (!id || includedIds.has(id)) {
78
+ continue;
79
+ }
80
+ const stat = index.get(id);
81
+ if (!stat) {
82
+ continue;
83
+ }
84
+ includedIds.add(id);
85
+ queue.push(...getReferencedStatsIds(stat));
86
+ }
87
+ return new RTCStatsReport([...includedIds]
88
+ .map((id) => index.get(id))
89
+ .filter((stat) => !!stat));
36
90
  }
37
91
  //# sourceMappingURL=stats.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../../src/media/stats.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA4UH,0CAMC;AAKD,8CAEC;AA9BD;;GAEG;AACH,MAAa,cAAe,SAAQ,GAAqB;IACvD,YAAY,KAAuB;QACjC,KAAK,EAAE,CAAC;QACR,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;CACF;AATD,wCASC;AAED;;GAEG;AACH,SAAgB,eAAe,CAC7B,IAAY,EACZ,GAAG,KAAsC;IAEzC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IACxD,OAAO,GAAG,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["/**\n * WebRTC Statistics API implementation\n * Based on: https://www.w3.org/TR/webrtc-stats/\n */\n\nexport type RTCStatsType =\n | \"codec\"\n | \"inbound-rtp\"\n | \"outbound-rtp\"\n | \"remote-inbound-rtp\"\n | \"remote-outbound-rtp\"\n | \"media-source\"\n | \"peer-connection\"\n | \"data-channel\"\n | \"transport\"\n | \"candidate-pair\"\n | \"local-candidate\"\n | \"remote-candidate\"\n | \"certificate\";\n\nexport interface RTCStats {\n timestamp: number;\n type: RTCStatsType;\n id: string;\n}\n\nexport interface RTCRtpStreamStats extends RTCStats {\n ssrc: number;\n kind: string;\n transportId?: string;\n codecId?: string;\n}\n\nexport interface RTCReceivedRtpStreamStats extends RTCRtpStreamStats {\n packetsReceived?: number;\n packetsLost?: number;\n jitter?: number;\n packetsDiscarded?: number;\n packetsRepaired?: number;\n burstPacketsLost?: number;\n burstPacketsDiscarded?: number;\n burstLossCount?: number;\n burstDiscardCount?: number;\n burstLossRate?: number;\n burstDiscardRate?: number;\n gapLossRate?: number;\n gapDiscardRate?: number;\n framesDropped?: number;\n partialFramesLost?: number;\n fullFramesLost?: number;\n}\n\nexport interface RTCInboundRtpStreamStats extends RTCReceivedRtpStreamStats {\n type: \"inbound-rtp\";\n trackIdentifier?: string;\n mid?: string;\n remoteId?: string;\n framesDecoded?: number;\n keyFramesDecoded?: number;\n frameWidth?: number;\n frameHeight?: number;\n frameBitDepth?: number;\n framesPerSecond?: number;\n qpSum?: number;\n totalDecodeTime?: number;\n totalInterFrameDelay?: number;\n totalSquaredInterFrameDelay?: number;\n lastPacketReceivedTimestamp?: number;\n headerBytesReceived?: number;\n packetsFailedDecryption?: number;\n packetsDuplicated?: number;\n perDscpPacketsReceived?: Record<string, number>;\n nackCount?: number;\n firCount?: number;\n pliCount?: number;\n totalProcessingDelay?: number;\n estimatedPlayoutTimestamp?: number;\n jitterBufferDelay?: number;\n jitterBufferTargetDelay?: number;\n jitterBufferEmittedCount?: number;\n jitterBufferMinimumDelay?: number;\n totalSamplesReceived?: number;\n concealedSamples?: number;\n silentConcealedSamples?: number;\n concealmentEvents?: number;\n insertedSamplesForDeceleration?: number;\n removedSamplesForAcceleration?: number;\n audioLevel?: number;\n totalAudioEnergy?: number;\n totalSamplesDuration?: number;\n framesReceived?: number;\n decoderImplementation?: string;\n playoutId?: string;\n powerEfficientDecoder?: boolean;\n framesAssembledFromMultiplePackets?: number;\n totalAssemblyTime?: number;\n retransmittedPacketsReceived?: number;\n retransmittedBytesReceived?: number;\n rtxSsrc?: number;\n fecSsrc?: number;\n}\n\nexport interface RTCSentRtpStreamStats extends RTCRtpStreamStats {\n packetsSent?: number;\n bytesSent?: number;\n}\n\nexport interface RTCOutboundRtpStreamStats extends RTCSentRtpStreamStats {\n type: \"outbound-rtp\";\n mid?: string;\n mediaSourceId?: string;\n remoteId?: string;\n rid?: string;\n headerBytesSent?: number;\n retransmittedPacketsSent?: number;\n retransmittedBytesSent?: number;\n rtxSsrc?: number;\n targetBitrate?: number;\n totalEncodedBytesTarget?: number;\n frameWidth?: number;\n frameHeight?: number;\n frameBitDepth?: number;\n framesPerSecond?: number;\n framesSent?: number;\n hugeFramesSent?: number;\n framesEncoded?: number;\n keyFramesEncoded?: number;\n qpSum?: number;\n totalEncodeTime?: number;\n totalPacketSendDelay?: number;\n qualityLimitationReason?: string;\n qualityLimitationDurations?: Record<string, number>;\n qualityLimitationResolutionChanges?: number;\n perDscpPacketsSent?: Record<string, number>;\n nackCount?: number;\n firCount?: number;\n pliCount?: number;\n encoderImplementation?: string;\n powerEfficientEncoder?: boolean;\n active?: boolean;\n scalabilityMode?: string;\n}\n\nexport interface RTCRemoteInboundRtpStreamStats\n extends RTCReceivedRtpStreamStats {\n type: \"remote-inbound-rtp\";\n localId?: string;\n roundTripTime?: number;\n totalRoundTripTime?: number;\n fractionLost?: number;\n roundTripTimeMeasurements?: number;\n}\n\nexport interface RTCRemoteOutboundRtpStreamStats extends RTCSentRtpStreamStats {\n type: \"remote-outbound-rtp\";\n localId?: string;\n remoteTimestamp?: number;\n reportsSent?: number;\n roundTripTime?: number;\n totalRoundTripTime?: number;\n roundTripTimeMeasurements?: number;\n}\n\nexport interface RTCMediaSourceStats extends RTCStats {\n type: \"media-source\";\n trackIdentifier: string;\n kind: string;\n}\n\nexport interface RTCVideoSourceStats extends RTCMediaSourceStats {\n width?: number;\n height?: number;\n frames?: number;\n framesPerSecond?: number;\n}\n\nexport interface RTCAudioSourceStats extends RTCMediaSourceStats {\n audioLevel?: number;\n totalAudioEnergy?: number;\n totalSamplesDuration?: number;\n echoReturnLoss?: number;\n echoReturnLossEnhancement?: number;\n droppedSamplesDuration?: number;\n droppedSamplesEvents?: number;\n totalCaptureDelay?: number;\n totalSamplesCaptured?: number;\n}\n\nexport interface RTCPeerConnectionStats extends RTCStats {\n type: \"peer-connection\";\n dataChannelsOpened?: number;\n dataChannelsClosed?: number;\n}\n\nexport interface RTCDataChannelStats extends RTCStats {\n type: \"data-channel\";\n label?: string;\n protocol?: string;\n dataChannelIdentifier?: number;\n state: RTCDataChannelState;\n messagesSent?: number;\n bytesSent?: number;\n messagesReceived?: number;\n bytesReceived?: number;\n}\n\nexport interface RTCTransportStats extends RTCStats {\n type: \"transport\";\n bytesSent?: number;\n packetsSent?: number;\n bytesReceived?: number;\n packetsReceived?: number;\n rtcpTransportStatsId?: string;\n iceRole?: RTCIceRole;\n iceLocalUsernameFragment?: string;\n dtlsState: RTCDtlsTransportState;\n iceState?: RTCIceTransportState;\n selectedCandidatePairId?: string;\n localCertificateId?: string;\n remoteCertificateId?: string;\n tlsVersion?: string;\n dtlsCipher?: string;\n dtlsRole?: RTCDtlsRole;\n srtpCipher?: string;\n selectedCandidatePairChanges?: number;\n iceRestarts?: number;\n}\n\nexport interface RTCIceCandidateStats extends RTCStats {\n transportId?: string;\n address?: string;\n port?: number;\n protocol?: string;\n candidateType: RTCIceCandidateType;\n priority?: number;\n url?: string;\n relayProtocol?: string;\n foundation?: string;\n relatedAddress?: string;\n relatedPort?: number;\n usernameFragment?: string;\n tcpType?: RTCIceTcpCandidateType;\n}\n\nexport interface RTCIceCandidatePairStats extends RTCStats {\n type: \"candidate-pair\";\n transportId?: string;\n localCandidateId: string;\n remoteCandidateId: string;\n state: RTCStatsIceCandidatePairState;\n nominated?: boolean;\n packetsSent?: number;\n packetsReceived?: number;\n bytesSent?: number;\n bytesReceived?: number;\n lastPacketSentTimestamp?: number;\n lastPacketReceivedTimestamp?: number;\n totalRoundTripTime?: number;\n currentRoundTripTime?: number;\n availableOutgoingBitrate?: number;\n availableIncomingBitrate?: number;\n requestsReceived?: number;\n requestsSent?: number;\n responsesReceived?: number;\n responsesSent?: number;\n retransmissionsReceived?: number;\n retransmissionsSent?: number;\n consentRequestsSent?: number;\n consentExpiredTimestamp?: number;\n packetsDiscardedOnSend?: number;\n bytesDiscardedOnSend?: number;\n}\n\nexport interface RTCCertificateStats extends RTCStats {\n type: \"certificate\";\n fingerprint: string;\n fingerprintAlgorithm: string;\n base64Certificate: string;\n issuerCertificateId?: string;\n}\n\nexport interface RTCCodecStats extends RTCStats {\n type: \"codec\";\n payloadType: number;\n transportId: string;\n mimeType: string;\n clockRate?: number;\n channels?: number;\n sdpFmtpLine?: string;\n}\n\n// Type definitions\nexport type RTCDataChannelState = \"connecting\" | \"open\" | \"closing\" | \"closed\";\nexport type RTCDtlsTransportState =\n | \"new\"\n | \"connecting\"\n | \"connected\"\n | \"closed\"\n | \"failed\";\nexport type RTCIceTransportState =\n | \"new\"\n | \"checking\"\n | \"connected\"\n | \"completed\"\n | \"disconnected\"\n | \"failed\"\n | \"closed\";\nexport type RTCIceRole = \"controlling\" | \"controlled\";\nexport type RTCDtlsRole = \"client\" | \"server\";\nexport type RTCIceCandidateType = \"host\" | \"srflx\" | \"prflx\" | \"relay\";\nexport type RTCIceTcpCandidateType = \"active\" | \"passive\" | \"so\";\nexport type RTCStatsIceCandidatePairState =\n | \"frozen\"\n | \"waiting\"\n | \"in-progress\"\n | \"failed\"\n | \"succeeded\";\n\n/**\n * RTCStatsReport is a Map-like object that holds WebRTC statistics\n */\nexport class RTCStatsReport extends Map<string, RTCStats> {\n constructor(stats?: Array<RTCStats>) {\n super();\n if (stats) {\n for (const stat of stats) {\n this.set(stat.id, stat);\n }\n }\n }\n}\n\n/**\n * Generate a unique ID for a statistics object\n */\nexport function generateStatsId(\n type: string,\n ...parts: (string | number | undefined)[]\n): string {\n const validParts = parts.filter((p) => p !== undefined);\n return `${type}_${validParts.join(\"_\")}`;\n}\n\n/**\n * Get current timestamp in milliseconds (DOMHighResTimeStamp)\n */\nexport function getStatsTimestamp(): number {\n return performance.now();\n}\n"]}
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../../src/media/stats.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WebRTC Statistics API implementation\n * Based on: https://www.w3.org/TR/webrtc-stats/\n */\n\nexport type RTCStatsType =\n | \"codec\"\n | \"inbound-rtp\"\n | \"outbound-rtp\"\n | \"remote-inbound-rtp\"\n | \"remote-outbound-rtp\"\n | \"media-source\"\n | \"media-playout\"\n | \"peer-connection\"\n | \"data-channel\"\n | \"transport\"\n | \"candidate-pair\"\n | \"local-candidate\"\n | \"remote-candidate\"\n | \"certificate\";\n\nexport interface RTCStats {\n timestamp: number;\n type: RTCStatsType;\n id: string;\n}\n\nexport interface RTCRtpStreamStats extends RTCStats {\n ssrc: number;\n kind: string;\n transportId?: string;\n codecId?: string;\n}\n\nexport interface RTCReceivedRtpStreamStats extends RTCRtpStreamStats {\n packetsReceived?: number;\n bytesReceived?: number;\n packetsLost?: number;\n jitter?: number;\n packetsDiscarded?: number;\n packetsRepaired?: number;\n burstPacketsLost?: number;\n burstPacketsDiscarded?: number;\n burstLossCount?: number;\n burstDiscardCount?: number;\n burstLossRate?: number;\n burstDiscardRate?: number;\n gapLossRate?: number;\n gapDiscardRate?: number;\n framesDropped?: number;\n partialFramesLost?: number;\n fullFramesLost?: number;\n}\n\nexport interface RTCInboundRtpStreamStats extends RTCReceivedRtpStreamStats {\n type: \"inbound-rtp\";\n trackIdentifier?: string;\n mid?: string;\n remoteId?: string;\n framesDecoded?: number;\n keyFramesDecoded?: number;\n frameWidth?: number;\n frameHeight?: number;\n frameBitDepth?: number;\n framesPerSecond?: number;\n qpSum?: number;\n totalDecodeTime?: number;\n totalInterFrameDelay?: number;\n totalSquaredInterFrameDelay?: number;\n lastPacketReceivedTimestamp?: number;\n headerBytesReceived?: number;\n packetsFailedDecryption?: number;\n packetsDuplicated?: number;\n perDscpPacketsReceived?: Record<string, number>;\n nackCount?: number;\n firCount?: number;\n pliCount?: number;\n totalProcessingDelay?: number;\n estimatedPlayoutTimestamp?: number;\n jitterBufferDelay?: number;\n jitterBufferTargetDelay?: number;\n jitterBufferEmittedCount?: number;\n jitterBufferMinimumDelay?: number;\n totalSamplesReceived?: number;\n concealedSamples?: number;\n silentConcealedSamples?: number;\n concealmentEvents?: number;\n insertedSamplesForDeceleration?: number;\n removedSamplesForAcceleration?: number;\n audioLevel?: number;\n totalAudioEnergy?: number;\n totalSamplesDuration?: number;\n framesReceived?: number;\n decoderImplementation?: string;\n playoutId?: string;\n powerEfficientDecoder?: boolean;\n framesAssembledFromMultiplePackets?: number;\n totalAssemblyTime?: number;\n retransmittedPacketsReceived?: number;\n retransmittedBytesReceived?: number;\n rtxSsrc?: number;\n fecSsrc?: number;\n}\n\nexport interface RTCSentRtpStreamStats extends RTCRtpStreamStats {\n packetsSent?: number;\n bytesSent?: number;\n}\n\nexport interface RTCOutboundRtpStreamStats extends RTCSentRtpStreamStats {\n type: \"outbound-rtp\";\n mid?: string;\n mediaSourceId?: string;\n remoteId?: string;\n rid?: string;\n headerBytesSent?: number;\n retransmittedPacketsSent?: number;\n retransmittedBytesSent?: number;\n rtxSsrc?: number;\n targetBitrate?: number;\n totalEncodedBytesTarget?: number;\n frameWidth?: number;\n frameHeight?: number;\n frameBitDepth?: number;\n framesPerSecond?: number;\n framesSent?: number;\n hugeFramesSent?: number;\n framesEncoded?: number;\n keyFramesEncoded?: number;\n qpSum?: number;\n totalEncodeTime?: number;\n totalPacketSendDelay?: number;\n qualityLimitationReason?: string;\n qualityLimitationDurations?: Record<string, number>;\n qualityLimitationResolutionChanges?: number;\n perDscpPacketsSent?: Record<string, number>;\n nackCount?: number;\n firCount?: number;\n pliCount?: number;\n encoderImplementation?: string;\n powerEfficientEncoder?: boolean;\n active?: boolean;\n scalabilityMode?: string;\n}\n\nexport interface RTCRemoteInboundRtpStreamStats\n extends RTCReceivedRtpStreamStats {\n type: \"remote-inbound-rtp\";\n localId?: string;\n roundTripTime?: number;\n totalRoundTripTime?: number;\n fractionLost?: number;\n roundTripTimeMeasurements?: number;\n}\n\nexport interface RTCRemoteOutboundRtpStreamStats extends RTCSentRtpStreamStats {\n type: \"remote-outbound-rtp\";\n localId?: string;\n remoteTimestamp?: number;\n reportsSent?: number;\n roundTripTime?: number;\n totalRoundTripTime?: number;\n roundTripTimeMeasurements?: number;\n}\n\nexport interface RTCMediaSourceStats extends RTCStats {\n type: \"media-source\";\n trackIdentifier: string;\n kind: string;\n}\n\nexport interface RTCVideoSourceStats extends RTCMediaSourceStats {\n width?: number;\n height?: number;\n frames?: number;\n framesPerSecond?: number;\n}\n\nexport interface RTCAudioPlayoutStats extends RTCStats {\n type: \"media-playout\";\n kind: \"audio\";\n synthesizedSamplesDuration?: number;\n synthesizedSamplesEvents?: number;\n totalSamplesDuration?: number;\n totalPlayoutDelay?: number;\n totalSamplesCount?: number;\n}\n\nexport interface RTCAudioSourceStats extends RTCMediaSourceStats {\n audioLevel?: number;\n totalAudioEnergy?: number;\n totalSamplesDuration?: number;\n echoReturnLoss?: number;\n echoReturnLossEnhancement?: number;\n droppedSamplesDuration?: number;\n droppedSamplesEvents?: number;\n totalCaptureDelay?: number;\n totalSamplesCaptured?: number;\n}\n\nexport interface RTCPeerConnectionStats extends RTCStats {\n type: \"peer-connection\";\n dataChannelsOpened?: number;\n dataChannelsClosed?: number;\n}\n\nexport interface RTCDataChannelStats extends RTCStats {\n type: \"data-channel\";\n label?: string;\n protocol?: string;\n dataChannelIdentifier?: number;\n state: RTCDataChannelState;\n messagesSent?: number;\n bytesSent?: number;\n messagesReceived?: number;\n bytesReceived?: number;\n}\n\nexport interface RTCTransportStats extends RTCStats {\n type: \"transport\";\n bytesSent?: number;\n packetsSent?: number;\n bytesReceived?: number;\n packetsReceived?: number;\n rtcpTransportStatsId?: string;\n iceRole?: RTCIceRole;\n iceLocalUsernameFragment?: string;\n dtlsState: RTCDtlsTransportState;\n iceState?: RTCIceTransportState;\n selectedCandidatePairId?: string;\n localCertificateId?: string;\n remoteCertificateId?: string;\n tlsVersion?: string;\n dtlsCipher?: string;\n dtlsRole?: RTCDtlsRole;\n srtpCipher?: string;\n selectedCandidatePairChanges?: number;\n iceRestarts?: number;\n}\n\nexport interface RTCIceCandidateStats extends RTCStats {\n transportId?: string;\n address?: string;\n port?: number;\n protocol?: string;\n candidateType: RTCIceCandidateType;\n priority?: number;\n url?: string;\n relayProtocol?: string;\n foundation?: string;\n relatedAddress?: string;\n relatedPort?: number;\n usernameFragment?: string;\n tcpType?: RTCIceTcpCandidateType;\n}\n\nexport interface RTCIceCandidatePairStats extends RTCStats {\n type: \"candidate-pair\";\n transportId?: string;\n localCandidateId: string;\n remoteCandidateId: string;\n state: RTCStatsIceCandidatePairState;\n nominated?: boolean;\n packetsSent?: number;\n packetsReceived?: number;\n bytesSent?: number;\n bytesReceived?: number;\n lastPacketSentTimestamp?: number;\n lastPacketReceivedTimestamp?: number;\n totalRoundTripTime?: number;\n currentRoundTripTime?: number;\n roundTripTimeMeasurements?: number;\n availableOutgoingBitrate?: number;\n availableIncomingBitrate?: number;\n requestsReceived?: number;\n requestsSent?: number;\n responsesReceived?: number;\n responsesSent?: number;\n retransmissionsReceived?: number;\n retransmissionsSent?: number;\n consentRequestsSent?: number;\n consentExpiredTimestamp?: number;\n packetsDiscardedOnSend?: number;\n bytesDiscardedOnSend?: number;\n}\n\nexport interface RTCCertificateStats extends RTCStats {\n type: \"certificate\";\n fingerprint: string;\n fingerprintAlgorithm: string;\n base64Certificate: string;\n issuerCertificateId?: string;\n}\n\nexport interface RTCCodecStats extends RTCStats {\n type: \"codec\";\n payloadType: number;\n transportId: string;\n mimeType: string;\n clockRate?: number;\n channels?: number;\n sdpFmtpLine?: string;\n}\n\n// Type definitions\nexport type RTCDataChannelState = \"connecting\" | \"open\" | \"closing\" | \"closed\";\nexport type RTCDtlsTransportState =\n | \"new\"\n | \"connecting\"\n | \"connected\"\n | \"closed\"\n | \"failed\";\nexport type RTCIceTransportState =\n | \"new\"\n | \"checking\"\n | \"connected\"\n | \"completed\"\n | \"disconnected\"\n | \"failed\"\n | \"closed\";\nexport type RTCIceRole = \"controlling\" | \"controlled\";\nexport type RTCDtlsRole = \"client\" | \"server\";\nexport type RTCIceCandidateType = \"host\" | \"srflx\" | \"prflx\" | \"relay\";\nexport type RTCIceTcpCandidateType = \"active\" | \"passive\" | \"so\";\nexport type RTCStatsIceCandidatePairState =\n | \"frozen\"\n | \"waiting\"\n | \"in-progress\"\n | \"failed\"\n | \"succeeded\";\n\n/**\n * RTCStatsReport is a Map-like object that holds WebRTC statistics\n */\nexport class RTCStatsReport extends Map<string, RTCStats> {\n constructor(stats?: Array<RTCStats>) {\n super();\n if (stats) {\n for (const stat of stats) {\n this.set(stat.id, stat);\n }\n }\n }\n}\n\n/**\n * Generate a unique ID for a statistics object\n */\nexport function generateStatsId(\n type: string,\n ...parts: (string | number | undefined)[]\n): string {\n const validParts = parts.filter((p) => p !== undefined);\n return `${type}_${validParts.join(\"_\")}`;\n}\n\nexport function generateCodecStatsId(\n transportId: string,\n payloadType: number,\n scopeId: string,\n) {\n return generateStatsId(\"codec\", transportId, payloadType, scopeId);\n}\n\n/**\n * Get current timestamp in milliseconds (DOMHighResTimeStamp)\n */\nexport function getStatsTimestamp(): number {\n return performance.timeOrigin + performance.now();\n}\n\nexport function getReferencedStatsIds(stat: RTCStats): string[] {\n const references: string[] = [];\n\n for (const [key, value] of Object.entries(\n stat as unknown as Record<string, unknown>,\n )) {\n if (key === \"id\") {\n continue;\n }\n\n if (key.endsWith(\"Id\")) {\n if (typeof value === \"string\") {\n references.push(value);\n }\n continue;\n }\n\n if (key.endsWith(\"Ids\") && Array.isArray(value)) {\n for (const entry of value) {\n if (typeof entry === \"string\") {\n references.push(entry);\n }\n }\n }\n }\n\n return references;\n}\n\nexport function buildStatsReport(\n stats: Iterable<RTCStats>,\n rootIds?: Iterable<string>,\n): RTCStatsReport {\n const index = new Map<string, RTCStats>();\n for (const stat of stats) {\n index.set(stat.id, stat);\n }\n\n if (!rootIds) {\n return new RTCStatsReport([...index.values()]);\n }\n\n const includedIds = new Set<string>();\n const queue = [...new Set(Array.from(rootIds))];\n\n while (queue.length > 0) {\n const id = queue.shift();\n if (!id || includedIds.has(id)) {\n continue;\n }\n\n const stat = index.get(id);\n if (!stat) {\n continue;\n }\n\n includedIds.add(id);\n queue.push(...getReferencedStatsIds(stat));\n }\n\n return new RTCStatsReport(\n [...includedIds]\n .map((id) => index.get(id))\n .filter((stat): stat is RTCStats => !!stat),\n );\n}\n"]}
@@ -30,8 +30,9 @@ export declare class MediaStreamTrack extends EventTarget {
30
30
  export declare class MediaStream {
31
31
  id: string;
32
32
  tracks: MediaStreamTrack[];
33
- constructor(props: Partial<MediaStream> | MediaStreamTrack[]);
33
+ constructor(props?: Partial<MediaStream> | MediaStreamTrack[]);
34
34
  addTrack(track: MediaStreamTrack): void;
35
+ removeTrack(track: MediaStreamTrack): void;
35
36
  getTracks(): MediaStreamTrack[];
36
37
  getAudioTracks(): MediaStreamTrack[];
37
38
  getVideoTracks(): MediaStreamTrack[];
@@ -145,7 +145,7 @@ class MediaStreamTrack extends helper_1.EventTarget {
145
145
  }
146
146
  exports.MediaStreamTrack = MediaStreamTrack;
147
147
  class MediaStream {
148
- constructor(props) {
148
+ constructor(props = {}) {
149
149
  Object.defineProperty(this, "id", {
150
150
  enumerable: true,
151
151
  configurable: true,
@@ -170,6 +170,12 @@ class MediaStream {
170
170
  track.streamId = this.id;
171
171
  this.tracks.push(track);
172
172
  }
173
+ removeTrack(track) {
174
+ this.tracks = this.tracks.filter((currentTrack) => currentTrack !== track);
175
+ if (track.streamId === this.id) {
176
+ track.streamId = undefined;
177
+ }
178
+ }
173
179
  getTracks() {
174
180
  return this.tracks;
175
181
  }
@@ -1 +1 @@
1
- {"version":3,"file":"track.js","sourceRoot":"","sources":["../../../../src/media/track.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { Event } from \"../imports/common\";\n\nimport { EventTarget } from \"../helper\";\nimport {\n type Extensions,\n type RtcpPacket,\n type RtpHeader,\n RtpPacket,\n} from \"../imports/rtp\";\nimport type { Kind } from \"../types/domain\";\nimport type { RTCRtpCodecParameters } from \"./parameters\";\n\nexport class MediaStreamTrack extends EventTarget {\n readonly uuid = randomUUID().toString();\n /**MediaStream ID*/\n streamId?: string;\n remote = false;\n label: string;\n kind!: Kind;\n id?: string;\n /**mediaSsrc */\n ssrc?: number;\n rid?: string;\n header?: RtpHeader;\n codec?: RTCRtpCodecParameters;\n /**todo impl */\n enabled = true;\n\n readonly onReceiveRtp = new Event<[RtpPacket, Extensions?]>();\n readonly onReceiveRtcp = new Event<[RtcpPacket]>();\n readonly onSourceChanged = new Event<\n [Pick<RtpHeader, \"sequenceNumber\" | \"timestamp\">]\n >();\n\n stopped = false;\n muted = true;\n\n constructor(\n props: Partial<MediaStreamTrack> & Pick<MediaStreamTrack, \"kind\">,\n ) {\n super();\n Object.assign(this, props);\n\n this.onReceiveRtp.subscribe((rtp) => {\n this.muted = false;\n this.header = rtp.header;\n });\n\n this.label = `${this.remote ? \"remote\" : \"local\"} ${this.kind}`;\n }\n\n stop = () => {\n this.stopped = true;\n this.muted = true;\n this.onReceiveRtp.complete();\n this.emit(\"ended\");\n };\n\n writeRtp = (rtp: RtpPacket | Buffer) => {\n if (this.remote) {\n throw new Error(\"this is remoteTrack\");\n }\n if (this.stopped) {\n return;\n }\n\n const packet = Buffer.isBuffer(rtp) ? RtpPacket.deSerialize(rtp) : rtp;\n packet.header.payloadType =\n this.codec?.payloadType ?? packet.header.payloadType;\n this.onReceiveRtp.execute(packet);\n };\n}\n\nexport class MediaStream {\n id!: string;\n tracks: MediaStreamTrack[] = [];\n\n constructor(props: Partial<MediaStream> | MediaStreamTrack[]) {\n if (Array.isArray(props)) {\n this.tracks = props;\n } else {\n Object.assign(this, props);\n }\n this.id ??= randomUUID().toString();\n }\n\n addTrack(track: MediaStreamTrack) {\n track.streamId = this.id;\n this.tracks.push(track);\n }\n\n getTracks() {\n return this.tracks;\n }\n\n getAudioTracks() {\n return this.tracks.filter((track) => track.kind === \"audio\");\n }\n\n getVideoTracks() {\n return this.tracks.filter((track) => track.kind === \"video\");\n }\n}\n"]}
1
+ {"version":3,"file":"track.js","sourceRoot":"","sources":["../../../../src/media/track.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { Event } from \"../imports/common\";\n\nimport { EventTarget } from \"../helper\";\nimport {\n type Extensions,\n type RtcpPacket,\n type RtpHeader,\n RtpPacket,\n} from \"../imports/rtp\";\nimport type { Kind } from \"../types/domain\";\nimport type { RTCRtpCodecParameters } from \"./parameters\";\n\nexport class MediaStreamTrack extends EventTarget {\n readonly uuid = randomUUID().toString();\n /**MediaStream ID*/\n streamId?: string;\n remote = false;\n label: string;\n kind!: Kind;\n id?: string;\n /**mediaSsrc */\n ssrc?: number;\n rid?: string;\n header?: RtpHeader;\n codec?: RTCRtpCodecParameters;\n /**todo impl */\n enabled = true;\n\n readonly onReceiveRtp = new Event<[RtpPacket, Extensions?]>();\n readonly onReceiveRtcp = new Event<[RtcpPacket]>();\n readonly onSourceChanged = new Event<\n [Pick<RtpHeader, \"sequenceNumber\" | \"timestamp\">]\n >();\n\n stopped = false;\n muted = true;\n\n constructor(\n props: Partial<MediaStreamTrack> & Pick<MediaStreamTrack, \"kind\">,\n ) {\n super();\n Object.assign(this, props);\n\n this.onReceiveRtp.subscribe((rtp) => {\n this.muted = false;\n this.header = rtp.header;\n });\n\n this.label = `${this.remote ? \"remote\" : \"local\"} ${this.kind}`;\n }\n\n stop = () => {\n this.stopped = true;\n this.muted = true;\n this.onReceiveRtp.complete();\n this.emit(\"ended\");\n };\n\n writeRtp = (rtp: RtpPacket | Buffer) => {\n if (this.remote) {\n throw new Error(\"this is remoteTrack\");\n }\n if (this.stopped) {\n return;\n }\n\n const packet = Buffer.isBuffer(rtp) ? RtpPacket.deSerialize(rtp) : rtp;\n packet.header.payloadType =\n this.codec?.payloadType ?? packet.header.payloadType;\n this.onReceiveRtp.execute(packet);\n };\n}\n\nexport class MediaStream {\n id!: string;\n tracks: MediaStreamTrack[] = [];\n\n constructor(props: Partial<MediaStream> | MediaStreamTrack[] = {}) {\n if (Array.isArray(props)) {\n this.tracks = props;\n } else {\n Object.assign(this, props);\n }\n this.id ??= randomUUID().toString();\n }\n\n addTrack(track: MediaStreamTrack) {\n track.streamId = this.id;\n this.tracks.push(track);\n }\n\n removeTrack(track: MediaStreamTrack) {\n this.tracks = this.tracks.filter((currentTrack) => currentTrack !== track);\n if (track.streamId === this.id) {\n track.streamId = undefined;\n }\n }\n\n getTracks() {\n return this.tracks;\n }\n\n getAudioTracks() {\n return this.tracks.filter((track) => track.kind === \"audio\");\n }\n\n getVideoTracks() {\n return this.tracks.filter((track) => track.kind === \"video\");\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import { MediaStreamTrack } from "../media/track";
2
+ export interface DummyAudioOptions {
3
+ packetIntervalMs: number;
4
+ }
5
+ export interface DummyVideoOptions {
6
+ fps: number;
7
+ keyframeIntervalFrames: number;
8
+ }
9
+ export interface DummySource {
10
+ stop(): void;
11
+ }
12
+ export declare function createDummyAudioTrack(options?: Partial<DummyAudioOptions>): {
13
+ track: MediaStreamTrack;
14
+ source: DummySource;
15
+ };
16
+ export declare function createDummyVideoTrack(options?: Partial<DummyVideoOptions>): {
17
+ track: MediaStreamTrack;
18
+ source: DummySource;
19
+ };