werift 0.17.5 → 0.17.6

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.
@@ -31,10 +31,13 @@ async function findPort(min, max, protocol = "udp4", interfaceAddresses) {
31
31
  port: i,
32
32
  address: (0, exports.interfaceAddress)(protocol, interfaceAddresses),
33
33
  }));
34
- await new Promise((r) => {
35
- socket.once("error", r);
36
- socket.once("listening", r);
34
+ const err = await new Promise((r) => {
35
+ socket.once("error", (e) => r(e));
36
+ socket.once("listening", () => r());
37
37
  });
38
+ if (err) {
39
+ continue;
40
+ }
38
41
  port = socket.address()?.port;
39
42
  await new Promise((r) => socket.close(() => r()));
40
43
  if (min <= port && port <= max) {
@@ -1 +1 @@
1
- {"version":3,"file":"network.js","sourceRoot":"","sources":["../../../../common/src/network.ts"],"names":[],"mappings":";;;AAAA,iCAAiD;AAM1C,MAAM,gBAAgB,GAAG,CAC9B,IAAgB,EAChB,kBAAkD,EAClD,EAAE,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAHpD,QAAA,gBAAgB,oBAGoC;AAE1D,KAAK,UAAU,UAAU,CAC9B,WAAuB,MAAM,EAC7B,kBAAuC;IAEvC,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,QAAQ,CAAC,CAAC;IAEtC,YAAY,CAAC,GAAG,EAAE,CAChB,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,CAAC;QACP,OAAO,EAAE,IAAA,wBAAgB,EAAC,QAAQ,EAAE,kBAAkB,CAAC;KACxD,CAAC,CACH,CAAC;IAEF,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;QAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC;IACpC,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AArBD,gCAqBC;AAEM,KAAK,UAAU,WAAW,CAC/B,GAAW,EACX,WAAuB,MAAM,EAC7B,kBAAuC;IAEvC,OAAO,OAAO,CAAC,GAAG,CAChB,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CACpE,CAAC;AACJ,CAAC;AARD,kCAQC;AAEM,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,GAAW,EACX,WAAuB,MAAM,EAC7B,kBAAuC;IAEvC,IAAI,IAAwB,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,QAAQ,CAAC,CAAC;QAEtC,YAAY,CAAC,GAAG,EAAE,CAChB,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,CAAC;YACP,OAAO,EAAE,IAAA,wBAAgB,EAAC,QAAQ,EAAE,kBAAkB,CAAC;SACxD,CAAC,CACH,CAAC;QAEF,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE;YAC5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC;QAC9B,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACxD,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,GAAG,EAAE;YAC9B,MAAM;SACP;KACF;IAED,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAE7C,OAAO,IAAI,CAAC;AACd,CAAC;AAjCD,4BAiCC","sourcesContent":["import { createSocket, SocketType } from \"dgram\";\n\nexport type InterfaceAddresses = {\n [K in SocketType]?: string;\n};\n\nexport const interfaceAddress = (\n type: SocketType,\n interfaceAddresses: InterfaceAddresses | undefined\n) => (interfaceAddresses ? interfaceAddresses[type] : undefined);\n\nexport async function randomPort(\n protocol: SocketType = \"udp4\",\n interfaceAddresses?: InterfaceAddresses\n) {\n const socket = createSocket(protocol);\n\n setImmediate(() =>\n socket.bind({\n port: 0,\n address: interfaceAddress(protocol, interfaceAddresses),\n })\n );\n\n await new Promise<void>((r) => {\n socket.once(\"error\", r);\n socket.once(\"listening\", r);\n });\n\n const port = socket.address()?.port;\n await new Promise<void>((r) => socket.close(() => r()));\n return port;\n}\n\nexport async function randomPorts(\n num: number,\n protocol: SocketType = \"udp4\",\n interfaceAddresses?: InterfaceAddresses\n) {\n return Promise.all(\n [...Array(num)].map(() => randomPort(protocol, interfaceAddresses))\n );\n}\n\nexport async function findPort(\n min: number,\n max: number,\n protocol: SocketType = \"udp4\",\n interfaceAddresses?: InterfaceAddresses\n) {\n let port: number | undefined;\n\n for (let i = min; i <= max; i++) {\n const socket = createSocket(protocol);\n\n setImmediate(() =>\n socket.bind({\n port: i,\n address: interfaceAddress(protocol, interfaceAddresses),\n })\n );\n\n await new Promise<void>((r) => {\n socket.once(\"error\", r);\n socket.once(\"listening\", r);\n });\n\n port = socket.address()?.port;\n await new Promise<void>((r) => socket.close(() => r()));\n if (min <= port && port <= max) {\n break;\n }\n }\n\n if (!port) throw new Error(\"port not found\");\n\n return port;\n}\n"]}
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../../../common/src/network.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSocket, SocketType } from \"dgram\";\n\nexport type InterfaceAddresses = {\n [K in SocketType]?: string;\n};\n\nexport const interfaceAddress = (\n type: SocketType,\n interfaceAddresses: InterfaceAddresses | undefined\n) => (interfaceAddresses ? interfaceAddresses[type] : undefined);\n\nexport async function randomPort(\n protocol: SocketType = \"udp4\",\n interfaceAddresses?: InterfaceAddresses\n) {\n const socket = createSocket(protocol);\n\n setImmediate(() =>\n socket.bind({\n port: 0,\n address: interfaceAddress(protocol, interfaceAddresses),\n })\n );\n\n await new Promise<void>((r) => {\n socket.once(\"error\", r);\n socket.once(\"listening\", r);\n });\n\n const port = socket.address()?.port;\n await new Promise<void>((r) => socket.close(() => r()));\n return port;\n}\n\nexport async function randomPorts(\n num: number,\n protocol: SocketType = \"udp4\",\n interfaceAddresses?: InterfaceAddresses\n) {\n return Promise.all(\n [...Array(num)].map(() => randomPort(protocol, interfaceAddresses))\n );\n}\n\nexport async function findPort(\n min: number,\n max: number,\n protocol: SocketType = \"udp4\",\n interfaceAddresses?: InterfaceAddresses\n) {\n let port: number | undefined;\n\n for (let i = min; i <= max; i++) {\n const socket = createSocket(protocol);\n\n setImmediate(() =>\n socket.bind({\n port: i,\n address: interfaceAddress(protocol, interfaceAddresses),\n })\n );\n\n const err = await new Promise<Error | void>((r) => {\n socket.once(\"error\", (e) => r(e));\n socket.once(\"listening\", () => r());\n });\n if (err) {\n continue;\n }\n\n port = socket.address()?.port;\n await new Promise<void>((r) => socket.close(() => r()));\n if (min <= port && port <= max) {\n break;\n }\n }\n\n if (!port) throw new Error(\"port not found\");\n\n return port;\n}\n"]}
@@ -181,6 +181,9 @@ class RTCRtpSender {
181
181
  this.stopped = true;
182
182
  this.rtcpRunning = false;
183
183
  this.rtcpCancel.abort();
184
+ if (this.disposeTrack) {
185
+ this.disposeTrack();
186
+ }
184
187
  this.track = undefined;
185
188
  }
186
189
  async runRtcp() {
@@ -1 +1 @@
1
- {"version":3,"file":"rtpSender.js","sourceRoot":"","sources":["../../../../src/media/rtpSender.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n [10 Nov 1995 11:33:25.125 UTC] [10 Nov 1995 11:33:36.5 UTC]\n n SR(n) A=b710:8000 (46864.500 s)\n ---------------------------------------------------------------->\n v ^\n ntp_sec =0xb44db705 v ^ dlsr=0x0005:4000 ( 5.250s)\n ntp_frac=0x20000000 v ^ lsr =0xb705:2000 (46853.125s)\n (3024992005.125 s) v ^\n r v ^ RR(n)\n ---------------------------------------------------------------->\n |<-DLSR->|\n (5.250 s)\n \n A 0xb710:8000 (46864.500 s)\n DLSR -0x0005:4000 ( 5.250 s)\n LSR -0xb705:2000 (46853.125 s)\n -------------------------------\n delay 0x0006:2000 ( 6.125 s)\n \nFigure 2: Example for round-trip time computation\n */\n\nimport { randomBytes } from \"crypto\";\nimport debug from \"debug\";\nimport { jspack } from \"jspack\";\nimport Event from \"rx.mini\";\nimport { setTimeout } from \"timers/promises\";\nimport * as uuid from \"uuid\";\n\nimport {\n bufferWriter,\n random16,\n uint16Add,\n uint32Add,\n} from \"../../../common/src\";\nimport {\n Extension,\n GenericNack,\n PictureLossIndication,\n ReceiverEstimatedMaxBitrate,\n RedEncoder,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSenderInfo,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n RtpHeader,\n RtpPacket,\n SourceDescriptionChunk,\n SourceDescriptionItem,\n TransportWideCC,\n} from \"../../../rtp/src\";\nimport { codecParametersFromString } from \"..\";\nimport { RTCDtlsTransport } from \"../transport/dtls\";\nimport { Kind } from \"../types/domain\";\nimport { compactNtp, milliTime, ntpTime, timestampSeconds } from \"../utils\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport {\n RTCRtpCodecParameters,\n RTCRtpHeaderExtensionParameters,\n RTCRtpSendParameters,\n} from \"./parameters\";\nimport { SenderBandwidthEstimator, SentInfo } from \"./sender/senderBWE\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpSender.ts\");\n\nconst RTP_HISTORY_SIZE = 128;\nconst RTT_ALPHA = 0.85;\n\nexport class RTCRtpSender {\n readonly type = \"sender\";\n readonly kind =\n typeof this.trackOrKind === \"string\"\n ? this.trackOrKind\n : this.trackOrKind.kind;\n readonly ssrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n readonly rtxSsrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n streamId = uuid.v4();\n readonly trackId = uuid.v4();\n readonly onReady = new Event();\n readonly onRtcp = new Event<[RtcpPacket]>();\n readonly onPictureLossIndication = new Event<[]>();\n readonly onGenericNack = new Event<[GenericNack]>();\n readonly senderBWE = new SenderBandwidthEstimator();\n\n private cname?: string;\n private mid?: string;\n private rtpStreamId?: string;\n private repairedRtpStreamId?: string;\n private rtxPayloadType?: number;\n private rtxSequenceNumber = random16();\n redRedundantPayloadType?: number;\n private _redDistance = 2;\n redEncoder = new RedEncoder(this._redDistance);\n private headerExtensions: RTCRtpHeaderExtensionParameters[] = [];\n private disposeTrack?: () => void;\n\n // # stats\n private lastSRtimestamp?: number;\n private lastSentSRTimestamp?: number;\n private ntpTimestamp = 0n;\n private rtpTimestamp = 0;\n private octetCount = 0;\n private packetCount = 0;\n private rtt?: number;\n receiverEstimatedMaxBitrate: bigint = 0n;\n\n // rtp\n private sequenceNumber?: number;\n private timestamp?: number;\n private timestampOffset = 0;\n private seqOffset = 0;\n private rtpCache: RtpPacket[] = [];\n codec?: RTCRtpCodecParameters;\n public dtlsTransport!: RTCDtlsTransport;\n private dtlsDisposer: (() => void)[] = [];\n\n track?: MediaStreamTrack;\n stopped = false;\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n\n constructor(public trackOrKind: Kind | MediaStreamTrack) {\n if (trackOrKind instanceof MediaStreamTrack) {\n if (trackOrKind.streamId) {\n this.streamId = trackOrKind.streamId;\n }\n this.registerTrack(trackOrKind);\n }\n }\n\n setDtlsTransport(dtlsTransport: RTCDtlsTransport) {\n if (this.dtlsTransport) {\n this.dtlsDisposer.forEach((dispose) => dispose());\n }\n\n this.dtlsTransport = dtlsTransport;\n this.dtlsDisposer = [\n this.dtlsTransport.onStateChange.subscribe((state) => {\n if (state === \"connected\") {\n this.onReady.execute();\n }\n }).unSubscribe,\n ];\n }\n\n get redDistance() {\n return this._redDistance;\n }\n set redDistance(n: number) {\n this._redDistance = n;\n this.redEncoder.distance = n;\n }\n\n prepareSend(params: RTCRtpSendParameters) {\n this.cname = params.rtcp?.cname;\n this.mid = params.muxId;\n this.headerExtensions = params.headerExtensions;\n this.rtpStreamId = params.rtpStreamId;\n this.repairedRtpStreamId = params.repairedRtpStreamId;\n\n this.codec = params.codecs[0];\n if (this.track) {\n this.track.codec = this.codec;\n }\n\n params.codecs.forEach((codec) => {\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n if (\n codec.name.toLowerCase() === \"rtx\" &&\n codecParams[\"apt\"] === this.codec?.payloadType\n ) {\n this.rtxPayloadType = codec.payloadType;\n }\n if (codec.name.toLowerCase() === \"red\") {\n this.redRedundantPayloadType = Number(\n (codec.parameters ?? \"\").split(\"/\")[0]\n );\n }\n });\n }\n\n registerTrack(track: MediaStreamTrack) {\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n\n track.id = this.trackId;\n\n const { unSubscribe } = track.onReceiveRtp.subscribe(async (rtp) => {\n await this.sendRtp(rtp);\n });\n this.track = track;\n this.disposeTrack = unSubscribe;\n\n if (this.codec) {\n track.codec = this.codec;\n }\n\n track.onSourceChanged.subscribe((header) => {\n this.replaceRTP(header);\n });\n }\n\n async replaceTrack(track: MediaStreamTrack | null) {\n if (track === null) {\n // todo impl\n return;\n }\n\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.sequenceNumber != undefined) {\n const header =\n track.header || (await track.onReceiveRtp.asPromise())[0].header;\n\n this.replaceRTP(header);\n }\n\n this.registerTrack(track);\n log(\"replaceTrack\", \"ssrc\", track.ssrc, \"rid\", track.rid);\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n\n this.track = undefined;\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const packets: RtcpPacket[] = [\n new RtcpSrPacket({\n ssrc: this.ssrc,\n senderInfo: new RtcpSenderInfo({\n ntpTimestamp: this.ntpTimestamp,\n rtpTimestamp: this.rtpTimestamp,\n packetCount: this.packetCount,\n octetCount: this.octetCount,\n }),\n }),\n ];\n this.lastSRtimestamp = compactNtp(this.ntpTimestamp);\n this.lastSentSRTimestamp = timestampSeconds();\n\n if (this.cname) {\n packets.push(\n new RtcpSourceDescriptionPacket({\n chunks: [\n new SourceDescriptionChunk({\n source: this.ssrc,\n items: [\n new SourceDescriptionItem({ type: 1, text: this.cname }),\n ],\n }),\n ],\n })\n );\n }\n\n try {\n await this.dtlsTransport.sendRtcp(packets);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n replaceRTP(\n {\n sequenceNumber,\n timestamp,\n }: Pick<RtpHeader, \"sequenceNumber\" | \"timestamp\">,\n discontinuity = false\n ) {\n if (this.sequenceNumber != undefined) {\n this.seqOffset = uint16Add(this.sequenceNumber, -sequenceNumber);\n if (discontinuity) {\n this.seqOffset = uint16Add(this.seqOffset, 2);\n }\n }\n if (this.timestamp != undefined) {\n this.timestampOffset = uint32Add(this.timestamp, -timestamp);\n if (discontinuity) {\n this.timestampOffset = uint16Add(this.timestampOffset, 1);\n }\n }\n this.rtpCache = [];\n log(\"replaceRTP\", this.sequenceNumber, sequenceNumber, this.seqOffset);\n }\n\n async sendRtp(rtp: Buffer | RtpPacket) {\n if (this.dtlsTransport.state !== \"connected\" || !this.codec) {\n return;\n }\n\n rtp = Buffer.isBuffer(rtp) ? RtpPacket.deSerialize(rtp) : rtp;\n\n const header = rtp.header;\n header.ssrc = this.ssrc;\n header.payloadType = this.codec.payloadType;\n header.timestamp = uint32Add(header.timestamp, this.timestampOffset);\n header.sequenceNumber = uint16Add(header.sequenceNumber, this.seqOffset);\n this.timestamp = header.timestamp;\n this.sequenceNumber = header.sequenceNumber;\n\n header.extensions = this.headerExtensions\n .map((extension) => {\n const payload = (() => {\n switch (extension.uri) {\n case RTP_EXTENSION_URI.sdesMid:\n if (this.mid) {\n return Buffer.from(this.mid);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n if (this.rtpStreamId) {\n return Buffer.from(this.rtpStreamId);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n if (this.repairedRtpStreamId) {\n return Buffer.from(this.repairedRtpStreamId);\n }\n return;\n case RTP_EXTENSION_URI.transportWideCC:\n this.dtlsTransport.transportSequenceNumber = uint16Add(\n this.dtlsTransport.transportSequenceNumber,\n 1\n );\n return bufferWriter(\n [2],\n [this.dtlsTransport.transportSequenceNumber]\n );\n case RTP_EXTENSION_URI.absSendTime:\n const buf = Buffer.alloc(3);\n const time = (ntpTime() >> 14n) & 0x00ffffffn;\n buf.writeUIntBE(Number(time), 0, 3);\n return buf;\n }\n })();\n\n if (payload) return { id: extension.id, payload };\n })\n .filter((v) => v) as Extension[];\n\n this.ntpTimestamp = ntpTime();\n this.rtpTimestamp = rtp.header.timestamp;\n this.octetCount += rtp.payload.length;\n this.packetCount = uint32Add(this.packetCount, 1);\n\n rtp.header = header;\n\n this.rtpCache.push(rtp);\n this.rtpCache = this.rtpCache.slice(-RTP_HISTORY_SIZE);\n\n let rtpPayload = rtp.payload;\n\n if (this.redRedundantPayloadType) {\n this.redEncoder.push({\n block: rtpPayload,\n timestamp: header.timestamp,\n blockPT: this.redRedundantPayloadType,\n });\n const red = this.redEncoder.build();\n rtpPayload = red.serialize();\n }\n\n const size = await this.dtlsTransport.sendRtp(rtpPayload, header);\n\n this.runRtcp();\n const sentInfo: SentInfo = {\n wideSeq: this.dtlsTransport.transportSequenceNumber,\n size,\n sendingAtMs: milliTime(),\n sentAtMs: milliTime(),\n };\n this.senderBWE.rtpPacketSent(sentInfo);\n }\n\n handleRtcpPacket(rtcpPacket: RtcpPacket) {\n switch (rtcpPacket.type) {\n case RtcpSrPacket.type:\n case RtcpRrPacket.type:\n {\n const packet = rtcpPacket as RtcpSrPacket | RtcpRrPacket;\n packet.reports\n .filter((report) => report.ssrc === this.ssrc)\n .forEach((report) => {\n if (this.lastSRtimestamp === report.lsr && report.dlsr) {\n if (this.lastSentSRTimestamp) {\n const rtt =\n timestampSeconds() -\n this.lastSentSRTimestamp -\n report.dlsr / 65536;\n if (this.rtt === undefined) {\n this.rtt = rtt;\n } else {\n this.rtt = RTT_ALPHA * this.rtt + (1 - RTT_ALPHA) * rtt;\n }\n }\n }\n });\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const packet = rtcpPacket as RtcpTransportLayerFeedback;\n switch (packet.feedback.count) {\n case TransportWideCC.count:\n {\n const feedback = packet.feedback as TransportWideCC;\n this.senderBWE.receiveTWCC(feedback);\n }\n break;\n case GenericNack.count:\n {\n const feedback = packet.feedback as GenericNack;\n feedback.lost.forEach(async (seqNum) => {\n let packet = this.rtpCache.find(\n (rtp) => rtp.header.sequenceNumber === seqNum\n );\n if (packet) {\n if (this.rtxPayloadType != undefined) {\n packet = wrapRtx(\n packet,\n this.rtxPayloadType,\n this.rtxSequenceNumber,\n this.rtxSsrc\n );\n this.rtxSequenceNumber = uint16Add(\n this.rtxSequenceNumber,\n 1\n );\n }\n await this.dtlsTransport.sendRtp(\n packet.payload,\n packet.header\n );\n }\n });\n this.onGenericNack.execute(feedback);\n }\n break;\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const packet = rtcpPacket as RtcpPayloadSpecificFeedback;\n switch (packet.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n {\n const feedback = packet.feedback as ReceiverEstimatedMaxBitrate;\n this.receiverEstimatedMaxBitrate = feedback.bitrate;\n }\n break;\n case PictureLossIndication.count:\n {\n this.onPictureLossIndication.execute();\n }\n break;\n }\n }\n break;\n }\n this.onRtcp.execute(rtcpPacket);\n }\n}\n\nexport function wrapRtx(\n packet: RtpPacket,\n payloadType: number,\n sequenceNumber: number,\n ssrc: number\n) {\n const rtx = new RtpPacket(\n new RtpHeader({\n payloadType,\n marker: packet.header.marker,\n sequenceNumber,\n timestamp: packet.header.timestamp,\n ssrc,\n csrc: packet.header.csrc,\n extensions: packet.header.extensions,\n }),\n Buffer.concat([\n Buffer.from(jspack.Pack(\"!H\", [packet.header.sequenceNumber])),\n packet.payload,\n ])\n );\n return rtx;\n}\n"]}
1
+ {"version":3,"file":"rtpSender.js","sourceRoot":"","sources":["../../../../src/media/rtpSender.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n [10 Nov 1995 11:33:25.125 UTC] [10 Nov 1995 11:33:36.5 UTC]\n n SR(n) A=b710:8000 (46864.500 s)\n ---------------------------------------------------------------->\n v ^\n ntp_sec =0xb44db705 v ^ dlsr=0x0005:4000 ( 5.250s)\n ntp_frac=0x20000000 v ^ lsr =0xb705:2000 (46853.125s)\n (3024992005.125 s) v ^\n r v ^ RR(n)\n ---------------------------------------------------------------->\n |<-DLSR->|\n (5.250 s)\n \n A 0xb710:8000 (46864.500 s)\n DLSR -0x0005:4000 ( 5.250 s)\n LSR -0xb705:2000 (46853.125 s)\n -------------------------------\n delay 0x0006:2000 ( 6.125 s)\n \nFigure 2: Example for round-trip time computation\n */\n\nimport { randomBytes } from \"crypto\";\nimport debug from \"debug\";\nimport { jspack } from \"jspack\";\nimport Event from \"rx.mini\";\nimport { setTimeout } from \"timers/promises\";\nimport * as uuid from \"uuid\";\n\nimport {\n bufferWriter,\n random16,\n uint16Add,\n uint32Add,\n} from \"../../../common/src\";\nimport {\n Extension,\n GenericNack,\n PictureLossIndication,\n ReceiverEstimatedMaxBitrate,\n RedEncoder,\n RtcpPacket,\n RtcpPayloadSpecificFeedback,\n RtcpRrPacket,\n RtcpSenderInfo,\n RtcpSourceDescriptionPacket,\n RtcpSrPacket,\n RtcpTransportLayerFeedback,\n RtpHeader,\n RtpPacket,\n SourceDescriptionChunk,\n SourceDescriptionItem,\n TransportWideCC,\n} from \"../../../rtp/src\";\nimport { codecParametersFromString } from \"..\";\nimport { RTCDtlsTransport } from \"../transport/dtls\";\nimport { Kind } from \"../types/domain\";\nimport { compactNtp, milliTime, ntpTime, timestampSeconds } from \"../utils\";\nimport { RTP_EXTENSION_URI } from \"./extension/rtpExtension\";\nimport {\n RTCRtpCodecParameters,\n RTCRtpHeaderExtensionParameters,\n RTCRtpSendParameters,\n} from \"./parameters\";\nimport { SenderBandwidthEstimator, SentInfo } from \"./sender/senderBWE\";\nimport { MediaStreamTrack } from \"./track\";\n\nconst log = debug(\"werift:packages/webrtc/src/media/rtpSender.ts\");\n\nconst RTP_HISTORY_SIZE = 128;\nconst RTT_ALPHA = 0.85;\n\nexport class RTCRtpSender {\n readonly type = \"sender\";\n readonly kind =\n typeof this.trackOrKind === \"string\"\n ? this.trackOrKind\n : this.trackOrKind.kind;\n readonly ssrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n readonly rtxSsrc = jspack.Unpack(\"!L\", randomBytes(4))[0];\n streamId = uuid.v4();\n readonly trackId = uuid.v4();\n readonly onReady = new Event();\n readonly onRtcp = new Event<[RtcpPacket]>();\n readonly onPictureLossIndication = new Event<[]>();\n readonly onGenericNack = new Event<[GenericNack]>();\n readonly senderBWE = new SenderBandwidthEstimator();\n\n private cname?: string;\n private mid?: string;\n private rtpStreamId?: string;\n private repairedRtpStreamId?: string;\n private rtxPayloadType?: number;\n private rtxSequenceNumber = random16();\n redRedundantPayloadType?: number;\n private _redDistance = 2;\n redEncoder = new RedEncoder(this._redDistance);\n private headerExtensions: RTCRtpHeaderExtensionParameters[] = [];\n private disposeTrack?: () => void;\n\n // # stats\n private lastSRtimestamp?: number;\n private lastSentSRTimestamp?: number;\n private ntpTimestamp = 0n;\n private rtpTimestamp = 0;\n private octetCount = 0;\n private packetCount = 0;\n private rtt?: number;\n receiverEstimatedMaxBitrate: bigint = 0n;\n\n // rtp\n private sequenceNumber?: number;\n private timestamp?: number;\n private timestampOffset = 0;\n private seqOffset = 0;\n private rtpCache: RtpPacket[] = [];\n codec?: RTCRtpCodecParameters;\n public dtlsTransport!: RTCDtlsTransport;\n private dtlsDisposer: (() => void)[] = [];\n\n track?: MediaStreamTrack;\n stopped = false;\n rtcpRunning = false;\n private rtcpCancel = new AbortController();\n\n constructor(public trackOrKind: Kind | MediaStreamTrack) {\n if (trackOrKind instanceof MediaStreamTrack) {\n if (trackOrKind.streamId) {\n this.streamId = trackOrKind.streamId;\n }\n this.registerTrack(trackOrKind);\n }\n }\n\n setDtlsTransport(dtlsTransport: RTCDtlsTransport) {\n if (this.dtlsTransport) {\n this.dtlsDisposer.forEach((dispose) => dispose());\n }\n\n this.dtlsTransport = dtlsTransport;\n this.dtlsDisposer = [\n this.dtlsTransport.onStateChange.subscribe((state) => {\n if (state === \"connected\") {\n this.onReady.execute();\n }\n }).unSubscribe,\n ];\n }\n\n get redDistance() {\n return this._redDistance;\n }\n set redDistance(n: number) {\n this._redDistance = n;\n this.redEncoder.distance = n;\n }\n\n prepareSend(params: RTCRtpSendParameters) {\n this.cname = params.rtcp?.cname;\n this.mid = params.muxId;\n this.headerExtensions = params.headerExtensions;\n this.rtpStreamId = params.rtpStreamId;\n this.repairedRtpStreamId = params.repairedRtpStreamId;\n\n this.codec = params.codecs[0];\n if (this.track) {\n this.track.codec = this.codec;\n }\n\n params.codecs.forEach((codec) => {\n const codecParams = codecParametersFromString(codec.parameters ?? \"\");\n if (\n codec.name.toLowerCase() === \"rtx\" &&\n codecParams[\"apt\"] === this.codec?.payloadType\n ) {\n this.rtxPayloadType = codec.payloadType;\n }\n if (codec.name.toLowerCase() === \"red\") {\n this.redRedundantPayloadType = Number(\n (codec.parameters ?? \"\").split(\"/\")[0]\n );\n }\n });\n }\n\n registerTrack(track: MediaStreamTrack) {\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n\n track.id = this.trackId;\n\n const { unSubscribe } = track.onReceiveRtp.subscribe(async (rtp) => {\n await this.sendRtp(rtp);\n });\n this.track = track;\n this.disposeTrack = unSubscribe;\n\n if (this.codec) {\n track.codec = this.codec;\n }\n\n track.onSourceChanged.subscribe((header) => {\n this.replaceRTP(header);\n });\n }\n\n async replaceTrack(track: MediaStreamTrack | null) {\n if (track === null) {\n // todo impl\n return;\n }\n\n if (track.stopped) throw new Error(\"track is ended\");\n\n if (this.sequenceNumber != undefined) {\n const header =\n track.header || (await track.onReceiveRtp.asPromise())[0].header;\n\n this.replaceRTP(header);\n }\n\n this.registerTrack(track);\n log(\"replaceTrack\", \"ssrc\", track.ssrc, \"rid\", track.rid);\n }\n\n stop() {\n this.stopped = true;\n this.rtcpRunning = false;\n this.rtcpCancel.abort();\n if (this.disposeTrack) {\n this.disposeTrack();\n }\n this.track = undefined;\n }\n\n async runRtcp() {\n if (this.rtcpRunning || this.stopped) return;\n this.rtcpRunning = true;\n\n try {\n while (this.rtcpRunning) {\n await setTimeout(500 + Math.random() * 1000, undefined, {\n signal: this.rtcpCancel.signal,\n });\n\n const packets: RtcpPacket[] = [\n new RtcpSrPacket({\n ssrc: this.ssrc,\n senderInfo: new RtcpSenderInfo({\n ntpTimestamp: this.ntpTimestamp,\n rtpTimestamp: this.rtpTimestamp,\n packetCount: this.packetCount,\n octetCount: this.octetCount,\n }),\n }),\n ];\n this.lastSRtimestamp = compactNtp(this.ntpTimestamp);\n this.lastSentSRTimestamp = timestampSeconds();\n\n if (this.cname) {\n packets.push(\n new RtcpSourceDescriptionPacket({\n chunks: [\n new SourceDescriptionChunk({\n source: this.ssrc,\n items: [\n new SourceDescriptionItem({ type: 1, text: this.cname }),\n ],\n }),\n ],\n })\n );\n }\n\n try {\n await this.dtlsTransport.sendRtcp(packets);\n } catch (error) {\n log(\"sendRtcp failed\", error);\n await setTimeout(500 + Math.random() * 1000);\n }\n }\n } catch (error) {}\n }\n\n replaceRTP(\n {\n sequenceNumber,\n timestamp,\n }: Pick<RtpHeader, \"sequenceNumber\" | \"timestamp\">,\n discontinuity = false\n ) {\n if (this.sequenceNumber != undefined) {\n this.seqOffset = uint16Add(this.sequenceNumber, -sequenceNumber);\n if (discontinuity) {\n this.seqOffset = uint16Add(this.seqOffset, 2);\n }\n }\n if (this.timestamp != undefined) {\n this.timestampOffset = uint32Add(this.timestamp, -timestamp);\n if (discontinuity) {\n this.timestampOffset = uint16Add(this.timestampOffset, 1);\n }\n }\n this.rtpCache = [];\n log(\"replaceRTP\", this.sequenceNumber, sequenceNumber, this.seqOffset);\n }\n\n async sendRtp(rtp: Buffer | RtpPacket) {\n if (this.dtlsTransport.state !== \"connected\" || !this.codec) {\n return;\n }\n\n rtp = Buffer.isBuffer(rtp) ? RtpPacket.deSerialize(rtp) : rtp;\n\n const header = rtp.header;\n header.ssrc = this.ssrc;\n header.payloadType = this.codec.payloadType;\n header.timestamp = uint32Add(header.timestamp, this.timestampOffset);\n header.sequenceNumber = uint16Add(header.sequenceNumber, this.seqOffset);\n this.timestamp = header.timestamp;\n this.sequenceNumber = header.sequenceNumber;\n\n header.extensions = this.headerExtensions\n .map((extension) => {\n const payload = (() => {\n switch (extension.uri) {\n case RTP_EXTENSION_URI.sdesMid:\n if (this.mid) {\n return Buffer.from(this.mid);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.sdesRTPStreamID:\n if (this.rtpStreamId) {\n return Buffer.from(this.rtpStreamId);\n }\n return;\n // todo : sender simulcast unsupported now\n case RTP_EXTENSION_URI.repairedRtpStreamId:\n if (this.repairedRtpStreamId) {\n return Buffer.from(this.repairedRtpStreamId);\n }\n return;\n case RTP_EXTENSION_URI.transportWideCC:\n this.dtlsTransport.transportSequenceNumber = uint16Add(\n this.dtlsTransport.transportSequenceNumber,\n 1\n );\n return bufferWriter(\n [2],\n [this.dtlsTransport.transportSequenceNumber]\n );\n case RTP_EXTENSION_URI.absSendTime:\n const buf = Buffer.alloc(3);\n const time = (ntpTime() >> 14n) & 0x00ffffffn;\n buf.writeUIntBE(Number(time), 0, 3);\n return buf;\n }\n })();\n\n if (payload) return { id: extension.id, payload };\n })\n .filter((v) => v) as Extension[];\n\n this.ntpTimestamp = ntpTime();\n this.rtpTimestamp = rtp.header.timestamp;\n this.octetCount += rtp.payload.length;\n this.packetCount = uint32Add(this.packetCount, 1);\n\n rtp.header = header;\n\n this.rtpCache.push(rtp);\n this.rtpCache = this.rtpCache.slice(-RTP_HISTORY_SIZE);\n\n let rtpPayload = rtp.payload;\n\n if (this.redRedundantPayloadType) {\n this.redEncoder.push({\n block: rtpPayload,\n timestamp: header.timestamp,\n blockPT: this.redRedundantPayloadType,\n });\n const red = this.redEncoder.build();\n rtpPayload = red.serialize();\n }\n\n const size = await this.dtlsTransport.sendRtp(rtpPayload, header);\n\n this.runRtcp();\n const sentInfo: SentInfo = {\n wideSeq: this.dtlsTransport.transportSequenceNumber,\n size,\n sendingAtMs: milliTime(),\n sentAtMs: milliTime(),\n };\n this.senderBWE.rtpPacketSent(sentInfo);\n }\n\n handleRtcpPacket(rtcpPacket: RtcpPacket) {\n switch (rtcpPacket.type) {\n case RtcpSrPacket.type:\n case RtcpRrPacket.type:\n {\n const packet = rtcpPacket as RtcpSrPacket | RtcpRrPacket;\n packet.reports\n .filter((report) => report.ssrc === this.ssrc)\n .forEach((report) => {\n if (this.lastSRtimestamp === report.lsr && report.dlsr) {\n if (this.lastSentSRTimestamp) {\n const rtt =\n timestampSeconds() -\n this.lastSentSRTimestamp -\n report.dlsr / 65536;\n if (this.rtt === undefined) {\n this.rtt = rtt;\n } else {\n this.rtt = RTT_ALPHA * this.rtt + (1 - RTT_ALPHA) * rtt;\n }\n }\n }\n });\n }\n break;\n case RtcpTransportLayerFeedback.type:\n {\n const packet = rtcpPacket as RtcpTransportLayerFeedback;\n switch (packet.feedback.count) {\n case TransportWideCC.count:\n {\n const feedback = packet.feedback as TransportWideCC;\n this.senderBWE.receiveTWCC(feedback);\n }\n break;\n case GenericNack.count:\n {\n const feedback = packet.feedback as GenericNack;\n feedback.lost.forEach(async (seqNum) => {\n let packet = this.rtpCache.find(\n (rtp) => rtp.header.sequenceNumber === seqNum\n );\n if (packet) {\n if (this.rtxPayloadType != undefined) {\n packet = wrapRtx(\n packet,\n this.rtxPayloadType,\n this.rtxSequenceNumber,\n this.rtxSsrc\n );\n this.rtxSequenceNumber = uint16Add(\n this.rtxSequenceNumber,\n 1\n );\n }\n await this.dtlsTransport.sendRtp(\n packet.payload,\n packet.header\n );\n }\n });\n this.onGenericNack.execute(feedback);\n }\n break;\n }\n }\n break;\n case RtcpPayloadSpecificFeedback.type:\n {\n const packet = rtcpPacket as RtcpPayloadSpecificFeedback;\n switch (packet.feedback.count) {\n case ReceiverEstimatedMaxBitrate.count:\n {\n const feedback = packet.feedback as ReceiverEstimatedMaxBitrate;\n this.receiverEstimatedMaxBitrate = feedback.bitrate;\n }\n break;\n case PictureLossIndication.count:\n {\n this.onPictureLossIndication.execute();\n }\n break;\n }\n }\n break;\n }\n this.onRtcp.execute(rtcpPacket);\n }\n}\n\nexport function wrapRtx(\n packet: RtpPacket,\n payloadType: number,\n sequenceNumber: number,\n ssrc: number\n) {\n const rtx = new RtpPacket(\n new RtpHeader({\n payloadType,\n marker: packet.header.marker,\n sequenceNumber,\n timestamp: packet.header.timestamp,\n ssrc,\n csrc: packet.header.csrc,\n extensions: packet.header.extensions,\n }),\n Buffer.concat([\n Buffer.from(jspack.Pack(\"!H\", [packet.header.sequenceNumber])),\n packet.payload,\n ])\n );\n return rtx;\n}\n"]}
@@ -1,7 +1,9 @@
1
+ import { EventDisposer } from "rx.mini";
1
2
  import { MediaStreamTrack, RtpSourceStream } from "../../..";
2
3
  import { MediaWriter } from ".";
3
4
  export declare class WebmFactory extends MediaWriter {
4
5
  rtpSources: RtpSourceStream[];
6
+ unSubscribers: EventDisposer;
5
7
  start(tracks: MediaStreamTrack[]): Promise<void>;
6
8
  stop(): Promise<void>;
7
9
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WebmFactory = void 0;
4
4
  const promises_1 = require("fs/promises");
5
+ const rx_mini_1 = require("rx.mini");
5
6
  const __1 = require("../../..");
6
7
  const _1 = require(".");
7
8
  const sourcePath = "packages/webrtc/src/nonstandard/recorder/writer/webm.ts";
@@ -9,6 +10,7 @@ class WebmFactory extends _1.MediaWriter {
9
10
  constructor() {
10
11
  super(...arguments);
11
12
  this.rtpSources = [];
13
+ this.unSubscribers = new rx_mini_1.EventDisposer();
12
14
  }
13
15
  async start(tracks) {
14
16
  await (0, promises_1.unlink)(this.path).catch((e) => e);
@@ -60,14 +62,18 @@ class WebmFactory extends _1.MediaWriter {
60
62
  });
61
63
  this.rtpSources = inputTracks.map(({ track, clockRate, codec }) => {
62
64
  const rtpSource = new __1.RtpSourceStream();
63
- track.onReceiveRtp.subscribe((r) => rtpSource.push(r));
64
- const jitterBuffer = (0, __1.jitterBufferTransformer)(clockRate, {
65
- latency: this.options.jitterBufferLatency,
66
- bufferSize: this.options.jitterBufferSize,
67
- });
65
+ track.onReceiveRtp
66
+ .subscribe((rtp) => {
67
+ rtpSource.push(rtp.clone());
68
+ })
69
+ .disposer(this.unSubscribers);
70
+ // const jitterBuffer = jitterBufferTransformer(clockRate, {
71
+ // latency: this.options.jitterBufferLatency,
72
+ // bufferSize: this.options.jitterBufferSize,
73
+ // });
68
74
  if (track.kind === "video") {
69
75
  rtpSource.readable
70
- .pipeThrough(jitterBuffer)
76
+ // .pipeThrough(jitterBuffer)
71
77
  .pipeThrough((0, __1.depacketizeTransformer)(codec, {
72
78
  waitForKeyframe: this.options.waitForKeyframe,
73
79
  isFinalPacketInSequence: (h) => h.marker,
@@ -76,7 +82,7 @@ class WebmFactory extends _1.MediaWriter {
76
82
  }
77
83
  else {
78
84
  rtpSource.readable
79
- .pipeThrough(jitterBuffer)
85
+ // .pipeThrough(jitterBuffer)
80
86
  .pipeThrough((0, __1.depacketizeTransformer)(codec))
81
87
  .pipeTo(webm.audioStream);
82
88
  }
@@ -101,6 +107,7 @@ class WebmFactory extends _1.MediaWriter {
101
107
  }
102
108
  async stop() {
103
109
  await Promise.all(this.rtpSources.map((r) => r.stop()));
110
+ this.unSubscribers.dispose();
104
111
  }
105
112
  }
106
113
  exports.WebmFactory = WebmFactory;
@@ -1 +1 @@
1
- {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../../src/nonstandard/recorder/writer/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, open, unlink } from \"fs/promises\";\nimport { ReadableStreamDefaultReadResult } from \"stream/web\";\n\nimport { SupportedCodec } from \"../../../../../rtp/src/container/webm\";\nimport {\n depacketizeTransformer,\n jitterBufferTransformer,\n MediaStreamTrack,\n RtpSourceStream,\n WebmStream,\n WebmStreamOutput,\n WeriftError,\n} from \"../../..\";\nimport { MediaWriter } from \".\";\n\nconst sourcePath = \"packages/webrtc/src/nonstandard/recorder/writer/webm.ts\";\n\nexport class WebmFactory extends MediaWriter {\n rtpSources: RtpSourceStream[] = [];\n\n async start(tracks: MediaStreamTrack[]) {\n await unlink(this.path).catch((e) => e);\n\n const inputTracks = tracks.map((track, i) => {\n const trackNumber = i + 1;\n const payloadType = track.codec!.payloadType;\n\n if (track.kind === \"video\") {\n const codec = ((): SupportedCodec => {\n switch (track.codec?.name.toLowerCase() as SupportedVideoCodec) {\n case \"vp8\":\n return \"VP8\";\n case \"vp9\":\n return \"VP9\";\n case \"h264\":\n return \"MPEG4/ISO/AVC\";\n case \"av1x\":\n return \"AV1\";\n default:\n throw new WeriftError({\n message: \"unsupported codec\",\n payload: { track, path: sourcePath },\n });\n }\n })();\n return {\n kind: \"video\" as const,\n codec,\n clockRate: 90000,\n trackNumber,\n width: this.options.width,\n height: this.options.height,\n payloadType,\n track,\n };\n } else {\n return {\n kind: \"audio\" as const,\n codec: \"OPUS\" as const,\n clockRate: 48000,\n trackNumber,\n payloadType,\n track,\n };\n }\n });\n\n const webm = new WebmStream(inputTracks, {\n duration: this.options.defaultDuration ?? 1000 * 60 * 60 * 24,\n });\n\n this.rtpSources = inputTracks.map(({ track, clockRate, codec }) => {\n const rtpSource = new RtpSourceStream();\n track.onReceiveRtp.subscribe((r) => rtpSource.push(r));\n\n const jitterBuffer = jitterBufferTransformer(clockRate, {\n latency: this.options.jitterBufferLatency,\n bufferSize: this.options.jitterBufferSize,\n });\n\n if (track.kind === \"video\") {\n rtpSource.readable\n .pipeThrough(jitterBuffer)\n .pipeThrough(\n depacketizeTransformer(codec, {\n waitForKeyframe: this.options.waitForKeyframe,\n isFinalPacketInSequence: (h) => h.marker,\n })\n )\n .pipeTo(webm.videoStream);\n } else {\n rtpSource.readable\n .pipeThrough(jitterBuffer)\n .pipeThrough(depacketizeTransformer(codec))\n .pipeTo(webm.audioStream);\n }\n\n return rtpSource;\n });\n\n const reader = webm.webmStream.getReader();\n const readChunk = async ({\n value,\n done,\n }: ReadableStreamDefaultReadResult<WebmStreamOutput>) => {\n if (done) return;\n\n if (value.saveToFile) {\n await appendFile(this.path, value.saveToFile);\n } else if (value.eol) {\n const { durationElement } = value.eol;\n const handler = await open(this.path, \"r+\");\n await handler.write(durationElement, 0, durationElement.length, 83);\n await handler.close();\n }\n reader.read().then(readChunk);\n };\n reader.read().then(readChunk);\n }\n\n async stop() {\n await Promise.all(this.rtpSources.map((r) => r.stop()));\n }\n}\n\nconst supportedVideoCodecs = [\"h264\", \"vp8\", \"vp9\", \"av1x\"] as const;\ntype SupportedVideoCodec = typeof supportedVideoCodecs[number];\n"]}
1
+ {"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../../src/nonstandard/recorder/writer/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, open, unlink } from \"fs/promises\";\nimport { EventDisposer } from \"rx.mini\";\nimport { ReadableStreamDefaultReadResult } from \"stream/web\";\n\nimport { SupportedCodec } from \"../../../../../rtp/src/container/webm\";\nimport {\n depacketizeTransformer,\n jitterBufferTransformer,\n MediaStreamTrack,\n RtpSourceStream,\n WebmStream,\n WebmStreamOutput,\n WeriftError,\n} from \"../../..\";\nimport { MediaWriter } from \".\";\n\nconst sourcePath = \"packages/webrtc/src/nonstandard/recorder/writer/webm.ts\";\n\nexport class WebmFactory extends MediaWriter {\n rtpSources: RtpSourceStream[] = [];\n\n unSubscribers = new EventDisposer();\n\n async start(tracks: MediaStreamTrack[]) {\n await unlink(this.path).catch((e) => e);\n\n const inputTracks = tracks.map((track, i) => {\n const trackNumber = i + 1;\n const payloadType = track.codec!.payloadType;\n\n if (track.kind === \"video\") {\n const codec = ((): SupportedCodec => {\n switch (track.codec?.name.toLowerCase() as SupportedVideoCodec) {\n case \"vp8\":\n return \"VP8\";\n case \"vp9\":\n return \"VP9\";\n case \"h264\":\n return \"MPEG4/ISO/AVC\";\n case \"av1x\":\n return \"AV1\";\n default:\n throw new WeriftError({\n message: \"unsupported codec\",\n payload: { track, path: sourcePath },\n });\n }\n })();\n return {\n kind: \"video\" as const,\n codec,\n clockRate: 90000,\n trackNumber,\n width: this.options.width,\n height: this.options.height,\n payloadType,\n track,\n };\n } else {\n return {\n kind: \"audio\" as const,\n codec: \"OPUS\" as const,\n clockRate: 48000,\n trackNumber,\n payloadType,\n track,\n };\n }\n });\n\n const webm = new WebmStream(inputTracks, {\n duration: this.options.defaultDuration ?? 1000 * 60 * 60 * 24,\n });\n\n this.rtpSources = inputTracks.map(({ track, clockRate, codec }) => {\n const rtpSource = new RtpSourceStream();\n\n track.onReceiveRtp\n .subscribe((rtp) => {\n rtpSource.push(rtp.clone());\n })\n .disposer(this.unSubscribers);\n\n // const jitterBuffer = jitterBufferTransformer(clockRate, {\n // latency: this.options.jitterBufferLatency,\n // bufferSize: this.options.jitterBufferSize,\n // });\n\n if (track.kind === \"video\") {\n rtpSource.readable\n // .pipeThrough(jitterBuffer)\n .pipeThrough(\n depacketizeTransformer(codec, {\n waitForKeyframe: this.options.waitForKeyframe,\n isFinalPacketInSequence: (h) => h.marker,\n })\n )\n .pipeTo(webm.videoStream);\n } else {\n rtpSource.readable\n // .pipeThrough(jitterBuffer)\n .pipeThrough(depacketizeTransformer(codec))\n .pipeTo(webm.audioStream);\n }\n\n return rtpSource;\n });\n\n const reader = webm.webmStream.getReader();\n const readChunk = async ({\n value,\n done,\n }: ReadableStreamDefaultReadResult<WebmStreamOutput>) => {\n if (done) return;\n\n if (value.saveToFile) {\n await appendFile(this.path, value.saveToFile);\n } else if (value.eol) {\n const { durationElement } = value.eol;\n const handler = await open(this.path, \"r+\");\n await handler.write(durationElement, 0, durationElement.length, 83);\n await handler.close();\n }\n reader.read().then(readChunk);\n };\n reader.read().then(readChunk);\n }\n\n async stop() {\n await Promise.all(this.rtpSources.map((r) => r.stop()));\n\n this.unSubscribers.dispose();\n }\n}\n\nconst supportedVideoCodecs = [\"h264\", \"vp8\", \"vp9\", \"av1x\"] as const;\ntype SupportedVideoCodec = typeof supportedVideoCodecs[number];\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "werift",
3
- "version": "0.17.5",
3
+ "version": "0.17.6",
4
4
  "description": "WebRTC Implementation for TypeScript (Node.js)",
5
5
  "keywords": [
6
6
  "WebRTC",
@@ -230,7 +230,9 @@ export class RTCRtpSender {
230
230
  this.stopped = true;
231
231
  this.rtcpRunning = false;
232
232
  this.rtcpCancel.abort();
233
-
233
+ if (this.disposeTrack) {
234
+ this.disposeTrack();
235
+ }
234
236
  this.track = undefined;
235
237
  }
236
238
 
@@ -1,4 +1,5 @@
1
1
  import { appendFile, open, unlink } from "fs/promises";
2
+ import { EventDisposer } from "rx.mini";
2
3
  import { ReadableStreamDefaultReadResult } from "stream/web";
3
4
 
4
5
  import { SupportedCodec } from "../../../../../rtp/src/container/webm";
@@ -18,6 +19,8 @@ const sourcePath = "packages/webrtc/src/nonstandard/recorder/writer/webm.ts";
18
19
  export class WebmFactory extends MediaWriter {
19
20
  rtpSources: RtpSourceStream[] = [];
20
21
 
22
+ unSubscribers = new EventDisposer();
23
+
21
24
  async start(tracks: MediaStreamTrack[]) {
22
25
  await unlink(this.path).catch((e) => e);
23
26
 
@@ -71,16 +74,21 @@ export class WebmFactory extends MediaWriter {
71
74
 
72
75
  this.rtpSources = inputTracks.map(({ track, clockRate, codec }) => {
73
76
  const rtpSource = new RtpSourceStream();
74
- track.onReceiveRtp.subscribe((r) => rtpSource.push(r));
75
77
 
76
- const jitterBuffer = jitterBufferTransformer(clockRate, {
77
- latency: this.options.jitterBufferLatency,
78
- bufferSize: this.options.jitterBufferSize,
79
- });
78
+ track.onReceiveRtp
79
+ .subscribe((rtp) => {
80
+ rtpSource.push(rtp.clone());
81
+ })
82
+ .disposer(this.unSubscribers);
83
+
84
+ // const jitterBuffer = jitterBufferTransformer(clockRate, {
85
+ // latency: this.options.jitterBufferLatency,
86
+ // bufferSize: this.options.jitterBufferSize,
87
+ // });
80
88
 
81
89
  if (track.kind === "video") {
82
90
  rtpSource.readable
83
- .pipeThrough(jitterBuffer)
91
+ // .pipeThrough(jitterBuffer)
84
92
  .pipeThrough(
85
93
  depacketizeTransformer(codec, {
86
94
  waitForKeyframe: this.options.waitForKeyframe,
@@ -90,7 +98,7 @@ export class WebmFactory extends MediaWriter {
90
98
  .pipeTo(webm.videoStream);
91
99
  } else {
92
100
  rtpSource.readable
93
- .pipeThrough(jitterBuffer)
101
+ // .pipeThrough(jitterBuffer)
94
102
  .pipeThrough(depacketizeTransformer(codec))
95
103
  .pipeTo(webm.audioStream);
96
104
  }
@@ -120,6 +128,8 @@ export class WebmFactory extends MediaWriter {
120
128
 
121
129
  async stop() {
122
130
  await Promise.all(this.rtpSources.map((r) => r.stop()));
131
+
132
+ this.unSubscribers.dispose();
123
133
  }
124
134
  }
125
135