werift 0.20.0 → 0.20.1

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 (139) hide show
  1. package/lib/common/src/event.d.ts +45 -0
  2. package/lib/common/src/event.js +232 -0
  3. package/lib/common/src/event.js.map +1 -0
  4. package/lib/common/src/index.d.ts +1 -0
  5. package/lib/common/src/index.js +1 -0
  6. package/lib/common/src/index.js.map +1 -1
  7. package/lib/dtls/src/flight/client/flight5.js +6 -1
  8. package/lib/dtls/src/flight/client/flight5.js.map +1 -1
  9. package/lib/dtls/src/imports/common.d.ts +1 -0
  10. package/lib/dtls/src/imports/common.js +18 -0
  11. package/lib/dtls/src/imports/common.js.map +1 -0
  12. package/lib/dtls/src/socket.d.ts +1 -1
  13. package/lib/dtls/src/socket.js +5 -5
  14. package/lib/dtls/src/socket.js.map +1 -1
  15. package/lib/ice/src/candidate.d.ts +1 -1
  16. package/lib/ice/src/candidate.js +2 -1
  17. package/lib/ice/src/candidate.js.map +1 -1
  18. package/lib/ice/src/helper.js +2 -2
  19. package/lib/ice/src/helper.js.map +1 -1
  20. package/lib/ice/src/ice.d.ts +10 -5
  21. package/lib/ice/src/ice.js +46 -16
  22. package/lib/ice/src/ice.js.map +1 -1
  23. package/lib/ice/src/imports/common.d.ts +1 -0
  24. package/lib/ice/src/imports/common.js +18 -0
  25. package/lib/ice/src/imports/common.js.map +1 -0
  26. package/lib/ice/src/index.d.ts +4 -0
  27. package/lib/ice/src/index.js +4 -0
  28. package/lib/ice/src/index.js.map +1 -1
  29. package/lib/ice/src/stun/message.d.ts +1 -0
  30. package/lib/ice/src/stun/message.js +16 -6
  31. package/lib/ice/src/stun/message.js.map +1 -1
  32. package/lib/ice/src/stun/protocol.d.ts +3 -2
  33. package/lib/ice/src/stun/protocol.js +13 -7
  34. package/lib/ice/src/stun/protocol.js.map +1 -1
  35. package/lib/ice/src/stun/transaction.js +4 -3
  36. package/lib/ice/src/stun/transaction.js.map +1 -1
  37. package/lib/ice/src/transport.d.ts +21 -4
  38. package/lib/ice/src/transport.js +115 -7
  39. package/lib/ice/src/transport.js.map +1 -1
  40. package/lib/ice/src/turn/protocol.d.ts +52 -36
  41. package/lib/ice/src/turn/protocol.js +183 -76
  42. package/lib/ice/src/turn/protocol.js.map +1 -1
  43. package/lib/ice/src/types/model.d.ts +5 -5
  44. package/lib/ice/src/types/model.js.map +1 -1
  45. package/lib/ice/src/utils.d.ts +1 -0
  46. package/lib/ice/src/utils.js +15 -16
  47. package/lib/ice/src/utils.js.map +1 -1
  48. package/lib/rtp/src/extra/container/mp4/container.d.ts +1 -1
  49. package/lib/rtp/src/extra/container/mp4/container.js +2 -5
  50. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  51. package/lib/rtp/src/extra/processor/depacketizer.d.ts +1 -1
  52. package/lib/rtp/src/extra/processor/depacketizer.js +2 -2
  53. package/lib/rtp/src/extra/processor/depacketizer.js.map +1 -1
  54. package/lib/rtp/src/extra/processor/mp4.d.ts +1 -1
  55. package/lib/rtp/src/extra/processor/mp4.js +2 -5
  56. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  57. package/lib/rtp/src/extra/processor/nack.d.ts +1 -1
  58. package/lib/rtp/src/extra/processor/nack.js +3 -3
  59. package/lib/rtp/src/extra/processor/nack.js.map +1 -1
  60. package/lib/rtp/src/extra/processor/rtcpCallback.d.ts +1 -1
  61. package/lib/rtp/src/extra/processor/rtcpCallback.js +2 -5
  62. package/lib/rtp/src/extra/processor/rtcpCallback.js.map +1 -1
  63. package/lib/rtp/src/extra/processor/rtpCallback.d.ts +1 -1
  64. package/lib/rtp/src/extra/processor/rtpCallback.js +2 -5
  65. package/lib/rtp/src/extra/processor/rtpCallback.js.map +1 -1
  66. package/lib/rtp/src/extra/processor/webm.d.ts +1 -1
  67. package/lib/rtp/src/extra/processor/webm.js +2 -5
  68. package/lib/rtp/src/extra/processor/webm.js.map +1 -1
  69. package/lib/rtp/src/imports/common.d.ts +1 -0
  70. package/lib/rtp/src/imports/common.js +18 -0
  71. package/lib/rtp/src/imports/common.js.map +1 -0
  72. package/lib/sctp/src/helper.js +2 -5
  73. package/lib/sctp/src/helper.js.map +1 -1
  74. package/lib/sctp/src/imports/common.d.ts +1 -0
  75. package/lib/sctp/src/imports/common.js +18 -0
  76. package/lib/sctp/src/imports/common.js.map +1 -0
  77. package/lib/sctp/src/sctp.d.ts +1 -1
  78. package/lib/sctp/src/sctp.js +3 -3
  79. package/lib/sctp/src/sctp.js.map +1 -1
  80. package/lib/webrtc/src/dataChannel.d.ts +1 -1
  81. package/lib/webrtc/src/dataChannel.js +5 -5
  82. package/lib/webrtc/src/dataChannel.js.map +1 -1
  83. package/lib/webrtc/src/imports/common.d.ts +1 -0
  84. package/lib/webrtc/src/imports/common.js +18 -0
  85. package/lib/webrtc/src/imports/common.js.map +1 -0
  86. package/lib/webrtc/src/media/receiver/nack.d.ts +1 -1
  87. package/lib/webrtc/src/media/receiver/nack.js +2 -2
  88. package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
  89. package/lib/webrtc/src/media/rtpReceiver.d.ts +2 -2
  90. package/lib/webrtc/src/media/rtpReceiver.js +2 -5
  91. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  92. package/lib/webrtc/src/media/rtpSender.d.ts +1 -1
  93. package/lib/webrtc/src/media/rtpSender.js +5 -5
  94. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  95. package/lib/webrtc/src/media/rtpTransceiver.d.ts +1 -1
  96. package/lib/webrtc/src/media/rtpTransceiver.js +2 -5
  97. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  98. package/lib/webrtc/src/media/sender/senderBWE.d.ts +1 -1
  99. package/lib/webrtc/src/media/sender/senderBWE.js +4 -7
  100. package/lib/webrtc/src/media/sender/senderBWE.js.map +1 -1
  101. package/lib/webrtc/src/media/track.d.ts +1 -1
  102. package/lib/webrtc/src/media/track.js +4 -7
  103. package/lib/webrtc/src/media/track.js.map +1 -1
  104. package/lib/webrtc/src/nonstandard/recorder/index.d.ts +2 -1
  105. package/lib/webrtc/src/nonstandard/recorder/index.js +2 -5
  106. package/lib/webrtc/src/nonstandard/recorder/index.js.map +1 -1
  107. package/lib/webrtc/src/nonstandard/recorder/writer/index.d.ts +1 -1
  108. package/lib/webrtc/src/nonstandard/recorder/writer/index.js.map +1 -1
  109. package/lib/webrtc/src/nonstandard/recorder/writer/webm.d.ts +1 -1
  110. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js +2 -2
  111. package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
  112. package/lib/webrtc/src/peerConnection.d.ts +3 -2
  113. package/lib/webrtc/src/peerConnection.js +13 -11
  114. package/lib/webrtc/src/peerConnection.js.map +1 -1
  115. package/lib/webrtc/src/transport/dtls.d.ts +1 -1
  116. package/lib/webrtc/src/transport/dtls.js +12 -8
  117. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  118. package/lib/webrtc/src/transport/ice.d.ts +2 -2
  119. package/lib/webrtc/src/transport/ice.js +10 -7
  120. package/lib/webrtc/src/transport/ice.js.map +1 -1
  121. package/lib/webrtc/src/transport/sctp.d.ts +1 -1
  122. package/lib/webrtc/src/transport/sctp.js +2 -2
  123. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  124. package/package.json +1 -1
  125. package/src/dataChannel.ts +1 -1
  126. package/src/imports/common.ts +1 -0
  127. package/src/media/receiver/nack.ts +1 -1
  128. package/src/media/rtpReceiver.ts +1 -1
  129. package/src/media/rtpSender.ts +1 -1
  130. package/src/media/rtpTransceiver.ts +1 -1
  131. package/src/media/sender/senderBWE.ts +1 -1
  132. package/src/media/track.ts +1 -1
  133. package/src/nonstandard/recorder/index.ts +3 -1
  134. package/src/nonstandard/recorder/writer/index.ts +1 -1
  135. package/src/nonstandard/recorder/writer/webm.ts +1 -1
  136. package/src/peerConnection.ts +4 -1
  137. package/src/transport/dtls.ts +11 -5
  138. package/src/transport/ice.ts +9 -4
  139. package/src/transport/sctp.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../../../ice/src/turn/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"crypto\";\nimport { jspack } from \"@shinyoshiaki/jspack\";\nimport debug from \"debug\";\nimport PCancelable from \"p-cancelable\";\nimport Event from \"rx.mini\";\nimport { setTimeout } from \"timers/promises\";\n\nimport { int } from \"../../../common/src\";\nimport type { InterfaceAddresses } from \"../../../common/src/network\";\nimport type { Candidate } from \"../candidate\";\nimport { TransactionFailed } from \"../exceptions\";\nimport { type Future, future, randomTransactionId } from \"../helper\";\nimport type { Connection } from \"../ice\";\nimport { classes, methods } from \"../stun/const\";\nimport { Message, parseMessage } from \"../stun/message\";\nimport { Transaction } from \"../stun/transaction\";\nimport { type Transport, UdpTransport } from \"../transport\";\nimport type { Address, Protocol } from \"../types/model\";\n\nconst log = debug(\"werift-ice:packages/ice/src/turn/protocol.ts\");\n\nconst DEFAULT_CHANNEL_REFRESH_TIME = 500;\nconst DEFAULT_ALLOCATION_LIFETIME = 600;\nconst TCP_TRANSPORT = 0x06000000;\nconst UDP_TRANSPORT = 0x11000000;\n\nclass TurnTransport implements Protocol {\n readonly type = \"turn\";\n localCandidate!: Candidate;\n receiver?: Connection;\n\n constructor(public turn: TurnClient) {\n turn.onDatagramReceived = this.datagramReceived;\n }\n\n private datagramReceived = (data: Buffer, addr: Address) => {\n try {\n const message = parseMessage(data);\n if (!message) {\n this.receiver?.dataReceived(data, this.localCandidate.component);\n return;\n }\n\n if (\n (message?.messageClass === classes.RESPONSE ||\n message?.messageClass === classes.ERROR) &&\n this.turn.transactions[message.transactionIdHex]\n ) {\n const transaction = this.turn.transactions[message.transactionIdHex];\n transaction.responseReceived(message, addr);\n } else if (message?.messageClass === classes.REQUEST) {\n this.receiver?.requestReceived(message, addr, this, data);\n }\n } catch (error) {\n log(\"datagramReceived error\", error);\n }\n };\n\n async request(request: Message, addr: Address, integrityKey?: Buffer) {\n if (this.turn.transactions[request.transactionIdHex])\n throw new Error(\"exist\");\n\n if (integrityKey) {\n request.addMessageIntegrity(integrityKey);\n request.addFingerprint();\n }\n\n const transaction = new Transaction(request, addr, this);\n this.turn.transactions[request.transactionIdHex] = transaction;\n\n try {\n return await transaction.run();\n } catch (e) {\n throw e;\n } finally {\n delete this.turn.transactions[request.transactionIdHex];\n }\n }\n async connectionMade() {}\n async sendData(data: Buffer, addr: Address) {\n await this.turn.sendData(data, addr);\n }\n async sendStun(message: Message, addr: Address) {\n await this.turn.sendData(message.bytes, addr);\n }\n}\n\nclass TurnClient implements Protocol {\n type = \"inner_turn\";\n readonly onData = new Event<[Buffer, Address]>();\n transactions: { [hexId: string]: Transaction } = {};\n integrityKey?: Buffer;\n nonce?: Buffer;\n realm?: string;\n relayedAddress!: Address;\n mappedAddress!: Address;\n refreshHandle?: Future;\n channelNumber = 0x4000;\n channelByAddr: { [addr: string]: { number: number; address: Address } } = {};\n addrByChannel: { [channel: number]: Address } = {};\n localCandidate!: Candidate;\n /**sec */\n channelRefreshTime: number;\n\n onDatagramReceived: (data: Buffer, addr: Address) => void = () => {};\n\n private channelBinding?: Promise<void>;\n channelRefreshAt = 0;\n\n constructor(\n public server: Address,\n public username: string,\n public password: string,\n public lifetime: number,\n public transport: Transport,\n public options: {\n /**sec */\n channelRefreshTime?: number;\n } = {},\n ) {\n this.channelRefreshTime =\n this.options.channelRefreshTime ?? DEFAULT_CHANNEL_REFRESH_TIME;\n }\n\n async connectionMade() {\n this.transport.onData = (data, addr) => {\n this.datagramReceived(data, addr);\n };\n }\n\n private handleChannelData(data: Buffer) {\n const [channel, length] = jspack.Unpack(\"!HH\", data.slice(0, 4));\n const addr = this.addrByChannel[channel];\n\n if (addr) {\n const payload = data.subarray(4, 4 + length);\n this.onDatagramReceived(payload, addr);\n this.onData.execute(payload, addr);\n }\n }\n\n private handleSTUNMessage(data: Buffer, addr: Address) {\n try {\n const message = parseMessage(data);\n if (!message) throw new Error(\"not stun message\");\n if (\n message.messageClass === classes.RESPONSE ||\n message.messageClass === classes.ERROR\n ) {\n const transaction = this.transactions[message.transactionIdHex];\n if (transaction) {\n transaction.responseReceived(message, addr);\n }\n } else if (message.messageClass === classes.REQUEST) {\n this.onDatagramReceived(data, addr);\n }\n\n if (message.getAttributeValue(\"DATA\")) {\n const buf: Buffer = message.getAttributeValue(\"DATA\");\n this.onDatagramReceived(buf, addr);\n this.onData.execute(buf, addr);\n }\n } catch (error) {\n log(\"parse error\", data.toString());\n }\n }\n\n private datagramReceived(data: Buffer, addr: Address) {\n if (data.length >= 4 && isChannelData(data)) {\n this.handleChannelData(data);\n } else {\n this.handleSTUNMessage(data, addr);\n }\n }\n\n async connect() {\n const request = new Message(methods.ALLOCATE, classes.REQUEST);\n request\n .setAttribute(\"LIFETIME\", this.lifetime)\n .setAttribute(\"REQUESTED-TRANSPORT\", UDP_TRANSPORT);\n\n const [response] = await this.requestWithRetry(request, this.server).catch(\n (e) => {\n log(\"connect error\", e);\n throw e;\n },\n );\n this.relayedAddress = response.getAttributeValue(\"XOR-RELAYED-ADDRESS\");\n this.mappedAddress = response.getAttributeValue(\"XOR-MAPPED-ADDRESS\");\n const exp = response.getAttributeValue(\"LIFETIME\");\n log(\"connect\", this.relayedAddress, this.mappedAddress, { exp });\n\n this.refreshHandle = future(this.refresh(exp));\n }\n\n async createPermission(peerAddress: Address) {\n const request = new Message(methods.CREATE_PERMISSION, classes.REQUEST);\n request\n .setAttribute(\"XOR-PEER-ADDRESS\", peerAddress)\n .setAttribute(\"USERNAME\", this.username)\n .setAttribute(\"REALM\", this.realm)\n .setAttribute(\"NONCE\", this.nonce);\n const [response] = await this.request(request, this.server).catch((e) => {\n request;\n throw e;\n });\n return response;\n }\n\n refresh = (exp: number) =>\n new PCancelable(async (_, f, onCancel) => {\n let run = true;\n onCancel(() => {\n run = false;\n f(\"cancel\");\n });\n\n while (run) {\n // refresh before expire\n const delay = (5 / 6) * exp * 1000;\n log(\"refresh delay\", delay, { exp });\n await setTimeout(delay);\n\n const request = new Message(methods.REFRESH, classes.REQUEST);\n request.setAttribute(\"LIFETIME\", exp);\n\n try {\n const [message] = await this.requestWithRetry(request, this.server);\n exp = message.getAttributeValue(\"LIFETIME\");\n log(\"refresh\", { exp });\n } catch (error) {\n log(\"refresh error\", error);\n }\n }\n });\n\n async request(request: Message, addr: Address): Promise<[Message, Address]> {\n if (this.transactions[request.transactionIdHex]) {\n throw new Error(\"exist\");\n }\n if (this.integrityKey) {\n request\n .setAttribute(\"USERNAME\", this.username)\n .setAttribute(\"REALM\", this.realm)\n .setAttribute(\"NONCE\", this.nonce)\n .addMessageIntegrity(this.integrityKey)\n .addFingerprint();\n }\n\n const transaction = new Transaction(request, addr, this);\n this.transactions[request.transactionIdHex] = transaction;\n\n try {\n return await transaction.run();\n } catch (e) {\n throw e;\n } finally {\n delete this.transactions[request.transactionIdHex];\n }\n }\n\n async requestWithRetry(\n request: Message,\n addr: Address,\n ): Promise<[Message, Address]> {\n let message: Message, address: Address;\n try {\n [message, address] = await this.request(request, addr);\n } catch (error) {\n if (error instanceof TransactionFailed == false) {\n log(\"requestWithRetry error\", error);\n throw error;\n }\n\n // resolve dns address\n this.server = error.addr;\n\n const [errorCode] = error.response.getAttributeValue(\"ERROR-CODE\");\n const nonce = error.response.getAttributeValue(\"NONCE\");\n const realm = error.response.getAttributeValue(\"REALM\");\n\n if (\n ((errorCode === 401 && realm) || (errorCode === 438 && this.realm)) &&\n nonce\n ) {\n log(\"retry with nonce\", errorCode);\n\n this.nonce = nonce;\n if (errorCode === 401) {\n this.realm = realm;\n }\n this.integrityKey = makeIntegrityKey(\n this.username,\n this.realm!,\n this.password,\n );\n\n request.transactionId = randomTransactionId();\n [message, address] = await this.request(request, this.server);\n } else {\n throw error;\n }\n }\n return [message!, address!];\n }\n\n async sendData(data: Buffer, addr: Address) {\n const channel = await this.getChannel(addr);\n\n const header = jspack.Pack(\"!HH\", [channel.number, data.length]);\n this.transport.send(\n Buffer.concat([Buffer.from(header), data]),\n this.server,\n );\n }\n\n async getChannel(addr: Address) {\n if (this.channelBinding) {\n await this.channelBinding;\n }\n\n let channel = this.channelByAddr[addr.join(\"\")];\n\n if (!channel) {\n this.channelByAddr[addr.join(\"\")] = {\n number: this.channelNumber++,\n address: addr,\n };\n channel = this.channelByAddr[addr.join(\"\")];\n this.addrByChannel[channel.number] = addr;\n\n this.channelBinding = this.channelBind(channel.number, addr);\n await this.channelBinding.catch((e) => {\n log(\"channelBind error\", e);\n throw e;\n });\n this.channelRefreshAt = int(Date.now() / 1000) + this.channelRefreshTime;\n this.channelBinding = undefined;\n log(\"channelBind\", channel);\n } else if (this.channelRefreshAt < int(Date.now() / 1000)) {\n this.channelBinding = this.channelBind(channel.number, addr);\n this.channelRefreshAt = int(Date.now() / 1000) + this.channelRefreshTime;\n await this.channelBinding.catch((e) => {\n log(\"channelBind error\", e);\n throw e;\n });\n this.channelBinding = undefined;\n log(\"channelBind refresh\", channel);\n }\n return channel;\n }\n\n private async channelBind(channelNumber: number, addr: Address) {\n const request = new Message(methods.CHANNEL_BIND, classes.REQUEST);\n request\n .setAttribute(\"CHANNEL-NUMBER\", channelNumber)\n .setAttribute(\"XOR-PEER-ADDRESS\", addr);\n const [response] = await this.requestWithRetry(request, this.server);\n if (response.messageMethod !== methods.CHANNEL_BIND) {\n throw new Error(\"should be CHANNEL_BIND\");\n }\n }\n\n async sendStun(message: Message, addr: Address) {\n await this.transport.send(message.bytes, addr);\n }\n}\n\nexport async function createTurnEndpoint(\n serverAddr: Address,\n username: string,\n password: string,\n {\n lifetime,\n portRange,\n interfaceAddresses,\n }: {\n lifetime?: number;\n ssl?: boolean;\n transport?: \"udp\";\n portRange?: [number, number];\n interfaceAddresses?: InterfaceAddresses;\n },\n) {\n if (lifetime == undefined) {\n lifetime = DEFAULT_ALLOCATION_LIFETIME;\n }\n\n const transport = await UdpTransport.init(\n \"udp4\",\n portRange,\n interfaceAddresses,\n );\n\n const turnClient = new TurnClient(\n serverAddr,\n username,\n password,\n lifetime,\n transport,\n );\n\n await turnClient.connectionMade();\n await turnClient.connect();\n const turnTransport = new TurnTransport(turnClient);\n\n return turnTransport;\n}\n\nexport function makeIntegrityKey(\n username: string,\n realm: string,\n password: string,\n) {\n return createHash(\"md5\")\n .update(Buffer.from([username, realm, password].join(\":\")))\n .digest();\n}\n\nfunction isChannelData(data: Buffer) {\n return (data[0] & 0xc0) == 0x40;\n}\n"]}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../../../ice/src/turn/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"crypto\";\nimport { jspack } from \"@shinyoshiaki/jspack\";\nimport debug from \"debug\";\nimport PCancelable from \"p-cancelable\";\nimport { setTimeout } from \"timers/promises\";\nimport { Event, EventDisposer } from \"../imports/common\";\n\nimport { bufferReader, int } from \"../../../common/src\";\nimport type { InterfaceAddresses } from \"../../../common/src/network\";\nimport type { Candidate } from \"../candidate\";\nimport { TransactionFailed } from \"../exceptions\";\nimport { type Future, future, randomTransactionId } from \"../helper\";\nimport type { Connection } from \"../ice\";\nimport { classes, methods } from \"../stun/const\";\nimport { Message, paddingLength, parseMessage } from \"../stun/message\";\nimport { Transaction } from \"../stun/transaction\";\nimport { TcpTransport, type Transport, UdpTransport } from \"../transport\";\nimport type { Address, Protocol } from \"../types/model\";\n\nconst log = debug(\"werift-ice:packages/ice/src/turn/protocol.ts\");\n\nconst DEFAULT_CHANNEL_REFRESH_TIME = 500;\nconst DEFAULT_ALLOCATION_LIFETIME = 600;\nconst UDP_TRANSPORT = 0x11000000;\n\nexport class StunOverTurnProtocol implements Protocol {\n static type = \"turn\";\n readonly type = StunOverTurnProtocol.type;\n localCandidate!: Candidate;\n private disposer = new EventDisposer();\n\n constructor(\n public turn: TurnProtocol,\n private ice: Connection,\n ) {\n turn.onData\n .subscribe((data, addr) => {\n this.handleStunMessage(data, addr);\n })\n .disposer(this.disposer);\n }\n\n private handleStunMessage = (data: Buffer, addr: Address) => {\n try {\n const message = parseMessage(data);\n if (!message) {\n this.ice.dataReceived(data, this.localCandidate.component);\n return;\n }\n\n if (\n message.messageClass === classes.RESPONSE ||\n message.messageClass === classes.ERROR\n ) {\n const transaction = this.turn.transactions[message.transactionIdHex];\n if (transaction) {\n transaction.responseReceived(message, addr);\n }\n } else if (message.messageClass === classes.REQUEST) {\n this.ice.requestReceived(message, addr, this, data);\n }\n } catch (error) {\n log(\"datagramReceived error\", error);\n }\n };\n\n async request(request: Message, addr: Address, integrityKey?: Buffer) {\n if (this.turn.transactions[request.transactionIdHex]) {\n throw new Error(\"exist\");\n }\n\n if (integrityKey) {\n request.addMessageIntegrity(integrityKey);\n request.addFingerprint();\n }\n\n const transaction = new Transaction(request, addr, this);\n this.turn.transactions[request.transactionIdHex] = transaction;\n\n try {\n return await transaction.run();\n } catch (e) {\n throw e;\n } finally {\n delete this.turn.transactions[request.transactionIdHex];\n }\n }\n async connectionMade() {}\n async sendData(data: Buffer, addr: Address) {\n await this.turn.sendData(data, addr);\n }\n async sendStun(message: Message, addr: Address) {\n await this.turn.sendData(message.bytes, addr);\n }\n async close() {\n this.disposer.dispose();\n return this.turn.close();\n }\n}\n\nexport class TurnProtocol implements Protocol {\n static type = \"turn\";\n readonly type = TurnProtocol.type;\n readonly onData = new Event<[Buffer, Address]>();\n integrityKey?: Buffer;\n nonce?: Buffer;\n realm?: string;\n relayedAddress!: Address;\n mappedAddress!: Address;\n localCandidate!: Candidate;\n transactions: { [hexId: string]: Transaction } = {};\n private refreshHandle?: Future;\n private channelNumber = 0x4000;\n private channelByAddr: {\n [addr: string]: { number: number; address: Address };\n } = {};\n private addrByChannel: { [channel: number]: Address } = {};\n /**sec */\n private channelRefreshTime: number;\n private channelBinding?: Promise<void>;\n private channelRefreshAt = 0;\n private tcpBuffer: Buffer = Buffer.alloc(0);\n private permissionByAddr: { [addr: string]: boolean } = {};\n private creatingPermission: Promise<void> = Promise.resolve();\n\n constructor(\n public server: Address,\n public username: string,\n public password: string,\n public lifetime: number,\n public transport: Transport,\n public options: {\n /**sec */\n channelRefreshTime?: number;\n } = {},\n ) {\n this.channelRefreshTime =\n this.options.channelRefreshTime ?? DEFAULT_CHANNEL_REFRESH_TIME;\n }\n\n async connectionMade() {\n this.transport.onData = (data, addr) => {\n this.dataReceived(data, addr);\n };\n\n const request = new Message(methods.ALLOCATE, classes.REQUEST);\n request\n .setAttribute(\"LIFETIME\", this.lifetime)\n .setAttribute(\"REQUESTED-TRANSPORT\", UDP_TRANSPORT);\n\n const [response] = await this.requestWithRetry(request, this.server).catch(\n (e) => {\n log(\"connect error\", e);\n throw e;\n },\n );\n this.relayedAddress = response.getAttributeValue(\"XOR-RELAYED-ADDRESS\");\n this.mappedAddress = response.getAttributeValue(\"XOR-MAPPED-ADDRESS\");\n const exp = response.getAttributeValue(\"LIFETIME\");\n log(\"connect\", this.relayedAddress, this.mappedAddress, { exp });\n\n this.refreshHandle = future(this.refresh(exp));\n }\n\n private handleChannelData(data: Buffer) {\n const [channel, length] = jspack.Unpack(\"!HH\", data.slice(0, 4));\n const addr = this.addrByChannel[channel];\n\n if (addr) {\n const payload = data.subarray(4, 4 + length);\n this.onData.execute(payload, addr);\n }\n }\n\n private handleSTUNMessage(data: Buffer, addr: Address) {\n try {\n const message = parseMessage(data);\n if (!message) {\n throw new Error(\"not stun message\");\n }\n\n if (\n message.messageClass === classes.RESPONSE ||\n message.messageClass === classes.ERROR\n ) {\n const transaction = this.transactions[message.transactionIdHex];\n if (transaction) {\n transaction.responseReceived(message, addr);\n }\n } else if (message.messageClass === classes.REQUEST) {\n this.onData.execute(data, addr);\n }\n\n if (message.getAttributeValue(\"DATA\")) {\n const buf: Buffer = message.getAttributeValue(\"DATA\");\n this.onData.execute(buf, addr);\n }\n } catch (error) {\n log(\"parse error\", data.toString());\n }\n }\n\n private dataReceived(data: Buffer, addr: Address) {\n const datagramReceived = (data: Buffer, addr: Address) => {\n if (data.length >= 4 && isChannelData(data)) {\n this.handleChannelData(data);\n } else {\n this.handleSTUNMessage(data, addr);\n }\n };\n\n if (this.transport.type === \"tcp\") {\n this.tcpBuffer = Buffer.concat([this.tcpBuffer, data]);\n while (this.tcpBuffer.length >= 4) {\n let [, length] = bufferReader(this.tcpBuffer.subarray(0, 4), [2, 2]);\n length += paddingLength(length);\n const fullLength = isChannelData(this.tcpBuffer)\n ? 4 + length\n : 20 + length;\n if (this.tcpBuffer.length < fullLength) {\n break;\n }\n\n datagramReceived(this.tcpBuffer.subarray(0, fullLength), addr);\n this.tcpBuffer = this.tcpBuffer.subarray(fullLength);\n }\n } else {\n datagramReceived(data, addr);\n }\n }\n\n private async send(data: Buffer, addr: Address) {\n if (this.transport.type === \"tcp\") {\n const padding = paddingLength(data.length);\n await this.transport.send(\n padding > 0 ? Buffer.concat([data, Buffer.alloc(padding)]) : data,\n addr,\n );\n } else {\n await this.transport.send(data, addr);\n }\n }\n\n private async createPermission(peerAddress: Address) {\n const request = new Message(methods.CREATE_PERMISSION, classes.REQUEST);\n request\n .setAttribute(\"XOR-PEER-ADDRESS\", peerAddress)\n .setAttribute(\"USERNAME\", this.username)\n .setAttribute(\"REALM\", this.realm)\n .setAttribute(\"NONCE\", this.nonce);\n await this.request(request, this.server).catch((e) => {\n request;\n throw e;\n });\n }\n\n private refresh = (exp: number) =>\n new PCancelable(async (_, f, onCancel) => {\n let run = true;\n onCancel(() => {\n run = false;\n f(\"cancel\");\n });\n\n while (run) {\n // refresh before expire\n const delay = (5 / 6) * exp * 1000;\n log(\"refresh delay\", delay, { exp });\n await setTimeout(delay);\n\n const request = new Message(methods.REFRESH, classes.REQUEST);\n request.setAttribute(\"LIFETIME\", exp);\n\n try {\n const [message] = await this.requestWithRetry(request, this.server);\n exp = message.getAttributeValue(\"LIFETIME\");\n log(\"refresh\", { exp });\n } catch (error) {\n log(\"refresh error\", error);\n }\n }\n });\n\n async request(request: Message, addr: Address): Promise<[Message, Address]> {\n if (this.transactions[request.transactionIdHex]) {\n throw new Error(\"exist\");\n }\n if (this.integrityKey) {\n request\n .setAttribute(\"USERNAME\", this.username)\n .setAttribute(\"REALM\", this.realm)\n .setAttribute(\"NONCE\", this.nonce)\n .addMessageIntegrity(this.integrityKey)\n .addFingerprint();\n }\n\n const transaction = new Transaction(request, addr, this);\n this.transactions[request.transactionIdHex] = transaction;\n\n try {\n return await transaction.run();\n } catch (e) {\n throw e;\n } finally {\n delete this.transactions[request.transactionIdHex];\n }\n }\n\n async requestWithRetry(\n request: Message,\n addr: Address,\n ): Promise<[Message, Address]> {\n let message: Message, address: Address;\n try {\n [message, address] = await this.request(request, addr);\n } catch (error) {\n if (error instanceof TransactionFailed == false) {\n log(\"requestWithRetry error\", error);\n throw error;\n }\n\n // resolve dns address\n this.server = error.addr;\n\n const [errorCode] = error.response.getAttributeValue(\"ERROR-CODE\");\n const nonce = error.response.getAttributeValue(\"NONCE\");\n const realm = error.response.getAttributeValue(\"REALM\");\n\n if (\n ((errorCode === 401 && realm) || (errorCode === 438 && this.realm)) &&\n nonce\n ) {\n log(\"retry with nonce\", errorCode);\n\n this.nonce = nonce;\n if (errorCode === 401) {\n this.realm = realm;\n }\n this.integrityKey = makeIntegrityKey(\n this.username,\n this.realm!,\n this.password,\n );\n\n request.transactionId = randomTransactionId();\n [message, address] = await this.request(request, this.server);\n } else {\n throw error;\n }\n }\n return [message!, address!];\n }\n\n async sendData(data: Buffer, addr: Address) {\n const channel = await this.getChannel(addr).catch((e) => {\n return new Error(\"channelBind error\");\n });\n\n if (channel instanceof Error) {\n await this.getPermission(addr);\n const indicate = new Message(methods.SEND, classes.INDICATION)\n .setAttribute(\"DATA\", data)\n .setAttribute(\"XOR-PEER-ADDRESS\", addr);\n\n await this.sendStun(indicate, this.server);\n return;\n }\n\n const header = jspack.Pack(\"!HH\", [channel.number, data.length]);\n await this.send(Buffer.concat([Buffer.from(header), data]), this.server);\n }\n\n async getPermission(addr: Address) {\n await this.creatingPermission;\n\n const permitted = this.permissionByAddr[addr.join(\":\")];\n if (!permitted) {\n this.creatingPermission = this.createPermission(addr);\n this.permissionByAddr[addr.join(\":\")] = true;\n await this.creatingPermission.catch((e) => {\n log(\"createPermission error\", e);\n throw e;\n });\n }\n }\n\n async getChannel(addr: Address) {\n if (this.channelBinding) {\n await this.channelBinding;\n }\n\n let channel = this.channelByAddr[addr.join(\":\")];\n\n if (!channel) {\n this.channelByAddr[addr.join(\":\")] = {\n number: this.channelNumber++,\n address: addr,\n };\n channel = this.channelByAddr[addr.join(\":\")];\n this.addrByChannel[channel.number] = addr;\n\n this.channelBinding = this.channelBind(channel.number, addr);\n await this.channelBinding.catch((e) => {\n log(\"channelBind error\", e);\n throw e;\n });\n this.channelRefreshAt = int(Date.now() / 1000) + this.channelRefreshTime;\n this.channelBinding = undefined;\n log(\"channelBind\", channel);\n } else if (this.channelRefreshAt < int(Date.now() / 1000)) {\n this.channelBinding = this.channelBind(channel.number, addr);\n this.channelRefreshAt = int(Date.now() / 1000) + this.channelRefreshTime;\n await this.channelBinding.catch((e) => {\n log(\"channelBind error\", e);\n throw e;\n });\n this.channelBinding = undefined;\n log(\"channelBind refresh\", channel);\n }\n return channel;\n }\n\n private async channelBind(channelNumber: number, addr: Address) {\n const request = new Message(methods.CHANNEL_BIND, classes.REQUEST);\n request\n .setAttribute(\"CHANNEL-NUMBER\", channelNumber)\n .setAttribute(\"XOR-PEER-ADDRESS\", addr);\n const [response] = await this.requestWithRetry(request, this.server);\n if (response.messageMethod !== methods.CHANNEL_BIND) {\n throw new Error(\"should be CHANNEL_BIND\");\n }\n }\n\n async sendStun(message: Message, addr: Address) {\n await this.send(message.bytes, addr);\n }\n\n async close() {\n this.refreshHandle?.cancel();\n await this.transport.close();\n }\n}\n\nexport interface TurnClientConfig {\n address: Address;\n username: string;\n password: string;\n}\nexport interface TurnClientOptions {\n lifetime?: number;\n ssl?: boolean;\n transport?: \"udp\" | \"tcp\";\n portRange?: [number, number];\n interfaceAddresses?: InterfaceAddresses;\n}\n\nexport async function createTurnClient(\n { address, username, password }: TurnClientConfig,\n {\n lifetime,\n portRange,\n interfaceAddresses,\n transport: transportType,\n }: TurnClientOptions = {},\n) {\n lifetime ??= DEFAULT_ALLOCATION_LIFETIME;\n transportType ??= \"udp\";\n\n const transport =\n transportType === \"udp\"\n ? await UdpTransport.init(\"udp4\", portRange, interfaceAddresses)\n : await TcpTransport.init(address);\n\n const turn = new TurnProtocol(\n address,\n username,\n password,\n lifetime,\n transport,\n );\n\n await turn.connectionMade();\n return turn;\n}\n\nexport async function createStunOverTurnClient(\n {\n address,\n username,\n password,\n ice,\n }: {\n address: Address;\n username: string;\n password: string;\n ice: Connection;\n },\n {\n lifetime,\n portRange,\n interfaceAddresses,\n transport: transportType,\n }: {\n lifetime?: number;\n ssl?: boolean;\n transport?: \"udp\" | \"tcp\";\n portRange?: [number, number];\n interfaceAddresses?: InterfaceAddresses;\n } = {},\n) {\n const turn = await createTurnClient(\n {\n address,\n username,\n password,\n },\n {\n lifetime,\n portRange,\n interfaceAddresses,\n transport: transportType,\n },\n );\n const turnTransport = new StunOverTurnProtocol(turn, ice);\n return turnTransport;\n}\n\nexport function makeIntegrityKey(\n username: string,\n realm: string,\n password: string,\n) {\n return createHash(\"md5\")\n .update(Buffer.from([username, realm, password].join(\":\")))\n .digest();\n}\n\nfunction isChannelData(data: Buffer) {\n return (data[0] & 0xc0) == 0x40;\n}\n"]}
@@ -3,13 +3,13 @@ import type { Message } from "../stun/message";
3
3
  export type Address = Readonly<[string, number]>;
4
4
  export interface Protocol {
5
5
  type: string;
6
- localCandidate?: Candidate;
7
- sentMessage?: Message;
8
6
  request: (message: Message, addr: Address, integrityKey?: Buffer, retransmissions?: any) => Promise<[Message, Address]>;
9
- responseAddr?: Address;
10
- responseMessage?: string;
11
- close?: () => Promise<void>;
7
+ close: () => Promise<void>;
12
8
  connectionMade: (...args: any) => Promise<void>;
13
9
  sendStun: (message: Message, addr: Address) => Promise<void>;
14
10
  sendData: (data: Buffer, addr: Address) => Promise<void>;
11
+ localCandidate?: Candidate;
12
+ sentMessage?: Message;
13
+ responseAddr?: Address;
14
+ responseMessage?: string;
15
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../../ice/src/types/model.ts"],"names":[],"mappings":"","sourcesContent":["import type { Candidate } from \"../candidate\";\nimport type { Message } from \"../stun/message\";\n\nexport type Address = Readonly<[string, number]>;\n\nexport interface Protocol {\n type: string;\n localCandidate?: Candidate;\n sentMessage?: Message;\n request: (\n message: Message,\n addr: Address,\n integrityKey?: Buffer,\n retransmissions?: any,\n ) => Promise<[Message, Address]>;\n responseAddr?: Address;\n responseMessage?: string;\n close?: () => Promise<void>;\n connectionMade: (...args: any) => Promise<void>;\n sendStun: (message: Message, addr: Address) => Promise<void>;\n sendData: (data: Buffer, addr: Address) => Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../../ice/src/types/model.ts"],"names":[],"mappings":"","sourcesContent":["import type { Candidate } from \"../candidate\";\nimport type { Message } from \"../stun/message\";\n\nexport type Address = Readonly<[string, number]>;\n\nexport interface Protocol {\n type: string;\n request: (\n message: Message,\n addr: Address,\n integrityKey?: Buffer,\n retransmissions?: any,\n ) => Promise<[Message, Address]>;\n close: () => Promise<void>;\n connectionMade: (...args: any) => Promise<void>;\n sendStun: (message: Message, addr: Address) => Promise<void>;\n sendData: (data: Buffer, addr: Address) => Promise<void>;\n localCandidate?: Candidate;\n sentMessage?: Message;\n responseAddr?: Address;\n responseMessage?: string;\n}\n"]}
@@ -3,3 +3,4 @@ import type { Address } from "./types/model";
3
3
  export declare function getGlobalIp(stunServer?: Address, interfaceAddresses?: InterfaceAddresses): Promise<string>;
4
4
  export declare function normalizeFamilyNodeV18(family: string | number): 4 | 6;
5
5
  export declare function getHostAddresses(useIpv4: boolean, useIpv6: boolean): string[];
6
+ export declare const url2Address: (url?: string) => readonly [string, number] | undefined;
@@ -26,31 +26,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.url2Address = void 0;
29
30
  exports.getGlobalIp = getGlobalIp;
30
31
  exports.normalizeFamilyNodeV18 = normalizeFamilyNodeV18;
31
32
  exports.getHostAddresses = getHostAddresses;
32
33
  const os_1 = __importDefault(require("os"));
33
34
  const nodeIp = __importStar(require("ip"));
34
- const ice_1 = require("./ice");
35
+ const const_1 = require("./stun/const");
36
+ const message_1 = require("./stun/message");
35
37
  const protocol_1 = require("./stun/protocol");
36
38
  async function getGlobalIp(stunServer, interfaceAddresses) {
37
- const connection = new ice_1.Connection(true, {
38
- stunServer: stunServer ?? ["stun.l.google.com", 19302],
39
- });
40
- await connection.gatherCandidates();
41
- const protocol = new protocol_1.StunProtocol(connection);
42
- protocol.localCandidate = connection.localCandidates[0];
39
+ const protocol = new protocol_1.StunProtocol();
43
40
  await protocol.connectionMade(true, undefined, interfaceAddresses);
44
- const candidate = await (0, ice_1.serverReflexiveCandidate)(protocol, [
45
- "stun.l.google.com",
46
- 19302,
47
- ]);
48
- await connection.close();
41
+ const request = new message_1.Message(const_1.methods.BINDING, const_1.classes.REQUEST);
42
+ const [response] = await protocol.request(request, stunServer ?? ["stun.l.google.com", 19302]);
49
43
  await protocol.close();
50
- if (!candidate?.host) {
51
- throw new Error("host not exist");
52
- }
53
- return candidate?.host;
44
+ const address = response.getAttributeValue("XOR-MAPPED-ADDRESS");
45
+ return address[0];
54
46
  }
55
47
  function normalizeFamilyNodeV18(family) {
56
48
  if (family === "IPv4")
@@ -101,4 +93,11 @@ function getHostAddresses(useIpv4, useIpv6) {
101
93
  address.push(...nodeIpAddress(6));
102
94
  return address;
103
95
  }
96
+ const url2Address = (url) => {
97
+ if (!url)
98
+ return;
99
+ const [address, port] = url.split(":");
100
+ return [address, Number.parseInt(port)];
101
+ };
102
+ exports.url2Address = url2Address;
104
103
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../ice/src/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,kCAyBC;AAED,wDAKC;AA8CD,4CAKC;AA1FD,4CAAoB;AACpB,2CAA6B;AAE7B,+BAA6D;AAC7D,8CAA+C;AAGxC,KAAK,UAAU,WAAW,CAC/B,UAAoB,EACpB,kBAAuC;IAEvC,MAAM,UAAU,GAAG,IAAI,gBAAU,CAAC,IAAI,EAAE;QACtC,UAAU,EAAE,UAAU,IAAI,CAAC,mBAAmB,EAAE,KAAK,CAAC;KACvD,CAAC,CAAC;IACH,MAAM,UAAU,CAAC,gBAAgB,EAAE,CAAC;IAEpC,MAAM,QAAQ,GAAG,IAAI,uBAAY,CAAC,UAAU,CAAC,CAAC;IAC9C,QAAQ,CAAC,cAAc,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,MAAM,IAAA,8BAAwB,EAAC,QAAQ,EAAE;QACzD,mBAAmB;QACnB,KAAK;KACN,CAAC,CAAC;IAEH,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;IACzB,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;IAEvB,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,SAAS,EAAE,IAAI,CAAC;AACzB,CAAC;AAED,SAAgB,sBAAsB,CAAC,MAAuB;IAC5D,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC;IAChC,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC;IAEhC,OAAO,MAAe,CAAC;AACzB,CAAC;AAED,SAAS,0BAA0B,CAAC,IAA6B;IAC/D,OAAO,CACL,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QACzC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,CACrC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAc;IACnC,qFAAqF;IACrF,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEtC,MAAM,UAAU,GAAG,YAAE,CAAC,iBAAiB,EAAE,CAAC;IAE1C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;SAChC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,cAAc,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC;YACvD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,OAAO;oBACL,GAAG;oBACH,SAAS,EAAE,EAAE;iBACd,CAAC;YACJ,CAAC;QACH,CAAC;QACD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAE,CAAC,MAAM,CACvC,CAAC,OAAO,EAAE,EAAE,CACV,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,MAAM;YACjD,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC;YACnC,CAAC,0BAA0B,CAAC,OAAO,CAAC,CACvC,CAAC;QACF,OAAO;YACL,GAAG;YACH,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;SACvD,CAAC;IACJ,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAElC,0EAA0E;IAC1E,qEAAqE;IACrE,cAAc;IACd,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAChE,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAgB,EAAE,OAAgB;IACjE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import os from \"os\";\nimport * as nodeIp from \"ip\";\nimport type { InterfaceAddresses } from \"../../common/src/network\";\nimport { Connection, serverReflexiveCandidate } from \"./ice\";\nimport { StunProtocol } from \"./stun/protocol\";\nimport type { Address } from \"./types/model\";\n\nexport async function getGlobalIp(\n stunServer?: Address,\n interfaceAddresses?: InterfaceAddresses,\n) {\n const connection = new Connection(true, {\n stunServer: stunServer ?? [\"stun.l.google.com\", 19302],\n });\n await connection.gatherCandidates();\n\n const protocol = new StunProtocol(connection);\n protocol.localCandidate = connection.localCandidates[0];\n await protocol.connectionMade(true, undefined, interfaceAddresses);\n const candidate = await serverReflexiveCandidate(protocol, [\n \"stun.l.google.com\",\n 19302,\n ]);\n\n await connection.close();\n await protocol.close();\n\n if (!candidate?.host) {\n throw new Error(\"host not exist\");\n }\n\n return candidate?.host;\n}\n\nexport function normalizeFamilyNodeV18(family: string | number): 4 | 6 {\n if (family === \"IPv4\") return 4;\n if (family === \"IPv6\") return 6;\n\n return family as 4 | 6;\n}\n\nfunction isAutoconfigurationAddress(info: os.NetworkInterfaceInfo) {\n return (\n normalizeFamilyNodeV18(info.family) === 4 &&\n info.address?.startsWith(\"169.254.\")\n );\n}\n\nfunction nodeIpAddress(family: number): string[] {\n // https://chromium.googlesource.com/external/webrtc/+/master/rtc_base/network.cc#236\n const costlyNetworks = [\"ipsec\", \"tun\", \"utun\", \"tap\"];\n const banNetworks = [\"vmnet\", \"veth\"];\n\n const interfaces = os.networkInterfaces();\n\n const all = Object.keys(interfaces)\n .map((nic) => {\n for (const word of [...costlyNetworks, ...banNetworks]) {\n if (nic.startsWith(word)) {\n return {\n nic,\n addresses: [],\n };\n }\n }\n const addresses = interfaces[nic]!.filter(\n (details) =>\n normalizeFamilyNodeV18(details.family) === family &&\n !nodeIp.isLoopback(details.address) &&\n !isAutoconfigurationAddress(details),\n );\n return {\n nic,\n addresses: addresses.map((address) => address.address),\n };\n })\n .filter((address) => !!address);\n\n // os.networkInterfaces doesn't actually return addresses in a good order.\n // have seen instances where en0 (ethernet) is after en1 (wlan), etc.\n // eth0 > eth1\n all.sort((a, b) => a.nic.localeCompare(b.nic));\n return Object.values(all).flatMap((entry) => entry.addresses);\n}\n\nexport function getHostAddresses(useIpv4: boolean, useIpv6: boolean) {\n const address: string[] = [];\n if (useIpv4) address.push(...nodeIpAddress(4));\n if (useIpv6) address.push(...nodeIpAddress(6));\n return address;\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../ice/src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import os from \"os\";\nimport * as nodeIp from \"ip\";\nimport type { InterfaceAddresses } from \"../../common/src/network\";\nimport { classes, methods } from \"./stun/const\";\nimport { Message } from \"./stun/message\";\nimport { StunProtocol } from \"./stun/protocol\";\nimport type { Address } from \"./types/model\";\n\nexport async function getGlobalIp(\n stunServer?: Address,\n interfaceAddresses?: InterfaceAddresses,\n) {\n const protocol = new StunProtocol();\n await protocol.connectionMade(true, undefined, interfaceAddresses);\n const request = new Message(methods.BINDING, classes.REQUEST);\n const [response] = await protocol.request(\n request,\n stunServer ?? [\"stun.l.google.com\", 19302],\n );\n await protocol.close();\n\n const address = response.getAttributeValue(\"XOR-MAPPED-ADDRESS\");\n return address[0] as string;\n}\n\nexport function normalizeFamilyNodeV18(family: string | number): 4 | 6 {\n if (family === \"IPv4\") return 4;\n if (family === \"IPv6\") return 6;\n\n return family as 4 | 6;\n}\n\nfunction isAutoconfigurationAddress(info: os.NetworkInterfaceInfo) {\n return (\n normalizeFamilyNodeV18(info.family) === 4 &&\n info.address?.startsWith(\"169.254.\")\n );\n}\n\nfunction nodeIpAddress(family: number): string[] {\n // https://chromium.googlesource.com/external/webrtc/+/master/rtc_base/network.cc#236\n const costlyNetworks = [\"ipsec\", \"tun\", \"utun\", \"tap\"];\n const banNetworks = [\"vmnet\", \"veth\"];\n\n const interfaces = os.networkInterfaces();\n\n const all = Object.keys(interfaces)\n .map((nic) => {\n for (const word of [...costlyNetworks, ...banNetworks]) {\n if (nic.startsWith(word)) {\n return {\n nic,\n addresses: [],\n };\n }\n }\n const addresses = interfaces[nic]!.filter(\n (details) =>\n normalizeFamilyNodeV18(details.family) === family &&\n !nodeIp.isLoopback(details.address) &&\n !isAutoconfigurationAddress(details),\n );\n return {\n nic,\n addresses: addresses.map((address) => address.address),\n };\n })\n .filter((address) => !!address);\n\n // os.networkInterfaces doesn't actually return addresses in a good order.\n // have seen instances where en0 (ethernet) is after en1 (wlan), etc.\n // eth0 > eth1\n all.sort((a, b) => a.nic.localeCompare(b.nic));\n return Object.values(all).flatMap((entry) => entry.addresses);\n}\n\nexport function getHostAddresses(useIpv4: boolean, useIpv6: boolean) {\n const address: string[] = [];\n if (useIpv4) address.push(...nodeIpAddress(4));\n if (useIpv6) address.push(...nodeIpAddress(6));\n return address;\n}\n\nexport const url2Address = (url?: string) => {\n if (!url) return;\n const [address, port] = url.split(\":\");\n return [address, Number.parseInt(port)] as Address;\n};\n"]}
@@ -1,4 +1,4 @@
1
- import Event from "rx.mini";
1
+ import { Event } from "../../../imports/common";
2
2
  type DecoderConfig = AudioDecoderConfig | VideoDecoderConfig;
3
3
  type EncodedChunk = EncodedAudioChunk | EncodedVideoChunk;
4
4
  export type DataType = "init" | "delta" | "key";
@@ -33,13 +33,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
33
33
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
34
34
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
35
35
  };
36
- var __importDefault = (this && this.__importDefault) || function (mod) {
37
- return (mod && mod.__esModule) ? mod : { "default": mod };
38
- };
39
36
  var _Mp4Container_instances, _Mp4Container_mp4, _Mp4Container_audioFrame, _Mp4Container_videoFrame, _Mp4Container_audioSegment, _Mp4Container_videoSegment, _Mp4Container_init, _Mp4Container_enqueue;
40
37
  Object.defineProperty(exports, "__esModule", { value: true });
41
38
  exports.mp4SupportedCodecs = exports.Mp4Container = void 0;
42
- const rx_mini_1 = __importDefault(require("rx.mini"));
39
+ const common_1 = require("../../../imports/common");
43
40
  const MP4 = __importStar(require("./mp4box"));
44
41
  class Mp4Container {
45
42
  constructor(props) {
@@ -71,7 +68,7 @@ class Mp4Container {
71
68
  enumerable: true,
72
69
  configurable: true,
73
70
  writable: true,
74
- value: new rx_mini_1.default()
71
+ value: new common_1.Event()
75
72
  });
76
73
  Object.defineProperty(this, "frameBuffer", {
77
74
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../../../../../../rtp/src/extra/container/mp4/container.ts"],"names":[],"mappings":"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","sourcesContent":["import Event from \"rx.mini\";\n\nimport * as MP4 from \"./mp4box\";\n\ntype DecoderConfig = AudioDecoderConfig | VideoDecoderConfig;\ntype EncodedChunk = EncodedAudioChunk | EncodedVideoChunk;\n\nexport type DataType = \"init\" | \"delta\" | \"key\";\n\nexport interface Mp4Data {\n type: DataType;\n timestamp: number;\n duration: number;\n data: Uint8Array;\n kind: \"audio\" | \"video\";\n}\n\nexport class Mp4Container {\n #mp4: MP4.ISOFile;\n #audioFrame?: EncodedAudioChunk | EncodedVideoChunk;\n #videoFrame?: EncodedAudioChunk | EncodedVideoChunk; // 1 frame buffer\n audioTrack?: number;\n videoTrack?: number;\n #audioSegment = 0;\n #videoSegment = 0;\n onData = new Event<[Mp4Data]>();\n\n constructor(\n private props: {\n track: { audio: boolean; video: boolean };\n },\n ) {\n this.#mp4 = new MP4.ISOFile();\n this.#mp4.init();\n }\n\n get tracksReady() {\n let ready = true;\n if (this.props.track.audio && !this.audioTrack) {\n ready = false;\n }\n if (this.props.track.video && !this.videoTrack) {\n ready = false;\n }\n return ready;\n }\n\n write(\n frame: (DecoderConfig | EncodedChunk) & {\n track: \"video\" | \"audio\";\n },\n ) {\n if (isDecoderConfig(frame)) {\n return this.#init(frame);\n } else {\n return this.#enqueue(frame);\n }\n }\n\n #init(\n frame: DecoderConfig & {\n track: \"video\" | \"audio\";\n },\n ) {\n let codec = frame.codec.substring(0, 4);\n if (codec == \"opus\") {\n codec = \"Opus\";\n }\n\n const options: MP4.TrackOptions = {\n type: codec,\n timescale: 1_000_000,\n };\n\n if (isVideoConfig(frame)) {\n options.width = frame.codedWidth;\n options.height = frame.codedHeight;\n } else {\n options.channel_count = frame.numberOfChannels;\n options.samplerate = frame.sampleRate;\n options.hdlr = \"soun\";\n }\n\n if (!frame.description) throw new Error(\"missing frame description\");\n const desc = frame.description as ArrayBufferLike;\n\n if (codec === \"avc1\") {\n options.avcDecoderConfigRecord = desc;\n } else if (codec === \"hev1\") {\n options.hevcDecoderConfigRecord = desc;\n } else if (codec === \"Opus\") {\n // description is an identification header: https://datatracker.ietf.org/doc/html/rfc7845#section-5.1\n // The first 8 bytes are the magic string \"OpusHead\", followed by what we actually want.\n const dops = new MP4.BoxParser.dOpsBox();\n\n // Annoyingly, the header is little endian while MP4 is big endian, so we have to parse.\n dops.parse(new MP4.Stream(desc, 8, MP4.Stream.LITTLE_ENDIAN));\n\n options.description = dops;\n } else {\n throw new Error(`unsupported codec: ${codec}`);\n }\n\n const track = this.#mp4.addTrack(options);\n if (track == undefined) {\n throw new Error(\"failed to initialize MP4 track\");\n }\n if (frame.track === \"audio\") {\n this.audioTrack = track;\n } else {\n this.videoTrack = track;\n }\n\n if (!this.tracksReady) {\n return;\n }\n\n const buffer = MP4.ISOFile.writeInitializationSegment(\n this.#mp4.ftyp!,\n this.#mp4.moov!,\n 0,\n 0,\n );\n const data = new Uint8Array(buffer);\n const res = {\n type: \"init\",\n timestamp: 0,\n duration: 0,\n data,\n kind: frame.track,\n } as const;\n this.onData.execute(res);\n }\n\n frameBuffer: (EncodedChunk & {\n track: \"video\" | \"audio\";\n })[] = [];\n\n #enqueue(\n frame: EncodedChunk & {\n track: \"video\" | \"audio\";\n },\n ) {\n this.frameBuffer.push(frame);\n if (!this.tracksReady) {\n return;\n }\n for (const frame of this.frameBuffer) {\n this._enqueue(frame);\n }\n this.frameBuffer = [];\n }\n\n private _enqueue(\n frame: EncodedChunk & {\n track: \"video\" | \"audio\";\n },\n ) {\n const track = frame.track === \"audio\" ? this.audioTrack : this.videoTrack;\n if (!track) {\n throw new Error(\"track missing\");\n }\n\n // Check if we should create a new segment\n if (frame.track === \"video\") {\n if (frame.type == \"key\") {\n this.#videoSegment += 1;\n } else if (this.#videoSegment == 0) {\n throw new Error(\"must start with keyframe\");\n }\n } else {\n this.#audioSegment += 1;\n }\n\n // We need a one frame buffer to compute the duration\n if (frame.track === \"video\") {\n if (!this.#videoFrame) {\n this.#videoFrame = frame;\n return;\n }\n } else {\n if (!this.#audioFrame) {\n this.#audioFrame = frame;\n return;\n }\n }\n\n const bufferFrame =\n frame.track === \"video\" ? this.#videoFrame : this.#audioFrame;\n\n if (!bufferFrame) {\n throw new Error(\"bufferFrame missing\");\n }\n\n const duration = frame.timestamp - bufferFrame.timestamp;\n\n // TODO avoid this extra copy by writing to the mdat directly\n // ...which means changing mp4box.js to take an offset instead of ArrayBuffer\n const buffer = new Uint8Array(bufferFrame.byteLength);\n bufferFrame.copyTo(buffer);\n\n // Add the sample to the container\n this.#mp4.addSample(track, buffer, {\n duration,\n dts: bufferFrame.timestamp,\n cts: bufferFrame.timestamp,\n is_sync: bufferFrame.type == \"key\",\n });\n\n const stream = new MP4.Stream(undefined, 0, MP4.Stream.BIG_ENDIAN);\n\n // Moof and mdat atoms are written in pairs.\n // TODO remove the moof/mdat from the Box to reclaim memory once everything works\n for (;;) {\n const moof = this.#mp4.moofs.shift();\n const mdat = this.#mp4.mdats.shift();\n\n if (!moof && !mdat) break;\n if (!moof) throw new Error(\"moof missing\");\n if (!mdat) throw new Error(\"mdat missing\");\n\n moof.write(stream);\n mdat.write(stream);\n }\n\n // TODO avoid this extra copy by writing to the buffer provided in copyTo\n const data = new Uint8Array(stream.buffer);\n\n if (frame.track === \"video\") {\n this.#videoFrame = frame;\n } else {\n this.#audioFrame = frame;\n }\n\n const res = {\n type: bufferFrame.type,\n timestamp: bufferFrame.timestamp,\n kind: frame.track,\n duration,\n data,\n };\n this.onData.execute(res);\n }\n\n /* TODO flush the last frame\n\t#flush(controller: TransformStreamDefaultController<Chunk>) {\n\t\tif (this.#frame) {\n\t\t\t// TODO guess the duration\n\t\t\tthis.#enqueue(this.#frame, 0, controller)\n\t\t}\n\t}\n\t*/\n}\n\nfunction isDecoderConfig(\n frame: DecoderConfig | EncodedChunk,\n): frame is DecoderConfig {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (frame as DecoderConfig).codec !== undefined;\n}\n\nfunction isVideoConfig(frame: DecoderConfig): frame is VideoDecoderConfig {\n return (frame as VideoDecoderConfig).codedWidth !== undefined;\n}\n\nexport interface AudioDecoderConfig {\n codec: string;\n description?: ArrayBuffer | undefined;\n numberOfChannels: number;\n sampleRate: number;\n}\n\nexport interface VideoDecoderConfig {\n codec: string;\n codedHeight?: number | undefined;\n codedWidth?: number | undefined;\n description?: ArrayBuffer | undefined;\n displayAspectHeight?: number | undefined;\n displayAspectWidth?: number | undefined;\n optimizeForLatency?: boolean | undefined;\n}\n\ninterface EncodedAudioChunk {\n readonly byteLength: number;\n readonly duration: number | null;\n readonly timestamp: number;\n readonly type: EncodedAudioChunkType;\n copyTo(destination: ArrayBuffer): void;\n}\n\ntype EncodedAudioChunkType = \"delta\" | \"key\";\n\ninterface EncodedVideoChunk {\n readonly byteLength: number;\n readonly duration: number | null;\n readonly timestamp: number;\n readonly type: EncodedVideoChunkType;\n copyTo(destination: ArrayBuffer): void;\n}\n\ntype EncodedVideoChunkType = \"delta\" | \"key\";\n\nexport const mp4SupportedCodecs = [\"avc1\", \"opus\"] as const;\nexport type Mp4SupportedCodec = (typeof mp4SupportedCodecs)[number];\n"]}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../../../../../../rtp/src/extra/container/mp4/container.ts"],"names":[],"mappings":"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","sourcesContent":["import { Event } from \"../../../imports/common\";\n\nimport * as MP4 from \"./mp4box\";\n\ntype DecoderConfig = AudioDecoderConfig | VideoDecoderConfig;\ntype EncodedChunk = EncodedAudioChunk | EncodedVideoChunk;\n\nexport type DataType = \"init\" | \"delta\" | \"key\";\n\nexport interface Mp4Data {\n type: DataType;\n timestamp: number;\n duration: number;\n data: Uint8Array;\n kind: \"audio\" | \"video\";\n}\n\nexport class Mp4Container {\n #mp4: MP4.ISOFile;\n #audioFrame?: EncodedAudioChunk | EncodedVideoChunk;\n #videoFrame?: EncodedAudioChunk | EncodedVideoChunk; // 1 frame buffer\n audioTrack?: number;\n videoTrack?: number;\n #audioSegment = 0;\n #videoSegment = 0;\n onData = new Event<[Mp4Data]>();\n\n constructor(\n private props: {\n track: { audio: boolean; video: boolean };\n },\n ) {\n this.#mp4 = new MP4.ISOFile();\n this.#mp4.init();\n }\n\n get tracksReady() {\n let ready = true;\n if (this.props.track.audio && !this.audioTrack) {\n ready = false;\n }\n if (this.props.track.video && !this.videoTrack) {\n ready = false;\n }\n return ready;\n }\n\n write(\n frame: (DecoderConfig | EncodedChunk) & {\n track: \"video\" | \"audio\";\n },\n ) {\n if (isDecoderConfig(frame)) {\n return this.#init(frame);\n } else {\n return this.#enqueue(frame);\n }\n }\n\n #init(\n frame: DecoderConfig & {\n track: \"video\" | \"audio\";\n },\n ) {\n let codec = frame.codec.substring(0, 4);\n if (codec == \"opus\") {\n codec = \"Opus\";\n }\n\n const options: MP4.TrackOptions = {\n type: codec,\n timescale: 1_000_000,\n };\n\n if (isVideoConfig(frame)) {\n options.width = frame.codedWidth;\n options.height = frame.codedHeight;\n } else {\n options.channel_count = frame.numberOfChannels;\n options.samplerate = frame.sampleRate;\n options.hdlr = \"soun\";\n }\n\n if (!frame.description) throw new Error(\"missing frame description\");\n const desc = frame.description as ArrayBufferLike;\n\n if (codec === \"avc1\") {\n options.avcDecoderConfigRecord = desc;\n } else if (codec === \"hev1\") {\n options.hevcDecoderConfigRecord = desc;\n } else if (codec === \"Opus\") {\n // description is an identification header: https://datatracker.ietf.org/doc/html/rfc7845#section-5.1\n // The first 8 bytes are the magic string \"OpusHead\", followed by what we actually want.\n const dops = new MP4.BoxParser.dOpsBox();\n\n // Annoyingly, the header is little endian while MP4 is big endian, so we have to parse.\n dops.parse(new MP4.Stream(desc, 8, MP4.Stream.LITTLE_ENDIAN));\n\n options.description = dops;\n } else {\n throw new Error(`unsupported codec: ${codec}`);\n }\n\n const track = this.#mp4.addTrack(options);\n if (track == undefined) {\n throw new Error(\"failed to initialize MP4 track\");\n }\n if (frame.track === \"audio\") {\n this.audioTrack = track;\n } else {\n this.videoTrack = track;\n }\n\n if (!this.tracksReady) {\n return;\n }\n\n const buffer = MP4.ISOFile.writeInitializationSegment(\n this.#mp4.ftyp!,\n this.#mp4.moov!,\n 0,\n 0,\n );\n const data = new Uint8Array(buffer);\n const res = {\n type: \"init\",\n timestamp: 0,\n duration: 0,\n data,\n kind: frame.track,\n } as const;\n this.onData.execute(res);\n }\n\n frameBuffer: (EncodedChunk & {\n track: \"video\" | \"audio\";\n })[] = [];\n\n #enqueue(\n frame: EncodedChunk & {\n track: \"video\" | \"audio\";\n },\n ) {\n this.frameBuffer.push(frame);\n if (!this.tracksReady) {\n return;\n }\n for (const frame of this.frameBuffer) {\n this._enqueue(frame);\n }\n this.frameBuffer = [];\n }\n\n private _enqueue(\n frame: EncodedChunk & {\n track: \"video\" | \"audio\";\n },\n ) {\n const track = frame.track === \"audio\" ? this.audioTrack : this.videoTrack;\n if (!track) {\n throw new Error(\"track missing\");\n }\n\n // Check if we should create a new segment\n if (frame.track === \"video\") {\n if (frame.type == \"key\") {\n this.#videoSegment += 1;\n } else if (this.#videoSegment == 0) {\n throw new Error(\"must start with keyframe\");\n }\n } else {\n this.#audioSegment += 1;\n }\n\n // We need a one frame buffer to compute the duration\n if (frame.track === \"video\") {\n if (!this.#videoFrame) {\n this.#videoFrame = frame;\n return;\n }\n } else {\n if (!this.#audioFrame) {\n this.#audioFrame = frame;\n return;\n }\n }\n\n const bufferFrame =\n frame.track === \"video\" ? this.#videoFrame : this.#audioFrame;\n\n if (!bufferFrame) {\n throw new Error(\"bufferFrame missing\");\n }\n\n const duration = frame.timestamp - bufferFrame.timestamp;\n\n // TODO avoid this extra copy by writing to the mdat directly\n // ...which means changing mp4box.js to take an offset instead of ArrayBuffer\n const buffer = new Uint8Array(bufferFrame.byteLength);\n bufferFrame.copyTo(buffer);\n\n // Add the sample to the container\n this.#mp4.addSample(track, buffer, {\n duration,\n dts: bufferFrame.timestamp,\n cts: bufferFrame.timestamp,\n is_sync: bufferFrame.type == \"key\",\n });\n\n const stream = new MP4.Stream(undefined, 0, MP4.Stream.BIG_ENDIAN);\n\n // Moof and mdat atoms are written in pairs.\n // TODO remove the moof/mdat from the Box to reclaim memory once everything works\n for (;;) {\n const moof = this.#mp4.moofs.shift();\n const mdat = this.#mp4.mdats.shift();\n\n if (!moof && !mdat) break;\n if (!moof) throw new Error(\"moof missing\");\n if (!mdat) throw new Error(\"mdat missing\");\n\n moof.write(stream);\n mdat.write(stream);\n }\n\n // TODO avoid this extra copy by writing to the buffer provided in copyTo\n const data = new Uint8Array(stream.buffer);\n\n if (frame.track === \"video\") {\n this.#videoFrame = frame;\n } else {\n this.#audioFrame = frame;\n }\n\n const res = {\n type: bufferFrame.type,\n timestamp: bufferFrame.timestamp,\n kind: frame.track,\n duration,\n data,\n };\n this.onData.execute(res);\n }\n\n /* TODO flush the last frame\n\t#flush(controller: TransformStreamDefaultController<Chunk>) {\n\t\tif (this.#frame) {\n\t\t\t// TODO guess the duration\n\t\t\tthis.#enqueue(this.#frame, 0, controller)\n\t\t}\n\t}\n\t*/\n}\n\nfunction isDecoderConfig(\n frame: DecoderConfig | EncodedChunk,\n): frame is DecoderConfig {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (frame as DecoderConfig).codec !== undefined;\n}\n\nfunction isVideoConfig(frame: DecoderConfig): frame is VideoDecoderConfig {\n return (frame as VideoDecoderConfig).codedWidth !== undefined;\n}\n\nexport interface AudioDecoderConfig {\n codec: string;\n description?: ArrayBuffer | undefined;\n numberOfChannels: number;\n sampleRate: number;\n}\n\nexport interface VideoDecoderConfig {\n codec: string;\n codedHeight?: number | undefined;\n codedWidth?: number | undefined;\n description?: ArrayBuffer | undefined;\n displayAspectHeight?: number | undefined;\n displayAspectWidth?: number | undefined;\n optimizeForLatency?: boolean | undefined;\n}\n\ninterface EncodedAudioChunk {\n readonly byteLength: number;\n readonly duration: number | null;\n readonly timestamp: number;\n readonly type: EncodedAudioChunkType;\n copyTo(destination: ArrayBuffer): void;\n}\n\ntype EncodedAudioChunkType = \"delta\" | \"key\";\n\ninterface EncodedVideoChunk {\n readonly byteLength: number;\n readonly duration: number | null;\n readonly timestamp: number;\n readonly type: EncodedVideoChunkType;\n copyTo(destination: ArrayBuffer): void;\n}\n\ntype EncodedVideoChunkType = \"delta\" | \"key\";\n\nexport const mp4SupportedCodecs = [\"avc1\", \"opus\"] as const;\nexport type Mp4SupportedCodec = (typeof mp4SupportedCodecs)[number];\n"]}
@@ -1,4 +1,4 @@
1
- import Event from "rx.mini";
1
+ import { Event } from "../../imports/common";
2
2
  import { type DepacketizerCodec, type RtpHeader, type RtpPacket } from "../..";
3
3
  import type { Processor } from "./interface";
4
4
  export type DepacketizerInput = {
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.DepacketizeBase = void 0;
7
7
  const debug_1 = __importDefault(require("debug"));
8
- const rx_mini_1 = __importDefault(require("rx.mini"));
8
+ const common_1 = require("../../imports/common");
9
9
  const __1 = require("../..");
10
10
  const path = `werift-rtp : packages/rtp/src/processor/depacketizer.ts`;
11
11
  const log = (0, debug_1.default)(path);
@@ -63,7 +63,7 @@ class DepacketizeBase {
63
63
  enumerable: true,
64
64
  configurable: true,
65
65
  writable: true,
66
- value: new rx_mini_1.default()
66
+ value: new common_1.Event()
67
67
  });
68
68
  Object.defineProperty(this, "internalStats", {
69
69
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"depacketizer.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/depacketizer.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,sDAA4B;AAE5B,6BAQe;AAGf,MAAM,IAAI,GAAG,yDAAyD,CAAC;AACvE,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,IAAI,CAAC,CAAC;AA2BxB,MAAa,eAAe;IAY1B,YACU,KAAwB,EACxB,UAA+B,EAAE;QADzC;;;;mBAAQ,KAAK;WAAmB;QAChC;;;;mBAAQ,OAAO;WAA0B;QAXnC;;;;mBAAiC,EAAE;WAAC;QACpC;;;;;WAA6B;QAC7B;;;;;WAAoB;QACpB;;;;mBAAc,KAAK;WAAC;QACpB;;;;mBAAmB,KAAK;WAAC;QACzB;;;;mBAAQ,CAAC;WAAC;QACT;;;;mBAAiB,IAAI,iBAAK,EAAE;WAAC;QAC9B;;;;mBAAgB,EAAE;WAAC;IAKxB,CAAC;IAEJ,MAAM;QACJ,OAAO;YACL,GAAG,IAAI,CAAC,aAAa;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM;YACtC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC;IACJ,CAAC;IAED,YAAY,CAAC,KAAwB;QACnC,MAAM,MAAM,GAAyB,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACf,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC3B,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC7C,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC;oBACH,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,mBAAmB,EAAE,GAClE,IAAA,yBAAqB,EACnB,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAI,CAAC,EACjC,IAAI,CAAC,mBAAmB,CACzB,CAAC;oBACJ,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;oBAE/C,IAAI,UAAU,EAAE,CAAC;wBACf,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;oBAC/B,CAAC;oBAED,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,gBAAgB,KAAK,KAAK,EAAE,CAAC;wBACpE,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;wBAC9B,OAAO,EAAE,CAAC;oBACZ,CAAC;oBAED,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;wBAC9C,MAAM,CAAC,IAAI,CAAC;4BACV,KAAK,EAAE;gCACL,IAAI;gCACJ,UAAU;gCACV,IAAI;gCACJ,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE;gCACtB,MAAM,EAAE,QAAQ;gCAChB,SAAS;6BACV;yBACF,CAAC,CAAC;wBACH,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBAChE,CAAC;oBAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBACrB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;oBAC3B,CAAC;oBAED,IAAI,CAAC,WAAW,EAAE,CAAC;oBAEnB,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;oBAClD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC;gBACH,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,mBAAmB,EAAE,GAClE,IAAA,yBAAqB,EACnB,IAAI,CAAC,KAAK,EACV,CAAC,KAAK,CAAC,GAAG,CAAC,EACX,IAAI,CAAC,mBAAmB,CACzB,CAAC;gBACJ,IAAI,CAAC,mBAAmB,GAAG,mBAAmB,CAAC;gBAC/C,MAAM,CAAC,IAAI,CAAC;oBACV,KAAK,EAAE;wBACL,IAAI;wBACJ,UAAU;wBACV,IAAI,EAAE,KAAK,CAAC,IAAK;wBACjB,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE;wBACtB,MAAM,EAAE,QAAQ;wBAChB,SAAS;qBACV;iBACF,CAAC,CAAC;gBACH,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC9D,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,IAAI;QACV,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,IAAI,CAAC,cAAc,CAAC,cAAc,EAAE,CAAC;IACvC,CAAC;IAEO,WAAW;QACjB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,mBAAmB,GAAG,SAAS,CAAC;IACvC,CAAC;IAEO,gBAAgB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAqB;;QACvD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,EAAE,cAAc,EAAE,GAAG,GAAI,CAAC,MAAM,CAAC;QACvC,IAAI,IAAI,CAAC,UAAU,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,IAAA,aAAS,EAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC7C,IAAI,IAAA,YAAQ,EAAC,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG;oBAC/B,MAAM;oBACN,cAAc;oBACd,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBAC5B,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC;iBACxD,CAAC;gBACF,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,IAAA,YAAQ,EAAC,cAAc,EAAE,MAAM,CAAC,EAAE,CAAC;gBACrC,MAAA,IAAI,CAAC,aAAa,EAAC,YAAY,SAAZ,YAAY,IAAM,EAAE,EAAC;gBACxC,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;oBACjD,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,KAAK,EAAE,CAAC;gBAC3C,CAAC;gBACD,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC;oBACpC,MAAM;oBACN,cAAc;oBACd,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBAC7B,CAAC,CAAC;gBACH,MAAA,IAAI,CAAC,aAAa,EAAC,iBAAiB,SAAjB,iBAAiB,IAAM,CAAC,EAAC;gBAC5C,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAExC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,cAAc,CAAC;QAEjC,IAAI,WAA+B,CAAC;QACpC,KAAK,MAAM,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,IAAA,aAAS,EAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,GAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtD,WAAW,GAAG,CAAC,CAAC;gBAChB,MAAM;YACR,CAAC;QACH,CAAC;QACD,IAAI,WAAW,IAAI,SAAS,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAlLD,0CAkLC","sourcesContent":["import debug from \"debug\";\nimport Event from \"rx.mini\";\n\nimport {\n type DepacketizerCodec,\n type RtpHeader,\n type RtpPacket,\n dePacketizeRtpPackets,\n enumerate,\n uint16Add,\n uint16Gt,\n} from \"../..\";\nimport type { Processor } from \"./interface\";\n\nconst path = `werift-rtp : packages/rtp/src/processor/depacketizer.ts`;\nconst log = debug(path);\n\nexport type DepacketizerInput = {\n rtp?: RtpPacket;\n /**ms */\n time?: number;\n eol?: boolean;\n};\n\nexport interface DepacketizerOutput {\n frame?: CodecFrame;\n eol?: boolean;\n}\n\nexport interface CodecFrame {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n [key: string]: any;\n}\n\nexport interface DepacketizerOptions {\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n waitForKeyframe?: boolean;\n}\n\nexport class DepacketizeBase\n implements Processor<DepacketizerInput, DepacketizerOutput>\n{\n private rtpBuffer: DepacketizerInput[] = [];\n private frameFragmentBuffer?: Buffer;\n private lastSeqNum?: number;\n private frameBroken = false;\n private keyframeReceived = false;\n private count = 0;\n readonly onNeedKeyFrame = new Event();\n private internalStats = {};\n\n constructor(\n private codec: DepacketizerCodec,\n private options: DepacketizerOptions = {},\n ) {}\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n codec: this.codec,\n bufferingLength: this.rtpBuffer.length,\n lastSeqNum: this.lastSeqNum,\n count: this.count,\n };\n }\n\n processInput(input: DepacketizerInput): DepacketizerOutput[] {\n const output: DepacketizerOutput[] = [];\n if (!input.rtp) {\n if (input.eol) {\n output.push({ eol: true });\n this.stop();\n }\n return output;\n }\n\n if (this.options.isFinalPacketInSequence) {\n const isFinal = this.checkFinalPacket(input);\n if (isFinal) {\n try {\n const { data, isKeyframe, sequence, timestamp, frameFragmentBuffer } =\n dePacketizeRtpPackets(\n this.codec,\n this.rtpBuffer.map((b) => b.rtp!),\n this.frameFragmentBuffer,\n );\n this.frameFragmentBuffer = frameFragmentBuffer;\n\n if (isKeyframe) {\n this.keyframeReceived = true;\n }\n\n if (this.options.waitForKeyframe && this.keyframeReceived === false) {\n this.onNeedKeyFrame.execute();\n return [];\n }\n\n if (!this.frameBroken && data.length > 0) {\n const time = this.rtpBuffer.at(-1)?.time ?? 0;\n output.push({\n frame: {\n data,\n isKeyframe,\n time,\n sequence: this.count++,\n rtpSeq: sequence,\n timestamp,\n },\n });\n this.internalStats[\"depacketizer\"] = new Date().toISOString();\n }\n\n if (this.frameBroken) {\n this.frameBroken = false;\n }\n\n this.clearBuffer();\n\n return output;\n } catch (error) {\n log(\"error\", error, { input, codec: this.codec });\n this.clearBuffer();\n }\n }\n } else {\n try {\n const { data, isKeyframe, sequence, timestamp, frameFragmentBuffer } =\n dePacketizeRtpPackets(\n this.codec,\n [input.rtp],\n this.frameFragmentBuffer,\n );\n this.frameFragmentBuffer = frameFragmentBuffer;\n output.push({\n frame: {\n data,\n isKeyframe,\n time: input.time!,\n sequence: this.count++,\n rtpSeq: sequence,\n timestamp,\n },\n });\n this.internalStats[\"depacketizer\"] = new Date().toISOString();\n return output;\n } catch (error) {\n log(\"error\", error, { input, codec: this.codec });\n }\n }\n return [];\n }\n\n private stop() {\n this.clearBuffer();\n\n this.onNeedKeyFrame.allUnsubscribe();\n }\n\n private clearBuffer() {\n this.rtpBuffer.forEach((b) => b.rtp!.clear());\n this.rtpBuffer = [];\n this.frameFragmentBuffer = undefined;\n }\n\n private checkFinalPacket({ rtp, time }: DepacketizerInput): boolean {\n if (!this.options.isFinalPacketInSequence) {\n throw new Error(\"isFinalPacketInSequence not exist\");\n }\n\n const { sequenceNumber } = rtp!.header;\n if (this.lastSeqNum != undefined) {\n const expect = uint16Add(this.lastSeqNum, 1);\n if (uint16Gt(expect, sequenceNumber)) {\n this.internalStats[\"unExpect\"] = {\n expect,\n sequenceNumber,\n codec: this.codec,\n at: new Date().toISOString(),\n count: (this.internalStats[\"unExpect\"]?.count ?? 0) + 1,\n };\n return false;\n }\n if (uint16Gt(sequenceNumber, expect)) {\n this.internalStats[\"packetLost\"] ??= [];\n if (this.internalStats[\"packetLost\"].length > 10) {\n this.internalStats[\"packetLost\"].shift();\n }\n this.internalStats[\"packetLost\"].push({\n expect,\n sequenceNumber,\n codec: this.codec,\n at: new Date().toISOString(),\n });\n this.internalStats[\"packetLostCount\"] ??= 0;\n this.internalStats[\"packetLostCount\"]++;\n\n this.frameBroken = true;\n this.clearBuffer();\n }\n }\n\n this.rtpBuffer.push({ rtp, time });\n this.lastSeqNum = sequenceNumber;\n\n let finalPacket: number | undefined;\n for (const [i, { rtp }] of enumerate(this.rtpBuffer)) {\n if (this.options.isFinalPacketInSequence(rtp!.header)) {\n finalPacket = i;\n break;\n }\n }\n if (finalPacket == undefined) {\n return false;\n }\n\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"depacketizer.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/depacketizer.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport { Event } from \"../../imports/common\";\n\nimport {\n type DepacketizerCodec,\n type RtpHeader,\n type RtpPacket,\n dePacketizeRtpPackets,\n enumerate,\n uint16Add,\n uint16Gt,\n} from \"../..\";\nimport type { Processor } from \"./interface\";\n\nconst path = `werift-rtp : packages/rtp/src/processor/depacketizer.ts`;\nconst log = debug(path);\n\nexport type DepacketizerInput = {\n rtp?: RtpPacket;\n /**ms */\n time?: number;\n eol?: boolean;\n};\n\nexport interface DepacketizerOutput {\n frame?: CodecFrame;\n eol?: boolean;\n}\n\nexport interface CodecFrame {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n [key: string]: any;\n}\n\nexport interface DepacketizerOptions {\n isFinalPacketInSequence?: (header: RtpHeader) => boolean;\n waitForKeyframe?: boolean;\n}\n\nexport class DepacketizeBase\n implements Processor<DepacketizerInput, DepacketizerOutput>\n{\n private rtpBuffer: DepacketizerInput[] = [];\n private frameFragmentBuffer?: Buffer;\n private lastSeqNum?: number;\n private frameBroken = false;\n private keyframeReceived = false;\n private count = 0;\n readonly onNeedKeyFrame = new Event();\n private internalStats = {};\n\n constructor(\n private codec: DepacketizerCodec,\n private options: DepacketizerOptions = {},\n ) {}\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n codec: this.codec,\n bufferingLength: this.rtpBuffer.length,\n lastSeqNum: this.lastSeqNum,\n count: this.count,\n };\n }\n\n processInput(input: DepacketizerInput): DepacketizerOutput[] {\n const output: DepacketizerOutput[] = [];\n if (!input.rtp) {\n if (input.eol) {\n output.push({ eol: true });\n this.stop();\n }\n return output;\n }\n\n if (this.options.isFinalPacketInSequence) {\n const isFinal = this.checkFinalPacket(input);\n if (isFinal) {\n try {\n const { data, isKeyframe, sequence, timestamp, frameFragmentBuffer } =\n dePacketizeRtpPackets(\n this.codec,\n this.rtpBuffer.map((b) => b.rtp!),\n this.frameFragmentBuffer,\n );\n this.frameFragmentBuffer = frameFragmentBuffer;\n\n if (isKeyframe) {\n this.keyframeReceived = true;\n }\n\n if (this.options.waitForKeyframe && this.keyframeReceived === false) {\n this.onNeedKeyFrame.execute();\n return [];\n }\n\n if (!this.frameBroken && data.length > 0) {\n const time = this.rtpBuffer.at(-1)?.time ?? 0;\n output.push({\n frame: {\n data,\n isKeyframe,\n time,\n sequence: this.count++,\n rtpSeq: sequence,\n timestamp,\n },\n });\n this.internalStats[\"depacketizer\"] = new Date().toISOString();\n }\n\n if (this.frameBroken) {\n this.frameBroken = false;\n }\n\n this.clearBuffer();\n\n return output;\n } catch (error) {\n log(\"error\", error, { input, codec: this.codec });\n this.clearBuffer();\n }\n }\n } else {\n try {\n const { data, isKeyframe, sequence, timestamp, frameFragmentBuffer } =\n dePacketizeRtpPackets(\n this.codec,\n [input.rtp],\n this.frameFragmentBuffer,\n );\n this.frameFragmentBuffer = frameFragmentBuffer;\n output.push({\n frame: {\n data,\n isKeyframe,\n time: input.time!,\n sequence: this.count++,\n rtpSeq: sequence,\n timestamp,\n },\n });\n this.internalStats[\"depacketizer\"] = new Date().toISOString();\n return output;\n } catch (error) {\n log(\"error\", error, { input, codec: this.codec });\n }\n }\n return [];\n }\n\n private stop() {\n this.clearBuffer();\n\n this.onNeedKeyFrame.allUnsubscribe();\n }\n\n private clearBuffer() {\n this.rtpBuffer.forEach((b) => b.rtp!.clear());\n this.rtpBuffer = [];\n this.frameFragmentBuffer = undefined;\n }\n\n private checkFinalPacket({ rtp, time }: DepacketizerInput): boolean {\n if (!this.options.isFinalPacketInSequence) {\n throw new Error(\"isFinalPacketInSequence not exist\");\n }\n\n const { sequenceNumber } = rtp!.header;\n if (this.lastSeqNum != undefined) {\n const expect = uint16Add(this.lastSeqNum, 1);\n if (uint16Gt(expect, sequenceNumber)) {\n this.internalStats[\"unExpect\"] = {\n expect,\n sequenceNumber,\n codec: this.codec,\n at: new Date().toISOString(),\n count: (this.internalStats[\"unExpect\"]?.count ?? 0) + 1,\n };\n return false;\n }\n if (uint16Gt(sequenceNumber, expect)) {\n this.internalStats[\"packetLost\"] ??= [];\n if (this.internalStats[\"packetLost\"].length > 10) {\n this.internalStats[\"packetLost\"].shift();\n }\n this.internalStats[\"packetLost\"].push({\n expect,\n sequenceNumber,\n codec: this.codec,\n at: new Date().toISOString(),\n });\n this.internalStats[\"packetLostCount\"] ??= 0;\n this.internalStats[\"packetLostCount\"]++;\n\n this.frameBroken = true;\n this.clearBuffer();\n }\n }\n\n this.rtpBuffer.push({ rtp, time });\n this.lastSeqNum = sequenceNumber;\n\n let finalPacket: number | undefined;\n for (const [i, { rtp }] of enumerate(this.rtpBuffer)) {\n if (this.options.isFinalPacketInSequence(rtp!.header)) {\n finalPacket = i;\n break;\n }\n }\n if (finalPacket == undefined) {\n return false;\n }\n\n return true;\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import Event from "rx.mini";
1
+ import { Event } from "../../imports/common";
2
2
  import { type DataType, type Mp4SupportedCodec } from "../container/mp4";
3
3
  import type { AVProcessor } from "./interface";
4
4
  export type Mp4Input = {
@@ -1,10 +1,7 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.MP4Base = void 0;
7
- const rx_mini_1 = __importDefault(require("rx.mini"));
4
+ const common_1 = require("../../imports/common");
8
5
  const __1 = require("../..");
9
6
  const mp4_1 = require("../container/mp4");
10
7
  class MP4Base {
@@ -49,7 +46,7 @@ class MP4Base {
49
46
  enumerable: true,
50
47
  configurable: true,
51
48
  writable: true,
52
- value: new rx_mini_1.default()
49
+ value: new common_1.Event()
53
50
  });
54
51
  Object.defineProperty(this, "processAudioInput", {
55
52
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"mp4.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/mp4.ts"],"names":[],"mappings":"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","sourcesContent":["import Event from \"rx.mini\";\n\nimport { OpusRtpPayload, buffer2ArrayBuffer } from \"../..\";\nimport {\n type DataType,\n Mp4Container,\n type Mp4SupportedCodec,\n annexb2avcc,\n} from \"../container/mp4\";\nimport type { AVProcessor } from \"./interface\";\n\nexport type Mp4Input = {\n frame?: {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n };\n eol?: boolean;\n};\n\nexport interface Mp4Output {\n type: DataType;\n timestamp: number;\n duration: number;\n data: Uint8Array;\n eol?: boolean;\n kind: \"audio\" | \"video\";\n}\n\nexport interface MP4Option {\n /**ms */\n duration?: number;\n encryptionKey?: Buffer;\n strictTimestamp?: boolean;\n}\n\nexport class MP4Base implements AVProcessor<Mp4Input> {\n private internalStats = {};\n private container: Mp4Container;\n stopped = false;\n onStopped = new Event();\n\n constructor(\n public tracks: Track[],\n private output: (output: Mp4Output) => void,\n private options: MP4Option = {},\n ) {\n this.container = new Mp4Container({\n track: {\n audio: !!this.tracks.find((t) => t.kind === \"audio\"),\n video: !!this.tracks.find((t) => t.kind === \"video\"),\n },\n });\n this.container.onData.subscribe((data) => {\n this.output(data);\n });\n }\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n };\n }\n\n processAudioInput = ({ frame }: Mp4Input) => {\n const track = this.tracks.find((t) => t.kind === \"audio\")!;\n\n if (frame) {\n if (!this.container.audioTrack) {\n this.container.write({\n codec: track.codec,\n description: buffer2ArrayBuffer(OpusRtpPayload.createCodecPrivate()),\n numberOfChannels: 2,\n sampleRate: track.clockRate,\n track: \"audio\",\n });\n } else {\n this.container.write({\n byteLength: frame.data.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: \"key\",\n copyTo: (destination: Uint8Array) => {\n frame.data.copy(destination);\n },\n track: \"audio\",\n });\n }\n }\n };\n\n processVideoInput = ({ frame }: Mp4Input) => {\n const track = this.tracks.find((t) => t.kind === \"video\")!;\n\n if (frame) {\n if (!this.container.videoTrack) {\n if (frame.isKeyframe) {\n const avcc = annexb2avcc(frame.data);\n\n const [displayAspectWidth, displayAspectHeight] = computeRatio(\n track.width!,\n track.height!,\n );\n\n this.container.write({\n codec: track.codec,\n codedWidth: track.width,\n codedHeight: track.height,\n description: avcc.buffer,\n displayAspectWidth,\n displayAspectHeight,\n track: \"video\",\n });\n this.container.write({\n byteLength: frame.data.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: \"key\",\n copyTo: (destination: Uint8Array) => {\n frame.data.copy(destination);\n },\n track: \"video\",\n });\n }\n } else {\n this.container.write({\n byteLength: frame.data.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: frame.isKeyframe ? \"key\" : \"delta\",\n copyTo: (destination: Uint8Array) => {\n frame.data.copy(destination);\n },\n track: \"video\",\n });\n }\n }\n };\n\n protected start() {}\n\n stop() {}\n}\n\nfunction computeRatio(a: number, b: number) {\n function gcd(x: number, y: number) {\n while (y !== 0) {\n const temp = y;\n y = x % y;\n x = temp;\n }\n return x;\n }\n\n const divisor = gcd(a, b);\n return [a / divisor, b / divisor];\n}\n\nexport interface Track {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: Mp4SupportedCodec;\n clockRate: number;\n trackNumber: number;\n}\n"]}
1
+ {"version":3,"file":"mp4.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/mp4.ts"],"names":[],"mappings":"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","sourcesContent":["import { Event } from \"../../imports/common\";\n\nimport { OpusRtpPayload, buffer2ArrayBuffer } from \"../..\";\nimport {\n type DataType,\n Mp4Container,\n type Mp4SupportedCodec,\n annexb2avcc,\n} from \"../container/mp4\";\nimport type { AVProcessor } from \"./interface\";\n\nexport type Mp4Input = {\n frame?: {\n data: Buffer;\n isKeyframe: boolean;\n /**ms */\n time: number;\n };\n eol?: boolean;\n};\n\nexport interface Mp4Output {\n type: DataType;\n timestamp: number;\n duration: number;\n data: Uint8Array;\n eol?: boolean;\n kind: \"audio\" | \"video\";\n}\n\nexport interface MP4Option {\n /**ms */\n duration?: number;\n encryptionKey?: Buffer;\n strictTimestamp?: boolean;\n}\n\nexport class MP4Base implements AVProcessor<Mp4Input> {\n private internalStats = {};\n private container: Mp4Container;\n stopped = false;\n onStopped = new Event();\n\n constructor(\n public tracks: Track[],\n private output: (output: Mp4Output) => void,\n private options: MP4Option = {},\n ) {\n this.container = new Mp4Container({\n track: {\n audio: !!this.tracks.find((t) => t.kind === \"audio\"),\n video: !!this.tracks.find((t) => t.kind === \"video\"),\n },\n });\n this.container.onData.subscribe((data) => {\n this.output(data);\n });\n }\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n };\n }\n\n processAudioInput = ({ frame }: Mp4Input) => {\n const track = this.tracks.find((t) => t.kind === \"audio\")!;\n\n if (frame) {\n if (!this.container.audioTrack) {\n this.container.write({\n codec: track.codec,\n description: buffer2ArrayBuffer(OpusRtpPayload.createCodecPrivate()),\n numberOfChannels: 2,\n sampleRate: track.clockRate,\n track: \"audio\",\n });\n } else {\n this.container.write({\n byteLength: frame.data.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: \"key\",\n copyTo: (destination: Uint8Array) => {\n frame.data.copy(destination);\n },\n track: \"audio\",\n });\n }\n }\n };\n\n processVideoInput = ({ frame }: Mp4Input) => {\n const track = this.tracks.find((t) => t.kind === \"video\")!;\n\n if (frame) {\n if (!this.container.videoTrack) {\n if (frame.isKeyframe) {\n const avcc = annexb2avcc(frame.data);\n\n const [displayAspectWidth, displayAspectHeight] = computeRatio(\n track.width!,\n track.height!,\n );\n\n this.container.write({\n codec: track.codec,\n codedWidth: track.width,\n codedHeight: track.height,\n description: avcc.buffer,\n displayAspectWidth,\n displayAspectHeight,\n track: \"video\",\n });\n this.container.write({\n byteLength: frame.data.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: \"key\",\n copyTo: (destination: Uint8Array) => {\n frame.data.copy(destination);\n },\n track: \"video\",\n });\n }\n } else {\n this.container.write({\n byteLength: frame.data.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: frame.isKeyframe ? \"key\" : \"delta\",\n copyTo: (destination: Uint8Array) => {\n frame.data.copy(destination);\n },\n track: \"video\",\n });\n }\n }\n };\n\n protected start() {}\n\n stop() {}\n}\n\nfunction computeRatio(a: number, b: number) {\n function gcd(x: number, y: number) {\n while (y !== 0) {\n const temp = y;\n y = x % y;\n x = temp;\n }\n return x;\n }\n\n const divisor = gcd(a, b);\n return [a / divisor, b / divisor];\n}\n\nexport interface Track {\n width?: number;\n height?: number;\n kind: \"audio\" | \"video\";\n codec: Mp4SupportedCodec;\n clockRate: number;\n trackNumber: number;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import Event from "rx.mini";
1
+ import { Event } from "../../imports/common";
2
2
  import { GenericNack, RtcpTransportLayerFeedback } from "../..";
3
3
  import type { Processor } from "./interface";
4
4
  import type { RtpOutput } from "./rtpCallback";
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.NackHandlerBase = void 0;
7
7
  const debug_1 = __importDefault(require("debug"));
8
- const rx_mini_1 = __importDefault(require("rx.mini"));
8
+ const common_1 = require("../../imports/common");
9
9
  const __1 = require("../..");
10
10
  const log = (0, debug_1.default)("werift-rtp : packages/rtp/src/processor/nack.ts");
11
11
  const LOST_SIZE = 30 * 5;
@@ -51,13 +51,13 @@ class NackHandlerBase {
51
51
  enumerable: true,
52
52
  configurable: true,
53
53
  writable: true,
54
- value: new rx_mini_1.default()
54
+ value: new common_1.Event()
55
55
  });
56
56
  Object.defineProperty(this, "onPacketLost", {
57
57
  enumerable: true,
58
58
  configurable: true,
59
59
  writable: true,
60
- value: new rx_mini_1.default()
60
+ value: new common_1.Event()
61
61
  });
62
62
  Object.defineProperty(this, "mediaSourceSsrc", {
63
63
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"nack.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/nack.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport Event from \"rx.mini\";\n\nimport {\n GenericNack,\n RtcpTransportLayerFeedback,\n type RtpPacket,\n timer,\n uint16Add,\n} from \"../..\";\nimport type { Processor } from \"./interface\";\nimport type { RtpOutput } from \"./rtpCallback\";\n\nconst log = debug(\"werift-rtp : packages/rtp/src/processor/nack.ts\");\n\nconst LOST_SIZE = 30 * 5;\n\nexport type NackHandlerInput = RtpOutput;\n\nexport type NackHandlerOutput = RtpOutput;\n\nexport class NackHandlerBase\n implements Processor<NackHandlerInput, NackHandlerOutput>\n{\n private newEstSeqNum = 0;\n private _lost: { [seqNum: number]: number } = {};\n private clearNackInterval?: () => void;\n private internalStats = {};\n\n readonly onNackSent = new Event<[GenericNack]>();\n readonly onPacketLost = new Event<[number]>();\n mediaSourceSsrc?: number;\n readonly retryCount = 10;\n stopped = false;\n\n constructor(\n private senderSsrc: number,\n private onNack: (rtcp: RtcpTransportLayerFeedback) => Promise<void>,\n ) {}\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n newEstSeqNum: this.newEstSeqNum,\n lostLength: Object.values(this._lost).length,\n senderSsrc: this.senderSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n };\n }\n\n private get lostSeqNumbers() {\n return Object.keys(this._lost).map(Number).sort();\n }\n\n private getLost(seq: number) {\n return this._lost[seq];\n }\n\n private setLost(seq: number, count: number) {\n this._lost[seq] = count;\n\n if (this.clearNackInterval || this.stopped) {\n return;\n }\n this.clearNackInterval = timer.setInterval(async () => {\n try {\n await this.sendNack();\n if (!Object.keys(this._lost).length) {\n this.clearNackInterval?.();\n this.clearNackInterval = undefined;\n }\n } catch (error) {\n log(\"failed to send nack\", error);\n }\n }, 5);\n }\n\n private removeLost(sequenceNumber: number) {\n delete this._lost[sequenceNumber];\n }\n\n processInput = (input: RtpOutput) => {\n if (input.rtp) {\n this.addPacket(input.rtp);\n this.internalStats[\"nackHandler\"] = new Date().toISOString();\n return [input];\n }\n\n this.stop();\n return [input];\n };\n\n private addPacket(packet: RtpPacket) {\n const { sequenceNumber, ssrc } = packet.header;\n this.mediaSourceSsrc = ssrc;\n\n if (this.newEstSeqNum === 0) {\n this.newEstSeqNum = sequenceNumber;\n return;\n }\n\n if (this.getLost(sequenceNumber)) {\n // log(\"packetLoss resolved\", { sequenceNumber });\n this.removeLost(sequenceNumber);\n return;\n }\n\n if (sequenceNumber === uint16Add(this.newEstSeqNum, 1)) {\n this.newEstSeqNum = sequenceNumber;\n } else if (sequenceNumber > uint16Add(this.newEstSeqNum, 1)) {\n // packet lost detected\n for (\n let seq = uint16Add(this.newEstSeqNum, 1);\n seq < sequenceNumber;\n seq++\n ) {\n this.setLost(seq, 1);\n }\n // this.receiver.sendRtcpPLI(this.mediaSourceSsrc);\n\n this.newEstSeqNum = sequenceNumber;\n this.pruneLost();\n }\n }\n\n private pruneLost() {\n if (this.lostSeqNumbers.length > LOST_SIZE) {\n this._lost = Object.entries(this._lost)\n .slice(-LOST_SIZE)\n .reduce(\n (acc, [key, v]) => {\n acc[key] = v;\n return acc;\n },\n {} as { [seqNum: number]: number },\n );\n }\n }\n\n private stop() {\n this.stopped = true;\n this._lost = {};\n this.clearNackInterval?.();\n this.onNackSent.allUnsubscribe();\n this.onPacketLost.allUnsubscribe();\n this.onNack = undefined as any;\n }\n\n private updateRetryCount() {\n this.lostSeqNumbers.forEach((seq) => {\n const count = this._lost[seq]++;\n if (count > this.retryCount) {\n this.removeLost(seq);\n this.onPacketLost.execute(seq);\n }\n });\n }\n\n private sendNack = () =>\n new Promise((r, f) => {\n if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {\n this.internalStats[\"count\"] = (this.internalStats[\"count\"] ?? 0) + 1;\n\n const nack = new GenericNack({\n senderSsrc: this.senderSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lostSeqNumbers,\n });\n\n const rtcp = new RtcpTransportLayerFeedback({\n feedback: nack,\n });\n this.onNack(rtcp).then(r).catch(f);\n\n this.updateRetryCount();\n this.onNackSent.execute(nack);\n }\n });\n}\n"]}
1
+ {"version":3,"file":"nack.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/nack.ts"],"names":[],"mappings":"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","sourcesContent":["import debug from \"debug\";\nimport { Event } from \"../../imports/common\";\n\nimport {\n GenericNack,\n RtcpTransportLayerFeedback,\n type RtpPacket,\n timer,\n uint16Add,\n} from \"../..\";\nimport type { Processor } from \"./interface\";\nimport type { RtpOutput } from \"./rtpCallback\";\n\nconst log = debug(\"werift-rtp : packages/rtp/src/processor/nack.ts\");\n\nconst LOST_SIZE = 30 * 5;\n\nexport type NackHandlerInput = RtpOutput;\n\nexport type NackHandlerOutput = RtpOutput;\n\nexport class NackHandlerBase\n implements Processor<NackHandlerInput, NackHandlerOutput>\n{\n private newEstSeqNum = 0;\n private _lost: { [seqNum: number]: number } = {};\n private clearNackInterval?: () => void;\n private internalStats = {};\n\n readonly onNackSent = new Event<[GenericNack]>();\n readonly onPacketLost = new Event<[number]>();\n mediaSourceSsrc?: number;\n readonly retryCount = 10;\n stopped = false;\n\n constructor(\n private senderSsrc: number,\n private onNack: (rtcp: RtcpTransportLayerFeedback) => Promise<void>,\n ) {}\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n newEstSeqNum: this.newEstSeqNum,\n lostLength: Object.values(this._lost).length,\n senderSsrc: this.senderSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n };\n }\n\n private get lostSeqNumbers() {\n return Object.keys(this._lost).map(Number).sort();\n }\n\n private getLost(seq: number) {\n return this._lost[seq];\n }\n\n private setLost(seq: number, count: number) {\n this._lost[seq] = count;\n\n if (this.clearNackInterval || this.stopped) {\n return;\n }\n this.clearNackInterval = timer.setInterval(async () => {\n try {\n await this.sendNack();\n if (!Object.keys(this._lost).length) {\n this.clearNackInterval?.();\n this.clearNackInterval = undefined;\n }\n } catch (error) {\n log(\"failed to send nack\", error);\n }\n }, 5);\n }\n\n private removeLost(sequenceNumber: number) {\n delete this._lost[sequenceNumber];\n }\n\n processInput = (input: RtpOutput) => {\n if (input.rtp) {\n this.addPacket(input.rtp);\n this.internalStats[\"nackHandler\"] = new Date().toISOString();\n return [input];\n }\n\n this.stop();\n return [input];\n };\n\n private addPacket(packet: RtpPacket) {\n const { sequenceNumber, ssrc } = packet.header;\n this.mediaSourceSsrc = ssrc;\n\n if (this.newEstSeqNum === 0) {\n this.newEstSeqNum = sequenceNumber;\n return;\n }\n\n if (this.getLost(sequenceNumber)) {\n // log(\"packetLoss resolved\", { sequenceNumber });\n this.removeLost(sequenceNumber);\n return;\n }\n\n if (sequenceNumber === uint16Add(this.newEstSeqNum, 1)) {\n this.newEstSeqNum = sequenceNumber;\n } else if (sequenceNumber > uint16Add(this.newEstSeqNum, 1)) {\n // packet lost detected\n for (\n let seq = uint16Add(this.newEstSeqNum, 1);\n seq < sequenceNumber;\n seq++\n ) {\n this.setLost(seq, 1);\n }\n // this.receiver.sendRtcpPLI(this.mediaSourceSsrc);\n\n this.newEstSeqNum = sequenceNumber;\n this.pruneLost();\n }\n }\n\n private pruneLost() {\n if (this.lostSeqNumbers.length > LOST_SIZE) {\n this._lost = Object.entries(this._lost)\n .slice(-LOST_SIZE)\n .reduce(\n (acc, [key, v]) => {\n acc[key] = v;\n return acc;\n },\n {} as { [seqNum: number]: number },\n );\n }\n }\n\n private stop() {\n this.stopped = true;\n this._lost = {};\n this.clearNackInterval?.();\n this.onNackSent.allUnsubscribe();\n this.onPacketLost.allUnsubscribe();\n this.onNack = undefined as any;\n }\n\n private updateRetryCount() {\n this.lostSeqNumbers.forEach((seq) => {\n const count = this._lost[seq]++;\n if (count > this.retryCount) {\n this.removeLost(seq);\n this.onPacketLost.execute(seq);\n }\n });\n }\n\n private sendNack = () =>\n new Promise((r, f) => {\n if (this.lostSeqNumbers.length > 0 && this.mediaSourceSsrc) {\n this.internalStats[\"count\"] = (this.internalStats[\"count\"] ?? 0) + 1;\n\n const nack = new GenericNack({\n senderSsrc: this.senderSsrc,\n mediaSourceSsrc: this.mediaSourceSsrc,\n lost: this.lostSeqNumbers,\n });\n\n const rtcp = new RtcpTransportLayerFeedback({\n feedback: nack,\n });\n this.onNack(rtcp).then(r).catch(f);\n\n this.updateRetryCount();\n this.onNackSent.execute(nack);\n }\n });\n}\n"]}