werift 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/lib/common/src/transport.d.ts +22 -9
- package/lib/common/src/transport.js +152 -25
- package/lib/common/src/transport.js.map +1 -1
- package/lib/ice/src/candidate.d.ts +16 -1
- package/lib/ice/src/candidate.js +99 -15
- package/lib/ice/src/candidate.js.map +1 -1
- package/lib/ice/src/ice.d.ts +2 -0
- package/lib/ice/src/ice.js +171 -41
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +23 -2
- package/lib/ice/src/iceBase.js +63 -1
- package/lib/ice/src/iceBase.js.map +1 -1
- package/lib/ice/src/index.d.ts +2 -0
- package/lib/ice/src/index.js +2 -0
- package/lib/ice/src/index.js.map +1 -1
- package/lib/ice/src/stun/const.d.ts +1 -26
- package/lib/ice/src/stun/const.js +15 -54
- package/lib/ice/src/stun/const.js.map +1 -1
- package/lib/ice/src/stun/message.d.ts +1 -25
- package/lib/ice/src/stun/message.js +15 -149
- package/lib/ice/src/stun/message.js.map +1 -1
- package/lib/ice/src/stun/protocol.d.ts +1 -1
- package/lib/ice/src/stun/protocol.js +2 -2
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
- package/lib/ice/src/stun/tcpFrame.js +26 -0
- package/lib/ice/src/stun/tcpFrame.js.map +1 -0
- package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
- package/lib/ice/src/stun/tcpProtocol.js +326 -0
- package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
- package/lib/ice/src/stun/transaction.d.ts +2 -1
- package/lib/ice/src/stun/transaction.js +9 -3
- package/lib/ice/src/stun/transaction.js.map +1 -1
- package/lib/ice/src/turn/frame.d.ts +1 -0
- package/lib/ice/src/turn/frame.js +18 -0
- package/lib/ice/src/turn/frame.js.map +1 -0
- package/lib/ice/src/turn/protocol.d.ts +9 -7
- package/lib/ice/src/turn/protocol.js +32 -44
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/types/model.d.ts +1 -1
- package/lib/ice/src/types/model.js.map +1 -1
- package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
- package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
- package/lib/ice-server/src/stun/attributes.js.map +1 -0
- package/lib/ice-server/src/stun/const.d.ts +28 -0
- package/lib/ice-server/src/stun/const.js +88 -0
- package/lib/ice-server/src/stun/const.js.map +1 -0
- package/lib/ice-server/src/stun/message.d.ts +37 -0
- package/lib/ice-server/src/stun/message.js +190 -0
- package/lib/ice-server/src/stun/message.js.map +1 -0
- package/lib/ice-server/src/turn/auth.d.ts +1 -0
- package/lib/ice-server/src/turn/auth.js +10 -0
- package/lib/ice-server/src/turn/auth.js.map +1 -0
- package/lib/ice-server/src/turn/frame.d.ts +13 -0
- package/lib/ice-server/src/turn/frame.js +69 -0
- package/lib/ice-server/src/turn/frame.js.map +1 -0
- package/lib/index.mjs +2688 -855
- package/lib/nonstandard/index.mjs +1753 -403
- package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
- package/lib/rtp/src/extra/container/mp4/container.js +258 -173
- package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
- package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
- package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
- package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
- package/lib/rtp/src/extra/processor/mp4.js +115 -60
- package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
- package/lib/webrtc/src/dataChannel.d.ts +3 -2
- package/lib/webrtc/src/dataChannel.js +9 -2
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/errors.d.ts +3 -0
- package/lib/webrtc/src/errors.js +11 -0
- package/lib/webrtc/src/errors.js.map +1 -0
- package/lib/webrtc/src/helper.d.ts +5 -1
- package/lib/webrtc/src/helper.js +33 -1
- package/lib/webrtc/src/helper.js.map +1 -1
- package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
- package/lib/webrtc/src/media/receiver/statistics.js +22 -0
- package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
- package/lib/webrtc/src/media/rtpReceiver.js +135 -20
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
- package/lib/webrtc/src/media/rtpSender.js +177 -28
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
- package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/stats.d.ts +15 -1
- package/lib/webrtc/src/media/stats.js +55 -1
- package/lib/webrtc/src/media/stats.js.map +1 -1
- package/lib/webrtc/src/media/track.d.ts +2 -1
- package/lib/webrtc/src/media/track.js +7 -1
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
- package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
- package/lib/webrtc/src/nonstandard/navigator.js +96 -32
- package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
- package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +183 -50
- package/lib/webrtc/src/peerConnection.js +458 -109
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +1 -1
- package/lib/webrtc/src/sctpManager.js +27 -7
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +10 -7
- package/lib/webrtc/src/sdp.js +39 -9
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +4 -3
- package/lib/webrtc/src/sdpManager.js +50 -27
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
- package/lib/webrtc/src/secureTransportManager.js +100 -22
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.d.ts +5 -4
- package/lib/webrtc/src/transceiverManager.js +61 -62
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.d.ts +15 -4
- package/lib/webrtc/src/transport/dtls.js +91 -23
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +21 -3
- package/lib/webrtc/src/transport/ice.js +159 -30
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +1 -0
- package/lib/webrtc/src/transport/sctp.js +9 -6
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +12 -4
- package/lib/webrtc/src/utils.js +118 -16
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +7 -4
- package/lib/ice/src/stun/attributes.js.map +0 -1
- package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
- package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
- package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
|
@@ -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 \"../../../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\n const buffer = new ArrayBuffer(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 {\n EncodedAudioPacketSource,\n EncodedPacket,\n EncodedVideoPacketSource,\n Mp4OutputFormat,\n NullTarget,\n Output,\n} from \"mediabunny\";\nimport { Event } from \"../../../imports/common\";\n\ntype DecoderConfig = AudioDecoderConfig | VideoDecoderConfig;\ntype EncodedChunk = EncodedAudioChunk | EncodedVideoChunk;\ntype TrackKind = \"audio\" | \"video\";\n\ninterface AudioChunkMetadata {\n decoderConfig: {\n codec: \"opus\";\n description?: Uint8Array;\n numberOfChannels: number;\n sampleRate: number;\n };\n}\n\ninterface VideoChunkMetadata {\n decoderConfig: {\n codec: string;\n codedHeight: number;\n codedWidth: number;\n description?: Uint8Array;\n displayAspectHeight?: number;\n displayAspectWidth?: number;\n };\n}\n\ninterface FragmentMeta {\n duration: number;\n kind: TrackKind;\n timestamp: number;\n type: DataType;\n}\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 #audioFrame?: (EncodedChunk & { track: TrackKind }) | undefined;\n #audioMeta?: AudioChunkMetadata;\n #audioSource?: EncodedAudioPacketSource;\n #currentFragment?: FragmentMeta;\n #ftyp?: Uint8Array;\n #initializationEmitted = false;\n #lastAudioDuration = 0;\n #lastMoof?: Uint8Array;\n #lastMoofTimestamp = 0;\n #lastVideoDuration = 0;\n #moov?: Uint8Array;\n #onDataOperation = Promise.resolve();\n #operation = Promise.resolve();\n #output?: Output<Mp4OutputFormat, NullTarget> | undefined;\n #startPromise?: Promise<void>;\n #stopPromise?: Promise<void>;\n #stopped = false;\n #videoFrame?: (EncodedChunk & { track: TrackKind }) | undefined;\n #videoMeta?: VideoChunkMetadata;\n #videoSource?: EncodedVideoPacketSource;\n audioTrack?: number;\n frameBuffer: (EncodedChunk & {\n track: TrackKind;\n })[] = [];\n onData = new Event<[Mp4Data | { eol: true }]>();\n videoTrack?: number;\n\n constructor(\n private props: {\n track: { audio: boolean; video: boolean };\n },\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: TrackKind;\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: TrackKind;\n },\n ) {\n if (frame.track === \"audio\") {\n if (isVideoConfig(frame)) {\n throw new Error(\"audio track requires an audio decoder config\");\n }\n if (frame.codec !== \"opus\") {\n throw new Error(`unsupported codec: ${frame.codec}`);\n }\n this.#audioMeta = {\n decoderConfig: {\n codec: \"opus\",\n description:\n frame.description != undefined\n ? new Uint8Array(frame.description)\n : undefined,\n numberOfChannels: frame.numberOfChannels,\n sampleRate: frame.sampleRate,\n },\n };\n this.audioTrack = 1;\n } else {\n if (!isVideoConfig(frame)) {\n throw new Error(\"video track requires a video decoder config\");\n }\n if (!frame.codec.startsWith(\"avc1\")) {\n throw new Error(`unsupported codec: ${frame.codec}`);\n }\n if (frame.codedWidth == undefined || frame.codedHeight == undefined) {\n throw new Error(\"missing coded video dimensions\");\n }\n this.#videoMeta = {\n decoderConfig: {\n codec: frame.codec,\n codedHeight: frame.codedHeight,\n codedWidth: frame.codedWidth,\n description:\n frame.description != undefined\n ? new Uint8Array(frame.description)\n : undefined,\n displayAspectHeight: frame.displayAspectHeight,\n displayAspectWidth: frame.displayAspectWidth,\n },\n };\n this.videoTrack = this.props.track.audio ? 2 : 1;\n }\n\n if (!this.tracksReady) {\n return;\n }\n\n void this.#enqueueOperation(async () => {\n await this.#ensureOutputStarted();\n await this.#drainFrameBuffer();\n });\n }\n\n #enqueue(\n frame: EncodedChunk & {\n track: TrackKind;\n },\n ) {\n this.frameBuffer.push(frame);\n if (!this.tracksReady) {\n return;\n }\n void this.#enqueueOperation(async () => {\n await this.#ensureOutputStarted();\n await this.#drainFrameBuffer();\n });\n }\n\n stop() {\n if (this.#stopPromise) {\n return this.#stopPromise;\n }\n\n this.#stopped = true;\n this.#stopPromise = this.#enqueueOperation(async () => {\n if (!this.tracksReady) {\n this.frameBuffer = [];\n return;\n }\n\n await this.#ensureOutputStarted();\n await this.#drainFrameBuffer();\n await this.#flushPendingFrame(\"audio\");\n await this.#flushPendingFrame(\"video\");\n\n this.#audioSource?.close();\n this.#videoSource?.close();\n if (this.#output) {\n await this.#output.finalize();\n }\n await this.#flushOnData();\n });\n return this.#stopPromise;\n }\n\n async #drainFrameBuffer() {\n const frames = this.frameBuffer;\n this.frameBuffer = [];\n\n for (const frame of frames) {\n await this.#processFrame(frame);\n }\n }\n\n async #ensureOutputStarted() {\n if (this.#startPromise) {\n await this.#startPromise;\n return;\n }\n if (!this.tracksReady) {\n return;\n }\n\n const output = new Output({\n format: new Mp4OutputFormat({\n fastStart: \"fragmented\",\n minimumFragmentDuration: 0,\n onFtyp: (data) => {\n this.#ftyp = copyBytes(data);\n },\n onMdat: (data) => {\n if (!this.#lastMoof) {\n throw new Error(\"moof missing before mdat\");\n }\n\n const fragment = this.#currentFragment;\n const timestamp = fragment\n ? fragment.timestamp\n : Math.round(this.#lastMoofTimestamp * 1_000_000);\n const duration = fragment?.duration ?? 0;\n const kind = fragment?.kind ?? this.#defaultKind();\n const type = fragment?.type ?? \"key\";\n const segment = concatBytes(this.#lastMoof, data);\n\n this.#currentFragment = undefined;\n this.#lastMoof = undefined;\n\n void this.#emitData({\n type,\n timestamp,\n duration,\n data: segment,\n kind,\n });\n },\n onMoof: (data, _position, timestamp) => {\n this.#lastMoof = copyBytes(data);\n this.#lastMoofTimestamp = timestamp;\n },\n onMoov: (data) => {\n this.#moov = copyBytes(data);\n this.#emitInitializationSegment();\n },\n }),\n target: new NullTarget(),\n });\n\n if (this.#audioMeta) {\n this.#audioSource = new EncodedAudioPacketSource(\"opus\");\n output.addAudioTrack(this.#audioSource);\n }\n if (this.#videoMeta) {\n this.#videoSource = new EncodedVideoPacketSource(\"avc\");\n output.addVideoTrack(this.#videoSource);\n }\n\n this.#output = output;\n this.#startPromise = output.start();\n await this.#startPromise;\n }\n\n #emitInitializationSegment() {\n if (this.#initializationEmitted || !this.#ftyp || !this.#moov) {\n return;\n }\n\n this.#initializationEmitted = true;\n void this.#emitData({\n type: \"init\",\n timestamp: 0,\n duration: 0,\n data: concatBytes(this.#ftyp, this.#moov),\n kind: this.#defaultKind(),\n });\n }\n\n #emitData(data: Mp4Data | { eol: true }) {\n const next = this.#onDataOperation.then(() => this.onData.execute(data));\n this.#onDataOperation = next;\n return next;\n }\n\n async #flushOnData() {\n await this.#onDataOperation;\n }\n\n #enqueueOperation(operation: () => Promise<void>) {\n const next = this.#operation.then(operation);\n this.#operation = next;\n return next;\n }\n\n #defaultKind(): TrackKind {\n return this.props.track.video ? \"video\" : \"audio\";\n }\n\n async #flushPendingFrame(track: TrackKind) {\n const buffered = track === \"audio\" ? this.#audioFrame : this.#videoFrame;\n if (!buffered) {\n return;\n }\n\n const duration =\n track === \"audio\" ? this.#lastAudioDuration : this.#lastVideoDuration;\n await this.#writePacket(buffered, duration);\n\n if (track === \"audio\") {\n this.#audioFrame = undefined;\n } else {\n this.#videoFrame = undefined;\n }\n }\n\n async #processFrame(\n frame: EncodedChunk & {\n track: TrackKind;\n },\n ) {\n const buffered =\n frame.track === \"audio\" ? this.#audioFrame : this.#videoFrame;\n if (!buffered) {\n if (frame.track === \"audio\") {\n this.#audioFrame = frame;\n } else {\n this.#videoFrame = frame;\n }\n return;\n }\n\n const duration = Math.max(frame.timestamp - buffered.timestamp, 0);\n await this.#writePacket(buffered, duration);\n\n if (frame.track === \"audio\") {\n this.#audioFrame = frame;\n this.#lastAudioDuration = duration;\n } else {\n this.#videoFrame = frame;\n this.#lastVideoDuration = duration;\n }\n }\n\n async #writePacket(\n frame: EncodedChunk & {\n track: TrackKind;\n },\n duration: number,\n ) {\n const data = new Uint8Array(frame.byteLength);\n frame.copyTo(data.buffer);\n\n const packet = new EncodedPacket(\n data,\n frame.type,\n frame.timestamp / 1_000_000,\n duration / 1_000_000,\n );\n\n if (frame.track === \"audio\") {\n if (!this.#audioSource || !this.#audioMeta) {\n throw new Error(\"audio track missing\");\n }\n\n await this.#audioSource.add(packet, this.#audioMeta);\n } else {\n if (!this.#videoSource || !this.#videoMeta) {\n throw new Error(\"video track missing\");\n }\n\n await this.#videoSource.add(packet, this.#videoMeta);\n }\n\n this.#rememberFragmentPacket(\n frame.track,\n frame.type,\n frame.timestamp,\n duration,\n );\n }\n\n #rememberFragmentPacket(\n kind: TrackKind,\n type: EncodedChunk[\"type\"],\n timestamp: number,\n duration: number,\n ) {\n const end = timestamp + duration;\n if (!this.#currentFragment) {\n this.#currentFragment = {\n kind,\n type,\n timestamp,\n duration,\n };\n return;\n }\n\n if (kind === \"video\" && type === \"key\") {\n this.#currentFragment.type = \"key\";\n }\n\n const fragmentEnd = Math.max(\n this.#currentFragment.timestamp + this.#currentFragment.duration,\n end,\n );\n this.#currentFragment.duration =\n fragmentEnd - this.#currentFragment.timestamp;\n }\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\nfunction concatBytes(...parts: Uint8Array[]) {\n const size = parts.reduce((sum, part) => sum + part.byteLength, 0);\n const combined = new Uint8Array(size);\n let offset = 0;\n\n for (const part of parts) {\n combined.set(part, offset);\n offset += part.byteLength;\n }\n\n return combined;\n}\n\nfunction copyBytes(data: Uint8Array) {\n return new Uint8Array(data);\n}\n"]}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.AVCDecoderConfigurationRecord = exports.H264AnnexBParser = exports.H264NaluAVC1 = exports.H264NaluPayload = exports.H264NaluType = void 0;
|
|
7
7
|
exports.annexb2avcc = annexb2avcc;
|
|
8
|
+
exports.annexb2avcSample = annexb2avcSample;
|
|
8
9
|
const sps_parser_1 = __importDefault(require("./sps-parser"));
|
|
9
10
|
var H264NaluType;
|
|
10
11
|
(function (H264NaluType) {
|
|
@@ -237,4 +238,16 @@ function annexb2avcc(data) {
|
|
|
237
238
|
const avcc = new AVCDecoderConfigurationRecord(sps_without_header, pps_without_header, details);
|
|
238
239
|
return avcc.getData();
|
|
239
240
|
}
|
|
241
|
+
function annexb2avcSample(data) {
|
|
242
|
+
const annexbParser = new H264AnnexBParser(data);
|
|
243
|
+
const nalUnits = [];
|
|
244
|
+
let naluPayload = null;
|
|
245
|
+
while ((naluPayload = annexbParser.readNextNaluPayload()) != null) {
|
|
246
|
+
nalUnits.push(Buffer.from(new H264NaluAVC1(naluPayload).data));
|
|
247
|
+
}
|
|
248
|
+
if (nalUnits.length === 0) {
|
|
249
|
+
throw new Error("annexb sample does not contain nal units");
|
|
250
|
+
}
|
|
251
|
+
return Buffer.concat(nalUnits);
|
|
252
|
+
}
|
|
240
253
|
//# sourceMappingURL=h264.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"h264.js","sourceRoot":"","sources":["../../../../../../../rtp/src/extra/container/mp4/h264.ts"],"names":[],"mappings":"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","sourcesContent":["import SPSParser from \"./sps-parser\";\n\nexport enum H264NaluType {\n kUnspecified = 0,\n kSliceNonIDR = 1,\n kSliceDPA = 2,\n kSliceDPB = 3,\n kSliceDPC = 4,\n kSliceIDR = 5,\n kSliceSEI = 6,\n kSliceSPS = 7,\n kSlicePPS = 8,\n kSliceAUD = 9,\n kEndOfSequence = 10,\n kEndOfStream = 11,\n kFiller = 12,\n kSPSExt = 13,\n kReserved0 = 14,\n}\n\nexport class H264NaluPayload {\n type!: H264NaluType;\n data!: Uint8Array;\n}\n\nexport class H264NaluAVC1 {\n type: H264NaluType;\n data: Uint8Array;\n\n constructor(nalu: H264NaluPayload) {\n const nalu_size = nalu.data.byteLength;\n\n this.type = nalu.type;\n this.data = new Uint8Array(4 + nalu_size); // 4 byte length-header + nalu payload\n\n const v = new DataView(this.data.buffer);\n // Fill 4 byte length-header\n v.setUint32(0, nalu_size);\n // Copy payload\n this.data.set(nalu.data, 4);\n }\n}\n\nexport class H264AnnexBParser {\n private readonly TAG: string = \"H264AnnexBParser\";\n\n private data_: Uint8Array;\n private current_startcode_offset_: number = 0;\n private eof_flag_: boolean = false;\n\n public constructor(data: Uint8Array) {\n this.data_ = data;\n this.current_startcode_offset_ = this.findNextStartCodeOffset(0);\n }\n\n private findNextStartCodeOffset(start_offset: number) {\n let i = start_offset;\n const data = this.data_;\n\n for (;;) {\n if (i + 3 >= data.byteLength) {\n this.eof_flag_ = true;\n return data.byteLength;\n }\n\n // search 00 00 00 01 or 00 00 01\n const uint32 =\n (data[i + 0] << 24) |\n (data[i + 1] << 16) |\n (data[i + 2] << 8) |\n data[i + 3];\n const uint24 = (data[i + 0] << 16) | (data[i + 1] << 8) | data[i + 2];\n if (uint32 === 0x00000001 || uint24 === 0x000001) {\n return i;\n } else {\n i++;\n }\n }\n }\n\n public readNextNaluPayload(): H264NaluPayload | null {\n const data = this.data_;\n let nalu_payload: H264NaluPayload | null = null;\n\n while (nalu_payload == null) {\n if (this.eof_flag_) {\n break;\n }\n // offset pointed to start code\n const startcode_offset = this.current_startcode_offset_;\n\n // nalu payload start offset\n let offset = startcode_offset;\n const u32 =\n (data[offset] << 24) |\n (data[offset + 1] << 16) |\n (data[offset + 2] << 8) |\n data[offset + 3];\n if (u32 === 0x00000001) {\n offset += 4;\n } else {\n offset += 3;\n }\n\n const nalu_type: H264NaluType = data[offset] & 0x1f;\n const forbidden_bit = (data[offset] & 0x80) >>> 7;\n\n const next_startcode_offset = this.findNextStartCodeOffset(offset);\n this.current_startcode_offset_ = next_startcode_offset;\n\n if (nalu_type >= H264NaluType.kReserved0) {\n continue;\n }\n if (forbidden_bit !== 0) {\n // Log.e(this.TAG, `forbidden_bit near offset ${offset} should be 0 but has value ${forbidden_bit}`);\n continue;\n }\n\n const payload_data = data.subarray(offset, next_startcode_offset);\n\n nalu_payload = new H264NaluPayload();\n nalu_payload.type = nalu_type;\n nalu_payload.data = payload_data;\n }\n\n return nalu_payload;\n }\n}\n\nexport class AVCDecoderConfigurationRecord {\n private data: Uint8Array;\n\n // sps, pps: require Nalu without 4 byte length-header\n public constructor(sps: Uint8Array, pps: Uint8Array, sps_details: any) {\n let length = 6 + 2 + sps.byteLength + 1 + 2 + pps.byteLength;\n let need_extra_fields = false;\n\n if (sps[3] !== 66 && sps[3] !== 77 && sps[3] !== 88) {\n need_extra_fields = true;\n length += 4;\n }\n\n const data = (this.data = new Uint8Array(length));\n\n data[0] = 0x01; // configurationVersion\n data[1] = sps[1]; // AVCProfileIndication\n data[2] = sps[2]; // profile_compatibility\n data[3] = sps[3]; // AVCLevelIndication\n data[4] = 0xff; // 111111 + lengthSizeMinusOne(3)\n\n data[5] = 0xe0 | 0x01; // 111 + numOfSequenceParameterSets\n\n const sps_length = sps.byteLength;\n data[6] = sps_length >>> 8; // sequenceParameterSetLength\n data[7] = sps_length & 0xff;\n\n let offset = 8;\n data.set(sps, 8);\n offset += sps_length;\n\n data[offset] = 1; // numOfPictureParameterSets\n\n const pps_length = pps.byteLength;\n data[offset + 1] = pps_length >>> 8; // pictureParameterSetLength\n data[offset + 2] = pps_length & 0xff;\n\n data.set(pps, offset + 3);\n offset += 3 + pps_length;\n\n if (need_extra_fields) {\n data[offset] = 0xfc | sps_details.chroma_format_idc;\n data[offset + 1] = 0xf8 | (sps_details.bit_depth_luma - 8);\n data[offset + 2] = 0xf8 | (sps_details.bit_depth_chroma - 8);\n data[offset + 3] = 0x00; // number of sps ext\n offset += 4;\n }\n }\n\n public getData() {\n return this.data;\n }\n}\n\nexport function annexb2avcc(data: Buffer) {\n const annexb_parser = new H264AnnexBParser(data);\n let nalu_payload: H264NaluPayload | null = null;\n const video_init_segment_dispatched_ = false;\n const video_metadata_changed_ = false;\n\n const video_metadata_: {\n sps: H264NaluAVC1 | undefined;\n pps: H264NaluAVC1 | undefined;\n details: any;\n } = {\n sps: undefined,\n pps: undefined,\n details: undefined,\n };\n\n while ((nalu_payload = annexb_parser.readNextNaluPayload()) != null) {\n const nalu_avc1 = new H264NaluAVC1(nalu_payload);\n\n if (nalu_avc1.type === H264NaluType.kSliceSPS) {\n // Notice: parseSPS requires Nalu without startcode or length-header\n const details = SPSParser.parseSPS(nalu_payload.data);\n if (!video_init_segment_dispatched_) {\n video_metadata_.sps = nalu_avc1;\n video_metadata_.details = details;\n }\n } else if (nalu_avc1.type === H264NaluType.kSlicePPS) {\n if (!video_init_segment_dispatched_ || video_metadata_changed_) {\n video_metadata_.pps = nalu_avc1;\n }\n }\n }\n\n const sps_without_header = video_metadata_.sps!.data.subarray(4);\n const pps_without_header = video_metadata_.pps!.data.subarray(4);\n const details = video_metadata_.details;\n const avcc = new AVCDecoderConfigurationRecord(\n sps_without_header,\n pps_without_header,\n details,\n );\n return avcc.getData();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"h264.js","sourceRoot":"","sources":["../../../../../../../rtp/src/extra/container/mp4/h264.ts"],"names":[],"mappings":"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","sourcesContent":["import SPSParser from \"./sps-parser\";\n\nexport enum H264NaluType {\n kUnspecified = 0,\n kSliceNonIDR = 1,\n kSliceDPA = 2,\n kSliceDPB = 3,\n kSliceDPC = 4,\n kSliceIDR = 5,\n kSliceSEI = 6,\n kSliceSPS = 7,\n kSlicePPS = 8,\n kSliceAUD = 9,\n kEndOfSequence = 10,\n kEndOfStream = 11,\n kFiller = 12,\n kSPSExt = 13,\n kReserved0 = 14,\n}\n\nexport class H264NaluPayload {\n type!: H264NaluType;\n data!: Uint8Array;\n}\n\nexport class H264NaluAVC1 {\n type: H264NaluType;\n data: Uint8Array;\n\n constructor(nalu: H264NaluPayload) {\n const nalu_size = nalu.data.byteLength;\n\n this.type = nalu.type;\n this.data = new Uint8Array(4 + nalu_size); // 4 byte length-header + nalu payload\n\n const v = new DataView(this.data.buffer);\n // Fill 4 byte length-header\n v.setUint32(0, nalu_size);\n // Copy payload\n this.data.set(nalu.data, 4);\n }\n}\n\nexport class H264AnnexBParser {\n private readonly TAG: string = \"H264AnnexBParser\";\n\n private data_: Uint8Array;\n private current_startcode_offset_: number = 0;\n private eof_flag_: boolean = false;\n\n public constructor(data: Uint8Array) {\n this.data_ = data;\n this.current_startcode_offset_ = this.findNextStartCodeOffset(0);\n }\n\n private findNextStartCodeOffset(start_offset: number) {\n let i = start_offset;\n const data = this.data_;\n\n for (;;) {\n if (i + 3 >= data.byteLength) {\n this.eof_flag_ = true;\n return data.byteLength;\n }\n\n // search 00 00 00 01 or 00 00 01\n const uint32 =\n (data[i + 0] << 24) |\n (data[i + 1] << 16) |\n (data[i + 2] << 8) |\n data[i + 3];\n const uint24 = (data[i + 0] << 16) | (data[i + 1] << 8) | data[i + 2];\n if (uint32 === 0x00000001 || uint24 === 0x000001) {\n return i;\n } else {\n i++;\n }\n }\n }\n\n public readNextNaluPayload(): H264NaluPayload | null {\n const data = this.data_;\n let nalu_payload: H264NaluPayload | null = null;\n\n while (nalu_payload == null) {\n if (this.eof_flag_) {\n break;\n }\n // offset pointed to start code\n const startcode_offset = this.current_startcode_offset_;\n\n // nalu payload start offset\n let offset = startcode_offset;\n const u32 =\n (data[offset] << 24) |\n (data[offset + 1] << 16) |\n (data[offset + 2] << 8) |\n data[offset + 3];\n if (u32 === 0x00000001) {\n offset += 4;\n } else {\n offset += 3;\n }\n\n const nalu_type: H264NaluType = data[offset] & 0x1f;\n const forbidden_bit = (data[offset] & 0x80) >>> 7;\n\n const next_startcode_offset = this.findNextStartCodeOffset(offset);\n this.current_startcode_offset_ = next_startcode_offset;\n\n if (nalu_type >= H264NaluType.kReserved0) {\n continue;\n }\n if (forbidden_bit !== 0) {\n // Log.e(this.TAG, `forbidden_bit near offset ${offset} should be 0 but has value ${forbidden_bit}`);\n continue;\n }\n\n const payload_data = data.subarray(offset, next_startcode_offset);\n\n nalu_payload = new H264NaluPayload();\n nalu_payload.type = nalu_type;\n nalu_payload.data = payload_data;\n }\n\n return nalu_payload;\n }\n}\n\nexport class AVCDecoderConfigurationRecord {\n private data: Uint8Array;\n\n // sps, pps: require Nalu without 4 byte length-header\n public constructor(sps: Uint8Array, pps: Uint8Array, sps_details: any) {\n let length = 6 + 2 + sps.byteLength + 1 + 2 + pps.byteLength;\n let need_extra_fields = false;\n\n if (sps[3] !== 66 && sps[3] !== 77 && sps[3] !== 88) {\n need_extra_fields = true;\n length += 4;\n }\n\n const data = (this.data = new Uint8Array(length));\n\n data[0] = 0x01; // configurationVersion\n data[1] = sps[1]; // AVCProfileIndication\n data[2] = sps[2]; // profile_compatibility\n data[3] = sps[3]; // AVCLevelIndication\n data[4] = 0xff; // 111111 + lengthSizeMinusOne(3)\n\n data[5] = 0xe0 | 0x01; // 111 + numOfSequenceParameterSets\n\n const sps_length = sps.byteLength;\n data[6] = sps_length >>> 8; // sequenceParameterSetLength\n data[7] = sps_length & 0xff;\n\n let offset = 8;\n data.set(sps, 8);\n offset += sps_length;\n\n data[offset] = 1; // numOfPictureParameterSets\n\n const pps_length = pps.byteLength;\n data[offset + 1] = pps_length >>> 8; // pictureParameterSetLength\n data[offset + 2] = pps_length & 0xff;\n\n data.set(pps, offset + 3);\n offset += 3 + pps_length;\n\n if (need_extra_fields) {\n data[offset] = 0xfc | sps_details.chroma_format_idc;\n data[offset + 1] = 0xf8 | (sps_details.bit_depth_luma - 8);\n data[offset + 2] = 0xf8 | (sps_details.bit_depth_chroma - 8);\n data[offset + 3] = 0x00; // number of sps ext\n offset += 4;\n }\n }\n\n public getData() {\n return this.data;\n }\n}\n\nexport function annexb2avcc(data: Buffer) {\n const annexb_parser = new H264AnnexBParser(data);\n let nalu_payload: H264NaluPayload | null = null;\n const video_init_segment_dispatched_ = false;\n const video_metadata_changed_ = false;\n\n const video_metadata_: {\n sps: H264NaluAVC1 | undefined;\n pps: H264NaluAVC1 | undefined;\n details: any;\n } = {\n sps: undefined,\n pps: undefined,\n details: undefined,\n };\n\n while ((nalu_payload = annexb_parser.readNextNaluPayload()) != null) {\n const nalu_avc1 = new H264NaluAVC1(nalu_payload);\n\n if (nalu_avc1.type === H264NaluType.kSliceSPS) {\n // Notice: parseSPS requires Nalu without startcode or length-header\n const details = SPSParser.parseSPS(nalu_payload.data);\n if (!video_init_segment_dispatched_) {\n video_metadata_.sps = nalu_avc1;\n video_metadata_.details = details;\n }\n } else if (nalu_avc1.type === H264NaluType.kSlicePPS) {\n if (!video_init_segment_dispatched_ || video_metadata_changed_) {\n video_metadata_.pps = nalu_avc1;\n }\n }\n }\n\n const sps_without_header = video_metadata_.sps!.data.subarray(4);\n const pps_without_header = video_metadata_.pps!.data.subarray(4);\n const details = video_metadata_.details;\n const avcc = new AVCDecoderConfigurationRecord(\n sps_without_header,\n pps_without_header,\n details,\n );\n return avcc.getData();\n}\n\nexport function annexb2avcSample(data: Buffer) {\n const annexbParser = new H264AnnexBParser(data);\n const nalUnits: Buffer[] = [];\n let naluPayload: H264NaluPayload | null = null;\n\n while ((naluPayload = annexbParser.readNextNaluPayload()) != null) {\n nalUnits.push(Buffer.from(new H264NaluAVC1(naluPayload).data));\n }\n\n if (nalUnits.length === 0) {\n throw new Error(\"annexb sample does not contain nal units\");\n }\n\n return Buffer.concat(nalUnits);\n}\n"]}
|
|
@@ -10,14 +10,16 @@ export type Mp4Input = {
|
|
|
10
10
|
};
|
|
11
11
|
eol?: boolean;
|
|
12
12
|
};
|
|
13
|
-
export
|
|
13
|
+
export type Mp4Output = {
|
|
14
14
|
type: DataType;
|
|
15
15
|
timestamp: number;
|
|
16
16
|
duration: number;
|
|
17
17
|
data: Uint8Array;
|
|
18
|
-
eol?:
|
|
18
|
+
eol?: false | undefined;
|
|
19
19
|
kind: "audio" | "video";
|
|
20
|
-
}
|
|
20
|
+
} | {
|
|
21
|
+
eol: true;
|
|
22
|
+
};
|
|
21
23
|
export interface MP4Option {
|
|
22
24
|
/**ms */
|
|
23
25
|
duration?: number;
|
|
@@ -28,16 +30,18 @@ export declare class MP4Base implements AVProcessor<Mp4Input> {
|
|
|
28
30
|
tracks: Track[];
|
|
29
31
|
private output;
|
|
30
32
|
private options;
|
|
33
|
+
audioStopped: boolean;
|
|
31
34
|
private internalStats;
|
|
32
35
|
private container;
|
|
33
36
|
stopped: boolean;
|
|
34
37
|
onStopped: Event<any[]>;
|
|
35
|
-
|
|
38
|
+
videoStopped: boolean;
|
|
39
|
+
constructor(tracks: Track[], output: (output: Mp4Output) => void | Promise<void>, options?: MP4Option);
|
|
36
40
|
toJSON(): Record<string, any>;
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
processVideoInput: ({ eol, frame }: Mp4Input) => void;
|
|
42
|
+
processAudioInput: ({ eol, frame }: Mp4Input) => void;
|
|
39
43
|
protected start(): void;
|
|
40
|
-
stop(): void
|
|
44
|
+
stop(): Promise<void>;
|
|
41
45
|
}
|
|
42
46
|
export interface Track {
|
|
43
47
|
width?: number;
|
|
@@ -24,6 +24,12 @@ class MP4Base {
|
|
|
24
24
|
writable: true,
|
|
25
25
|
value: options
|
|
26
26
|
});
|
|
27
|
+
Object.defineProperty(this, "audioStopped", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
writable: true,
|
|
31
|
+
value: false
|
|
32
|
+
});
|
|
27
33
|
Object.defineProperty(this, "internalStats", {
|
|
28
34
|
enumerable: true,
|
|
29
35
|
configurable: true,
|
|
@@ -48,84 +54,113 @@ class MP4Base {
|
|
|
48
54
|
writable: true,
|
|
49
55
|
value: new common_1.Event()
|
|
50
56
|
});
|
|
51
|
-
Object.defineProperty(this, "
|
|
57
|
+
Object.defineProperty(this, "videoStopped", {
|
|
52
58
|
enumerable: true,
|
|
53
59
|
configurable: true,
|
|
54
60
|
writable: true,
|
|
55
|
-
value:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
value: false
|
|
62
|
+
});
|
|
63
|
+
Object.defineProperty(this, "processVideoInput", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: ({ eol, frame }) => {
|
|
68
|
+
if (this.stopped) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (!frame) {
|
|
72
|
+
if (eol) {
|
|
73
|
+
this.videoStopped = true;
|
|
74
|
+
if (!this.tracks.some((track) => track.kind === "audio") ||
|
|
75
|
+
this.audioStopped) {
|
|
76
|
+
void this.stop();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const track = this.tracks.find((t) => t.kind === "video");
|
|
82
|
+
this.videoStopped = false;
|
|
83
|
+
if (!this.container.videoTrack) {
|
|
84
|
+
if (frame.isKeyframe) {
|
|
85
|
+
const avcc = (0, mp4_1.annexb2avcc)(frame.data);
|
|
86
|
+
const sample = (0, mp4_1.annexb2avcSample)(frame.data);
|
|
87
|
+
const [displayAspectWidth, displayAspectHeight] = computeRatio(track.width, track.height);
|
|
59
88
|
this.container.write({
|
|
60
|
-
codec:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
89
|
+
codec: avccToCodecString(avcc),
|
|
90
|
+
codedWidth: track.width,
|
|
91
|
+
codedHeight: track.height,
|
|
92
|
+
description: toArrayBuffer(Buffer.from(avcc)),
|
|
93
|
+
displayAspectWidth,
|
|
94
|
+
displayAspectHeight,
|
|
95
|
+
track: "video",
|
|
65
96
|
});
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
97
|
this.container.write({
|
|
69
|
-
byteLength:
|
|
98
|
+
byteLength: sample.length,
|
|
70
99
|
duration: null,
|
|
71
100
|
timestamp: frame.time * 1000,
|
|
72
101
|
type: "key",
|
|
73
102
|
copyTo: (destination) => {
|
|
74
|
-
|
|
75
|
-
frame.data.copy(destination);
|
|
103
|
+
new Uint8Array(destination).set(sample);
|
|
76
104
|
},
|
|
77
|
-
track: "
|
|
105
|
+
track: "video",
|
|
78
106
|
});
|
|
79
107
|
}
|
|
80
108
|
}
|
|
109
|
+
else {
|
|
110
|
+
const sample = (0, mp4_1.annexb2avcSample)(frame.data);
|
|
111
|
+
this.container.write({
|
|
112
|
+
byteLength: sample.length,
|
|
113
|
+
duration: null,
|
|
114
|
+
timestamp: frame.time * 1000,
|
|
115
|
+
type: frame.isKeyframe ? "key" : "delta",
|
|
116
|
+
copyTo: (destination) => {
|
|
117
|
+
new Uint8Array(destination).set(sample);
|
|
118
|
+
},
|
|
119
|
+
track: "video",
|
|
120
|
+
});
|
|
121
|
+
}
|
|
81
122
|
}
|
|
82
123
|
});
|
|
83
|
-
Object.defineProperty(this, "
|
|
124
|
+
Object.defineProperty(this, "processAudioInput", {
|
|
84
125
|
enumerable: true,
|
|
85
126
|
configurable: true,
|
|
86
127
|
writable: true,
|
|
87
|
-
value: ({ frame }) => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
codedHeight: track.height,
|
|
98
|
-
description: avcc.buffer,
|
|
99
|
-
displayAspectWidth,
|
|
100
|
-
displayAspectHeight,
|
|
101
|
-
track: "video",
|
|
102
|
-
});
|
|
103
|
-
this.container.write({
|
|
104
|
-
byteLength: frame.data.length,
|
|
105
|
-
duration: null,
|
|
106
|
-
timestamp: frame.time * 1000,
|
|
107
|
-
type: "key",
|
|
108
|
-
copyTo: (destination) => {
|
|
109
|
-
//@ts-expect-error
|
|
110
|
-
frame.data.copy(destination);
|
|
111
|
-
},
|
|
112
|
-
track: "video",
|
|
113
|
-
});
|
|
128
|
+
value: ({ eol, frame }) => {
|
|
129
|
+
if (this.stopped) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (!frame) {
|
|
133
|
+
if (eol) {
|
|
134
|
+
this.audioStopped = true;
|
|
135
|
+
if (!this.tracks.some((track) => track.kind === "video") ||
|
|
136
|
+
this.videoStopped) {
|
|
137
|
+
void this.stop();
|
|
114
138
|
}
|
|
115
139
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const track = this.tracks.find((t) => t.kind === "audio");
|
|
143
|
+
this.audioStopped = false;
|
|
144
|
+
if (!this.container.audioTrack) {
|
|
145
|
+
this.container.write({
|
|
146
|
+
codec: track.codec,
|
|
147
|
+
description: toArrayBuffer(__1.OpusRtpPayload.createCodecPrivate()),
|
|
148
|
+
numberOfChannels: 2,
|
|
149
|
+
sampleRate: track.clockRate,
|
|
150
|
+
track: "audio",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
this.container.write({
|
|
155
|
+
byteLength: frame.data.length,
|
|
156
|
+
duration: null,
|
|
157
|
+
timestamp: frame.time * 1000,
|
|
158
|
+
type: "key",
|
|
159
|
+
copyTo: (destination) => {
|
|
160
|
+
new Uint8Array(destination).set(frame.data);
|
|
161
|
+
},
|
|
162
|
+
track: "audio",
|
|
163
|
+
});
|
|
129
164
|
}
|
|
130
165
|
}
|
|
131
166
|
});
|
|
@@ -135,8 +170,8 @@ class MP4Base {
|
|
|
135
170
|
video: !!this.tracks.find((t) => t.kind === "video"),
|
|
136
171
|
},
|
|
137
172
|
});
|
|
138
|
-
this.container.onData.subscribe((data) => {
|
|
139
|
-
this.output(data);
|
|
173
|
+
this.container.onData.subscribe(async (data) => {
|
|
174
|
+
await this.output(data);
|
|
140
175
|
});
|
|
141
176
|
}
|
|
142
177
|
toJSON() {
|
|
@@ -145,7 +180,15 @@ class MP4Base {
|
|
|
145
180
|
};
|
|
146
181
|
}
|
|
147
182
|
start() { }
|
|
148
|
-
stop() {
|
|
183
|
+
async stop() {
|
|
184
|
+
if (this.stopped) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
this.stopped = true;
|
|
188
|
+
await this.container.stop();
|
|
189
|
+
await this.output({ eol: true });
|
|
190
|
+
await this.onStopped.execute();
|
|
191
|
+
}
|
|
149
192
|
}
|
|
150
193
|
exports.MP4Base = MP4Base;
|
|
151
194
|
function computeRatio(a, b) {
|
|
@@ -160,4 +203,16 @@ function computeRatio(a, b) {
|
|
|
160
203
|
const divisor = gcd(a, b);
|
|
161
204
|
return [a / divisor, b / divisor];
|
|
162
205
|
}
|
|
206
|
+
function avccToCodecString(avcc) {
|
|
207
|
+
if (avcc.byteLength < 4) {
|
|
208
|
+
throw new Error("invalid avcc decoder configuration record");
|
|
209
|
+
}
|
|
210
|
+
return `avc1.${toHex(avcc[1])}${toHex(avcc[2])}${toHex(avcc[3])}`;
|
|
211
|
+
}
|
|
212
|
+
function toHex(value) {
|
|
213
|
+
return value.toString(16).padStart(2, "0");
|
|
214
|
+
}
|
|
215
|
+
function toArrayBuffer(buffer) {
|
|
216
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
217
|
+
}
|
|
163
218
|
//# sourceMappingURL=mp4.js.map
|
|
@@ -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 \"../../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(\n OpusRtpPayload.createCodecPrivate(),\n ) as ArrayBuffer,\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) => {\n //@ts-expect-error\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 as ArrayBuffer,\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) => {\n //@ts-expect-error\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) => {\n //@ts-expect-error\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 } from \"../..\";\nimport {\n type DataType,\n Mp4Container,\n type Mp4SupportedCodec,\n annexb2avcSample,\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 type Mp4Output =\n | {\n type: DataType;\n timestamp: number;\n duration: number;\n data: Uint8Array;\n eol?: false | undefined;\n kind: \"audio\" | \"video\";\n }\n | {\n eol: true;\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 audioStopped = false;\n private internalStats = {};\n private container: Mp4Container;\n stopped = false;\n onStopped = new Event();\n videoStopped = false;\n\n constructor(\n public tracks: Track[],\n private output: (output: Mp4Output) => void | Promise<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(async (data) => {\n await this.output(data);\n });\n }\n\n toJSON(): Record<string, any> {\n return {\n ...this.internalStats,\n };\n }\n\n processVideoInput = ({ eol, frame }: Mp4Input) => {\n if (this.stopped) {\n return;\n }\n\n if (!frame) {\n if (eol) {\n this.videoStopped = true;\n if (\n !this.tracks.some((track) => track.kind === \"audio\") ||\n this.audioStopped\n ) {\n void this.stop();\n }\n }\n return;\n }\n\n const track = this.tracks.find((t) => t.kind === \"video\")!;\n\n this.videoStopped = false;\n if (!this.container.videoTrack) {\n if (frame.isKeyframe) {\n const avcc = annexb2avcc(frame.data);\n const sample = annexb2avcSample(frame.data);\n\n const [displayAspectWidth, displayAspectHeight] = computeRatio(\n track.width!,\n track.height!,\n );\n\n this.container.write({\n codec: avccToCodecString(avcc),\n codedWidth: track.width,\n codedHeight: track.height,\n description: toArrayBuffer(Buffer.from(avcc)),\n displayAspectWidth,\n displayAspectHeight,\n track: \"video\",\n });\n this.container.write({\n byteLength: sample.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: \"key\",\n copyTo: (destination) => {\n new Uint8Array(destination).set(sample);\n },\n track: \"video\",\n });\n }\n } else {\n const sample = annexb2avcSample(frame.data);\n this.container.write({\n byteLength: sample.length,\n duration: null,\n timestamp: frame.time * 1000,\n type: frame.isKeyframe ? \"key\" : \"delta\",\n copyTo: (destination) => {\n new Uint8Array(destination).set(sample);\n },\n track: \"video\",\n });\n }\n };\n\n processAudioInput = ({ eol, frame }: Mp4Input) => {\n if (this.stopped) {\n return;\n }\n\n if (!frame) {\n if (eol) {\n this.audioStopped = true;\n if (\n !this.tracks.some((track) => track.kind === \"video\") ||\n this.videoStopped\n ) {\n void this.stop();\n }\n }\n return;\n }\n\n const track = this.tracks.find((t) => t.kind === \"audio\")!;\n\n this.audioStopped = false;\n if (!this.container.audioTrack) {\n this.container.write({\n codec: track.codec,\n description: toArrayBuffer(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) => {\n new Uint8Array(destination).set(frame.data);\n },\n track: \"audio\",\n });\n }\n };\n\n protected start() {}\n\n async stop() {\n if (this.stopped) {\n return;\n }\n\n this.stopped = true;\n await this.container.stop();\n await this.output({ eol: true });\n await this.onStopped.execute();\n }\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\nfunction avccToCodecString(avcc: Uint8Array) {\n if (avcc.byteLength < 4) {\n throw new Error(\"invalid avcc decoder configuration record\");\n }\n\n return `avc1.${toHex(avcc[1])}${toHex(avcc[2])}${toHex(avcc[3])}`;\n}\n\nfunction toHex(value: number) {\n return value.toString(16).padStart(2, \"0\");\n}\n\nfunction toArrayBuffer(buffer: Buffer) {\n return buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer;\n}\n"]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { MP4Base, type Mp4Input, type Mp4Output, type Track } from "./mp4";
|
|
2
|
-
import type { WebmOption } from "./webm";
|
|
1
|
+
import { MP4Base, type MP4Option, type Mp4Input, type Mp4Output, type Track } from "./mp4";
|
|
3
2
|
export declare class MP4Callback extends MP4Base {
|
|
4
3
|
private cb?;
|
|
5
4
|
private queue;
|
|
6
|
-
constructor(tracks: Track[], options?:
|
|
5
|
+
constructor(tracks: Track[], options?: MP4Option);
|
|
7
6
|
pipe: (cb: (input: Mp4Output) => Promise<void>) => void;
|
|
8
7
|
inputAudio: (input: Mp4Input) => void;
|
|
9
8
|
inputVideo: (input: Mp4Input) => void;
|
|
@@ -55,8 +55,10 @@ class MP4Callback extends mp4_1.MP4Base {
|
|
|
55
55
|
configurable: true,
|
|
56
56
|
writable: true,
|
|
57
57
|
value: () => {
|
|
58
|
-
this.
|
|
59
|
-
|
|
58
|
+
void this.stop().finally(() => {
|
|
59
|
+
this.cb = undefined;
|
|
60
|
+
this.queue.cancel();
|
|
61
|
+
});
|
|
60
62
|
}
|
|
61
63
|
});
|
|
62
64
|
}
|
|
@@ -71,7 +73,7 @@ Object.defineProperty(MP4Callback, "saveToFileSystem", {
|
|
|
71
73
|
const queue = new __1.PromiseQueue();
|
|
72
74
|
return async (value) => {
|
|
73
75
|
await queue.push(async () => {
|
|
74
|
-
if (value
|
|
76
|
+
if ("data" in value) {
|
|
75
77
|
await (0, promises_1.appendFile)(path, value.data);
|
|
76
78
|
}
|
|
77
79
|
else if (value.eol) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mp4Callback.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/mp4Callback.ts"],"names":[],"mappings":";;;;AAAA,0CAAyC;AAEzC,6BAAqC;AACrC,+
|
|
1
|
+
{"version":3,"file":"mp4Callback.js","sourceRoot":"","sources":["../../../../../../rtp/src/extra/processor/mp4Callback.ts"],"names":[],"mappings":";;;;AAAA,0CAAyC;AAEzC,6BAAqC;AACrC,+BAMe;AAEf,MAAa,WAAY,SAAQ,aAAO;IAGtC,YAAY,MAAe,EAAE,UAAqB,EAAE;QAClD,KAAK,CACH,MAAM,EACN,KAAK,EAAE,MAAM,EAAE,EAAE;YACf,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YACnB,IAAI,EAAE,EAAE,CAAC;gBACP,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,EACD,OAAO,CACR,CAAC;QAZI;;;;;WAAyC;QACzC;;;;mBAAQ,IAAI,gBAAY,EAAE;WAAC;QAcnC;;;;mBAAO,CAAC,EAAuC,EAAE,EAAE;gBACjD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,CAAC;WAAC;QAEF;;;;mBAAa,CAAC,KAAe,EAAE,EAAE;gBAC/B,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;WAAC;QACF;;;;mBAAa,CAAC,KAAe,EAAE,EAAE;gBAC/B,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;WAAC;QAEF;;;;mBAAU,GAAG,EAAE;gBACb,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;oBAC5B,IAAI,CAAC,EAAE,GAAG,SAAS,CAAC;oBACpB,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACtB,CAAC,CAAC,CAAC;YACL,CAAC;WAAC;IAnBF,CAAC;;AAdH,kCA8CC;;AAXQ;;;;WAAmB,CAAC,IAAY,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,IAAI,gBAAY,EAAE,CAAC;QACjC,OAAO,KAAK,EAAE,KAAgB,EAAE,EAAE;YAChC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;gBAC1B,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;oBACpB,MAAM,IAAA,qBAAU,EAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrC,CAAC;qBAAM,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBACvB,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC;EAVsB,CAUrB","sourcesContent":["import { appendFile } from \"fs/promises\";\n\nimport { PromiseQueue } from \"../..\";\nimport {\n MP4Base,\n type MP4Option,\n type Mp4Input,\n type Mp4Output,\n type Track,\n} from \"./mp4\";\n\nexport class MP4Callback extends MP4Base {\n private cb?: (input: Mp4Output) => Promise<void>;\n private queue = new PromiseQueue();\n constructor(tracks: Track[], options: MP4Option = {}) {\n super(\n tracks,\n async (output) => {\n const cb = this.cb;\n if (cb) {\n await this.queue.push(() => cb(output));\n }\n },\n options,\n );\n }\n\n pipe = (cb: (input: Mp4Output) => Promise<void>) => {\n this.cb = cb;\n this.start();\n };\n\n inputAudio = (input: Mp4Input) => {\n this.processAudioInput(input);\n };\n inputVideo = (input: Mp4Input) => {\n this.processVideoInput(input);\n };\n\n destroy = () => {\n void this.stop().finally(() => {\n this.cb = undefined;\n this.queue.cancel();\n });\n };\n\n static saveToFileSystem = (path: string) => {\n const queue = new PromiseQueue();\n return async (value: Mp4Output) => {\n await queue.push(async () => {\n if (\"data\" in value) {\n await appendFile(path, value.data);\n } else if (value.eol) {\n }\n });\n };\n };\n}\n"]}
|
|
@@ -13,6 +13,7 @@ export declare class RTCDataChannel extends EventTarget implements DataChannelSt
|
|
|
13
13
|
readonly sctp: RTCSctpTransport;
|
|
14
14
|
private readonly parameters;
|
|
15
15
|
readonly sendOpen: boolean;
|
|
16
|
+
readonly statsId: string;
|
|
16
17
|
readonly stateChange: Event<[DCState]>;
|
|
17
18
|
readonly stateChanged: Event<[DCState]>;
|
|
18
19
|
readonly onMessage: Event<[string | Buffer<ArrayBufferLike>]>;
|
|
@@ -34,8 +35,8 @@ export declare class RTCDataChannel extends EventTarget implements DataChannelSt
|
|
|
34
35
|
bytesReceived: number;
|
|
35
36
|
constructor(sctp: RTCSctpTransport, parameters: RTCDataChannelParameters, sendOpen?: boolean);
|
|
36
37
|
get ordered(): boolean;
|
|
37
|
-
get maxRetransmits(): number |
|
|
38
|
-
get maxPacketLifeTime(): number |
|
|
38
|
+
get maxRetransmits(): number | null;
|
|
39
|
+
get maxPacketLifeTime(): number | null;
|
|
39
40
|
get label(): string;
|
|
40
41
|
get protocol(): string;
|
|
41
42
|
get negotiated(): boolean;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RTCDataChannelParameters = exports.RTCDataChannel = void 0;
|
|
4
4
|
exports.getDataChannelMessageSize = getDataChannelMessageSize;
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
5
6
|
const common_1 = require("./imports/common");
|
|
6
7
|
const helper_1 = require("./helper");
|
|
7
8
|
const log = (0, common_1.debug)("werift:packages/webrtc/src/dataChannel.ts");
|
|
@@ -29,6 +30,12 @@ class RTCDataChannel extends helper_1.EventTarget {
|
|
|
29
30
|
writable: true,
|
|
30
31
|
value: sendOpen
|
|
31
32
|
});
|
|
33
|
+
Object.defineProperty(this, "statsId", {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
writable: true,
|
|
37
|
+
value: (0, crypto_1.randomUUID)().toString()
|
|
38
|
+
});
|
|
32
39
|
Object.defineProperty(this, "stateChange", {
|
|
33
40
|
enumerable: true,
|
|
34
41
|
configurable: true,
|
|
@@ -164,10 +171,10 @@ class RTCDataChannel extends helper_1.EventTarget {
|
|
|
164
171
|
return this.parameters.ordered;
|
|
165
172
|
}
|
|
166
173
|
get maxRetransmits() {
|
|
167
|
-
return this.parameters.maxRetransmits;
|
|
174
|
+
return this.parameters.maxRetransmits ?? null;
|
|
168
175
|
}
|
|
169
176
|
get maxPacketLifeTime() {
|
|
170
|
-
return this.parameters.maxPacketLifeTime;
|
|
177
|
+
return this.parameters.maxPacketLifeTime ?? null;
|
|
171
178
|
}
|
|
172
179
|
get label() {
|
|
173
180
|
return this.parameters.label;
|