diff --git a/dist/metamuxer.d.ts b/dist/metamuxer.d.ts index e099e9d..3120704 100644 --- a/dist/metamuxer.d.ts +++ b/dist/metamuxer.d.ts @@ -1,3 +1,14 @@ +/** @public */ +export declare const ALL_FORMATS: InputFormat[]; + +/** @public */ +export declare type AnyIterable = Iterable | AsyncIterable; + +/** @public */ +export declare class ArrayBufferSource extends Source { + constructor(buffer: ArrayBuffer); +} + /** @public */ export declare class ArrayBufferTarget extends Target { buffer: ArrayBuffer | null; @@ -6,6 +17,14 @@ export declare class ArrayBufferTarget extends Target { /** @public */ export declare const AUDIO_CODECS: readonly ["aac", "opus"]; +/** @public */ +export declare class AudioBufferDrain { + constructor(audioTrack: InputAudioTrack); + getBuffer(timestamp: number): Promise; + buffers(startTimestamp?: number, endTimestamp?: number): AsyncGenerator; + buffersAtTimestamps(timestamps: AnyIterable): AsyncGenerator; +} + /** @public */ export declare class AudioBufferSource extends AudioSource { constructor(codecConfig: AudioCodecConfig); @@ -21,6 +40,14 @@ export declare type AudioCodecConfig = { bitrate: number; }; +/** @public */ +export declare class AudioDataDrain extends BaseMediaFrameDrain { + constructor(audioTrack: InputAudioTrack); + getData(timestamp: number): Promise; + data(startTimestamp?: number, endTimestamp?: number): AsyncGenerator; + dataAtTimestamps(timestamps: AnyIterable): AsyncGenerator; +} + /** @public */ export declare class AudioDataSource extends AudioSource { constructor(codecConfig: AudioCodecConfig); @@ -35,24 +62,151 @@ export declare abstract class AudioSource extends MediaSource_2 { /** @public */ export declare type AudioTrackMetadata = {}; +/** @public */ +export declare abstract class BaseChunkDrain { + abstract getFirstChunk(options?: ChunkRetrievalOptions): Promise; + abstract getChunk(timestamp: number, options?: ChunkRetrievalOptions): Promise; + abstract getNextChunk(chunk: Chunk, options?: ChunkRetrievalOptions): Promise; + abstract getKeyChunk(timestamp: number, options?: ChunkRetrievalOptions): Promise; + abstract getNextKeyChunk(chunk: Chunk, options?: ChunkRetrievalOptions): Promise; + chunks(startChunk?: Chunk, endTimestamp?: number): AsyncGenerator; +} + +/** @public */ +export declare abstract class BaseMediaFrameDrain { + protected mediaFramesAtTimestamps(timestamps: AnyIterable): AsyncGenerator; + protected mediaFramesInRange(startTimestamp?: number, endTimestamp?: number): AsyncGenerator; +} + +/** @public */ +export declare class BlobSource extends Source { + constructor(blob: Blob); +} + +/** @public */ +export declare class CanvasDrain { + constructor(videoTrack: InputVideoTrack, dimensions?: { + width: number; + height: number; + }); + getCanvas(timestamp: number): Promise; + canvases(startTimestamp?: number, endTimestamp?: number): AsyncGenerator; + canvasesAtTimestamps(timestamps: AnyIterable): AsyncGenerator; +} + /** @public */ export declare class CanvasSource extends VideoSource { constructor(canvas: HTMLCanvasElement | OffscreenCanvas, codecConfig: VideoCodecConfig); digest(timestamp: number, duration?: number): Promise; } +/** @public */ +export declare type ChunkRetrievalOptions = { + metadataOnly?: boolean; +}; + +/** @public */ +export declare class EncodedAudioChunkDrain extends BaseChunkDrain { + constructor(audioTrack: InputAudioTrack); + getFirstChunk(options?: ChunkRetrievalOptions): Promise; + getChunk(timestamp: number, options?: ChunkRetrievalOptions): Promise; + getNextChunk(chunk: EncodedAudioChunk, options?: ChunkRetrievalOptions): Promise; + getKeyChunk(timestamp: number, options?: ChunkRetrievalOptions): Promise; + getNextKeyChunk(chunk: EncodedAudioChunk, options?: ChunkRetrievalOptions): Promise; +} + /** @public */ export declare class EncodedAudioChunkSource extends AudioSource { constructor(codec: AudioCodec); digest(chunk: EncodedAudioChunk, meta?: EncodedAudioChunkMetadata): Promise; } +/** @public */ +export declare class EncodedVideoChunkDrain extends BaseChunkDrain { + constructor(videoTrack: InputVideoTrack); + getFirstChunk(options?: ChunkRetrievalOptions): Promise; + getChunk(timestamp: number, options?: ChunkRetrievalOptions): Promise; + getNextChunk(chunk: EncodedVideoChunk, options?: ChunkRetrievalOptions): Promise; + getKeyChunk(timestamp: number, options?: ChunkRetrievalOptions): Promise; + getNextKeyChunk(chunk: EncodedVideoChunk, options?: ChunkRetrievalOptions): Promise; +} + /** @public */ export declare class EncodedVideoChunkSource extends VideoSource { constructor(codec: VideoCodec); digest(chunk: EncodedVideoChunk, meta?: EncodedVideoChunkMetadata): Promise; } +/** @public */ +export declare class Input { + constructor(options: InputOptions); + getFormat(): Promise; + computeDuration(): Promise; + getTracks(): Promise; + getVideoTracks(): Promise; + getPrimaryVideoTrack(): Promise; + getAudioTracks(): Promise; + getPrimaryAudioTrack(): Promise; + getMimeType(): Promise; +} + +/** @public */ +export declare class InputAudioTrack extends InputTrack { + getCodec(): Promise<"aac" | "opus">; + getNumberOfChannels(): Promise; + getSampleRate(): Promise; + getDecoderConfig(): Promise; + getCodecMimeType(): Promise; +} + +/** @public */ +export declare abstract class InputFormat { +} + +/** @public */ +export declare type InputOptions = { + formats: InputFormat[]; + source: Source; +}; + +/** @public */ +export declare abstract class InputTrack { + abstract getCodec(): Promise; + abstract getCodecMimeType(): Promise; + isVideoTrack(): this is InputVideoTrack; + isAudioTrack(): this is InputAudioTrack; + computeDuration(): Promise; +} + +/** @public */ +export declare class InputVideoTrack extends InputTrack { + getCodec(): Promise<"avc" | "hevc" | "vp8" | "vp9" | "av1">; + getCodedWidth(): Promise; + getCodedHeight(): Promise; + getRotation(): Promise; + getDisplayWidth(): Promise; + getDisplayHeight(): Promise; + getDecoderConfig(): Promise; + getCodecMimeType(): Promise; +} + +/** @public */ +export declare const ISOBMFF: IsobmffInputFormat; + +/** @public */ +export declare class IsobmffInputFormat extends InputFormat { +} + +/** @public */ +export declare const MATROSKA: MatroskaInputFormat; + +/** @public */ +export declare class MatroskaInputFormat extends InputFormat { +} + +/** @public */ +export declare type MediaCodec = VideoCodec | AudioCodec | SubtitleCodec; + /** @public */ declare abstract class MediaSource_2 { close(): void; @@ -69,6 +223,9 @@ export declare class MediaStreamVideoTrackSource extends VideoSource { constructor(track: MediaStreamVideoTrack, codecConfig: VideoCodecConfig); } +/** @public */ +export declare const MKV: MatroskaInputFormat; + /** @public */ export declare class MkvOutputFormat extends OutputFormat { constructor(options?: MkvOutputFormatOptions); @@ -79,6 +236,12 @@ export declare type MkvOutputFormatOptions = { streamable?: boolean; }; +/** @public */ +export declare const MOV: IsobmffInputFormat; + +/** @public */ +export declare const MP4: IsobmffInputFormat; + /** @public */ export declare class Mp4OutputFormat extends OutputFormat { constructor(options?: Mp4OutputFormatOptions); @@ -109,6 +272,13 @@ export declare type OutputOptions = { target: Target; }; +/** @public */ +export declare type Rotation = 0 | 90 | 180 | 270; + +/** @public */ +export declare abstract class Source { +} + /** @public */ export declare class StreamTarget extends Target { constructor(writable: WritableStream, options?: StreamTargetOptions); @@ -167,6 +337,14 @@ export declare type VideoCodecConfig = { latencyMode?: VideoEncoderConfig['latencyMode']; }; +/** @public */ +export declare class VideoFrameDrain extends BaseMediaFrameDrain { + constructor(videoTrack: InputVideoTrack); + getFrame(timestamp: number): Promise; + frames(startTimestamp?: number, endTimestamp?: number): AsyncGenerator; + framesAtTimestamps(timestamps: AnyIterable): AsyncGenerator; +} + /** @public */ export declare class VideoFrameSource extends VideoSource { constructor(codecConfig: VideoCodecConfig); @@ -184,6 +362,9 @@ export declare type VideoTrackMetadata = { frameRate?: number; }; +/** @public */ +export declare const WEBM: MatroskaInputFormat; + /** @public */ export declare class WebMOutputFormat extends MkvOutputFormat { } @@ -191,6 +372,19 @@ export declare class WebMOutputFormat extends MkvOutputFormat { /** @public */ export declare type WebMOutputFormatOptions = MkvOutputFormatOptions; +/** @public */ +export declare type WrappedAudioBuffer = { + buffer: AudioBuffer; + timestamp: number; +}; + +/** @public */ +export declare type WrappedCanvas = { + canvas: HTMLCanvasElement; + timestamp: number; + duration: number; +}; + export { } export as namespace Metamuxer; \ No newline at end of file diff --git a/dist/metamuxer.js b/dist/metamuxer.js index 81965ce..de18ef1 100644 --- a/dist/metamuxer.js +++ b/dist/metamuxer.js @@ -30,6 +30,8 @@ var Metamuxer = (() => { AudioDataDrain: () => AudioDataDrain, AudioDataSource: () => AudioDataSource, AudioSource: () => AudioSource, + BaseChunkDrain: () => BaseChunkDrain, + BaseMediaFrameDrain: () => BaseMediaFrameDrain, BlobSource: () => BlobSource, CanvasDrain: () => CanvasDrain, CanvasSource: () => CanvasSource, @@ -39,10 +41,16 @@ var Metamuxer = (() => { EncodedVideoChunkSource: () => EncodedVideoChunkSource, ISOBMFF: () => ISOBMFF, Input: () => Input, + InputAudioTrack: () => InputAudioTrack, + InputFormat: () => InputFormat, + InputTrack: () => InputTrack, + InputVideoTrack: () => InputVideoTrack, + IsobmffInputFormat: () => IsobmffInputFormat, MATROSKA: () => MATROSKA, MKV: () => MKV, MOV: () => MOV, MP4: () => MP4, + MatroskaInputFormat: () => MatroskaInputFormat, MediaSource: () => MediaSource, MediaStreamAudioTrackSource: () => MediaStreamAudioTrackSource, MediaStreamVideoTrackSource: () => MediaStreamVideoTrackSource, @@ -145,7 +153,9 @@ var Metamuxer = (() => { return x instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && x instanceof SharedArrayBuffer || ArrayBuffer.isView(x) && !(x instanceof DataView); }; var AsyncMutex = class { - currentPromise = Promise.resolve(); + constructor() { + this.currentPromise = Promise.resolve(); + } async acquire() { let resolver; const nextPromise = new Promise((resolve) => { @@ -234,6 +244,14 @@ var Metamuxer = (() => { arr.splice(index, 1); } }; + var findLastIndex = (arr, predicate) => { + for (let i = arr.length - 1; i >= 0; i--) { + if (predicate(arr[i])) { + return i; + } + } + return -1; + }; var toAsyncIterator = async function* (source) { if (Symbol.iterator in source) { yield* source[Symbol.iterator](); @@ -247,10 +265,9 @@ var Metamuxer = (() => { var preambleStartRegex = /^WEBVTT(.|\n)*?\n{2}/; var inlineTimestampRegex = /<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g; var SubtitleParser = class { - options; - preambleText = null; - preambleEmitted = false; constructor(options) { + this.preambleText = null; + this.preambleEmitted = false; this.options = options; } parse(text) { @@ -327,14 +344,14 @@ var Metamuxer = (() => { var IsobmffBoxWriter = class { constructor(writer) { this.writer = writer; + this.helper = new Uint8Array(8); + this.helperView = new DataView(this.helper.buffer); + /** + * Stores the position from the start of the file to where boxes elements have been written. This is used to + * rewrite/edit elements that were already added before, and to measure sizes of things. + */ + this.offsets = /* @__PURE__ */ new WeakMap(); } - helper = new Uint8Array(8); - helperView = new DataView(this.helper.buffer); - /** - * Stores the position from the start of the file to where boxes elements have been written. This is used to - * rewrite/edit elements that were already added before, and to measure sizes of things. - */ - offsets = /* @__PURE__ */ new WeakMap(); writeU32(value) { this.helperView.setUint32(0, value, false); this.writer.write(this.helper.subarray(0, 4)); @@ -1209,9 +1226,9 @@ var Metamuxer = (() => { // src/muxer.ts var Muxer = class { - output; - mutex = new AsyncMutex(); constructor(output) { + this.mutex = new AsyncMutex(); + this.trackTimestampInfo = /* @__PURE__ */ new WeakMap(); this.output = output; } // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -1220,7 +1237,6 @@ var Metamuxer = (() => { // eslint-disable-next-line @typescript-eslint/no-unused-vars onTrackClose(track) { } - trackTimestampInfo = /* @__PURE__ */ new WeakMap(); validateAndNormalizeTimestamp(track, rawTimestampInUs, isKeyFrame) { let timestampInSeconds = rawTimestampInUs / 1e6; let timestampInfo = this.trackTimestampInfo.get(track); @@ -1264,19 +1280,20 @@ var Metamuxer = (() => { // src/writer.ts var Writer = class { - /** Setting this to true will cause the writer to ensure data is written in a strictly monotonic, streamable way. */ - ensureMonotonicity = false; + constructor() { + /** Setting this to true will cause the writer to ensure data is written in a strictly monotonic, streamable way. */ + this.ensureMonotonicity = false; + } start() { } }; var ArrayBufferTargetWriter = class extends Writer { - pos = 0; - target; - buffer = new ArrayBuffer(2 ** 16); - bytes = new Uint8Array(this.buffer); - maxPos = 0; constructor(target) { super(); + this.pos = 0; + this.buffer = new ArrayBuffer(2 ** 16); + this.bytes = new Uint8Array(this.buffer); + this.maxPos = 0; this.target = target; } ensureSize(size) { @@ -1312,13 +1329,12 @@ var Metamuxer = (() => { } }; var StreamTargetWriter = class extends Writer { - pos = 0; - target; - sections = []; - lastFlushEnd = 0; - writer = null; constructor(target) { super(); + this.pos = 0; + this.sections = []; + this.lastFlushEnd = 0; + this.writer = null; this.target = target; } start() { @@ -1388,19 +1404,17 @@ var Metamuxer = (() => { var DEFAULT_CHUNK_SIZE = 2 ** 24; var MAX_CHUNKS_AT_ONCE = 2; var ChunkedStreamTargetWriter = class extends Writer { - pos = 0; - target; - chunkSize; - /** - * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out. - * A chunk is flushed if all of its contents have been written. - */ - chunks = []; - lastFlushEnd = 0; - writer = null; - flushedChunkQueue = []; constructor(target) { super(); + this.pos = 0; + /** + * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out. + * A chunk is flushed if all of its contents have been written. + */ + this.chunks = []; + this.lastFlushEnd = 0; + this.writer = null; + this.flushedChunkQueue = []; this.target = target; this.chunkSize = target._options?.chunkSize ?? DEFAULT_CHUNK_SIZE; if (!Number.isInteger(this.chunkSize) || this.chunkSize < 2 ** 10) { @@ -1518,21 +1532,22 @@ var Metamuxer = (() => { // src/target.ts var Target = class { - /** @internal */ - _output = null; + constructor() { + /** @internal */ + this._output = null; + } }; var ArrayBufferTarget = class extends Target { - buffer = null; + constructor() { + super(...arguments); + this.buffer = null; + } /** @internal */ _createWriter() { return new ArrayBufferTargetWriter(this); } }; var StreamTarget = class extends Target { - /** @internal */ - _writable; - /** @internal */ - _options; constructor(writable, options = {}) { super(); if (!(writable instanceof WritableStream)) { @@ -2072,21 +2087,18 @@ var Metamuxer = (() => { return round ? Math.round(value) : value; }; var IsobmffMuxer = class extends Muxer { - timestampsMustStartAtZero = true; - writer; - boxWriter; - fastStart; - auxTarget = new ArrayBufferTarget(); - auxWriter = this.auxTarget._createWriter(); - auxBoxWriter = new IsobmffBoxWriter(this.auxWriter); - ftypSize = null; - mdat = null; - trackDatas = []; - creationTime = Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET; - finalizedChunks = []; - nextFragmentNumber = 1; constructor(output, format) { super(output); + this.timestampsMustStartAtZero = true; + this.auxTarget = new ArrayBufferTarget(); + this.auxWriter = this.auxTarget._createWriter(); + this.auxBoxWriter = new IsobmffBoxWriter(this.auxWriter); + this.ftypSize = null; + this.mdat = null; + this.trackDatas = []; + this.creationTime = Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET; + this.finalizedChunks = []; + this.nextFragmentNumber = 1; this.writer = output._writer; this.boxWriter = new IsobmffBoxWriter(this.writer); const fastStartDefault = this.writer instanceof ArrayBufferTargetWriter ? "in-memory" : false; @@ -2675,19 +2687,16 @@ var Metamuxer = (() => { // src/matroska/ebml.ts var EBMLFloat32 = class { - value; constructor(value) { this.value = value; } }; var EBMLFloat64 = class { - value; constructor(value) { this.value = value; } }; var EBMLSignedInt = class { - value; constructor(value) { this.value = value; } @@ -2761,31 +2770,29 @@ var Metamuxer = (() => { subtitle: 17 }; var MatroskaMuxer = class extends Muxer { - timestampsMustStartAtZero = false; - writer; - format; - helper = new Uint8Array(8); - helperView = new DataView(this.helper.buffer); - /** - * Stores the position from the start of the file to where EBML elements have been written. This is used to - * rewrite/edit elements that were already added before, and to measure sizes of things. - */ - offsets = /* @__PURE__ */ new WeakMap(); - /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */ - dataOffsets = /* @__PURE__ */ new WeakMap(); - trackDatas = []; - segment = null; - segmentInfo = null; - seekHead = null; - tracksElement = null; - segmentDuration = null; - cues = null; - currentCluster = null; - currentClusterMsTimestamp = null; - trackDatasInCurrentCluster = /* @__PURE__ */ new Set(); - duration = 0; constructor(output, format) { super(output); + this.timestampsMustStartAtZero = false; + this.helper = new Uint8Array(8); + this.helperView = new DataView(this.helper.buffer); + /** + * Stores the position from the start of the file to where EBML elements have been written. This is used to + * rewrite/edit elements that were already added before, and to measure sizes of things. + */ + this.offsets = /* @__PURE__ */ new WeakMap(); + /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */ + this.dataOffsets = /* @__PURE__ */ new WeakMap(); + this.trackDatas = []; + this.segment = null; + this.segmentInfo = null; + this.seekHead = null; + this.tracksElement = null; + this.segmentDuration = null; + this.cues = null; + this.currentCluster = null; + this.currentClusterMsTimestamp = null; + this.trackDatasInCurrentCluster = /* @__PURE__ */ new Set(); + this.duration = 0; this.writer = output._writer; this.format = format; if (this.format._options.streamable) { @@ -3460,8 +3467,6 @@ ${cue.notes ?? ""}`; var OutputFormat = class { }; var Mp4OutputFormat = class extends OutputFormat { - /** @internal */ - _options; constructor(options = {}) { if (!options || typeof options !== "object") { throw new TypeError("options must be an object."); @@ -3478,8 +3483,6 @@ ${cue.notes ?? ""}`; } }; var MkvOutputFormat2 = class extends OutputFormat { - /** @internal */ - _options; constructor(options = {}) { if (!options || typeof options !== "object") { throw new TypeError("options must be an object."); @@ -3500,12 +3503,14 @@ ${cue.notes ?? ""}`; // src/media-source.ts var MediaSource = class { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _closed = false; - /** @internal */ - _offsetTimestamps = false; + constructor() { + /** @internal */ + this._connectedTrack = null; + /** @internal */ + this._closed = false; + /** @internal */ + this._offsetTimestamps = false; + } /** @internal */ _ensureValidDigest() { if (!this._connectedTrack) { @@ -3545,12 +3550,10 @@ ${cue.notes ?? ""}`; } }; var VideoSource = class extends MediaSource { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _codec; constructor(codec) { super(); + /** @internal */ + this._connectedTrack = null; if (!VIDEO_CODECS.includes(codec)) { throw new TypeError(`Invalid video codec '${codec}'. Must be one of: ${VIDEO_CODECS.join(", ")}.`); } @@ -3588,13 +3591,13 @@ ${cue.notes ?? ""}`; constructor(source, codecConfig) { this.source = source; this.codecConfig = codecConfig; + this.encoder = null; + this.muxer = null; + this.lastMultipleOfKeyFrameInterval = -1; + this.lastWidth = null; + this.lastHeight = null; validateVideoCodecConfig(codecConfig); } - encoder = null; - muxer = null; - lastMultipleOfKeyFrameInterval = -1; - lastWidth = null; - lastHeight = null; async digest(videoFrame) { this.source._ensureValidDigest(); if (this.lastWidth !== null && this.lastHeight !== null) { @@ -3652,8 +3655,6 @@ ${cue.notes ?? ""}`; } }; var VideoFrameSource = class extends VideoSource { - /** @internal */ - _encoder; constructor(codecConfig) { super(codecConfig.codec); this._encoder = new VideoEncoderWrapper(this, codecConfig); @@ -3670,10 +3671,6 @@ ${cue.notes ?? ""}`; } }; var CanvasSource = class extends VideoSource { - /** @internal */ - _encoder; - /** @internal */ - _canvas; constructor(canvas, codecConfig) { if (!(canvas instanceof HTMLCanvasElement)) { throw new TypeError("canvas must be an HTMLCanvasElement."); @@ -3704,14 +3701,6 @@ ${cue.notes ?? ""}`; } }; var MediaStreamVideoTrackSource = class extends VideoSource { - /** @internal */ - _encoder; - /** @internal */ - _abortController = null; - /** @internal */ - _track; - /** @internal */ - _offsetTimestamps = true; constructor(track, codecConfig) { if (!(track instanceof MediaStreamTrack) || track.kind !== "video") { throw new TypeError("track must be a video MediaStreamTrack."); @@ -3721,6 +3710,10 @@ ${cue.notes ?? ""}`; latencyMode: "realtime" }; super(codecConfig.codec); + /** @internal */ + this._abortController = null; + /** @internal */ + this._offsetTimestamps = true; this._encoder = new VideoEncoderWrapper(this, codecConfig); this._track = track; } @@ -3751,12 +3744,10 @@ ${cue.notes ?? ""}`; } }; var AudioSource = class extends MediaSource { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _codec; constructor(codec) { super(); + /** @internal */ + this._connectedTrack = null; if (!AUDIO_CODECS.includes(codec)) { throw new TypeError(`Invalid audio codec '${codec}'. Must be one of: ${AUDIO_CODECS.join(", ")}.`); } @@ -3790,12 +3781,12 @@ ${cue.notes ?? ""}`; constructor(source, codecConfig) { this.source = source; this.codecConfig = codecConfig; + this.encoder = null; + this.muxer = null; + this.lastNumberOfChannels = null; + this.lastSampleRate = null; validateAudioCodecConfig(codecConfig); } - encoder = null; - muxer = null; - lastNumberOfChannels = null; - lastSampleRate = null; async digest(audioData) { this.source._ensureValidDigest(); if (this.lastNumberOfChannels !== null && this.lastSampleRate !== null) { @@ -3842,8 +3833,6 @@ ${cue.notes ?? ""}`; } }; var AudioDataSource = class extends AudioSource { - /** @internal */ - _encoder; constructor(codecConfig) { super(codecConfig.codec); this._encoder = new AudioEncoderWrapper(this, codecConfig); @@ -3860,12 +3849,10 @@ ${cue.notes ?? ""}`; } }; var AudioBufferSource = class extends AudioSource { - /** @internal */ - _encoder; - /** @internal */ - _accumulatedFrameCount = 0; constructor(codecConfig) { super(codecConfig.codec); + /** @internal */ + this._accumulatedFrameCount = 0; this._encoder = new AudioEncoderWrapper(this, codecConfig); } digest(audioBuffer) { @@ -3899,19 +3886,15 @@ ${cue.notes ?? ""}`; } }; var MediaStreamAudioTrackSource = class extends AudioSource { - /** @internal */ - _encoder; - /** @internal */ - _abortController = null; - /** @internal */ - _track; - /** @internal */ - _offsetTimestamps = true; constructor(track, codecConfig) { if (!(track instanceof MediaStreamTrack) || track.kind !== "audio") { throw new TypeError("track must be an audio MediaStreamTrack."); } super(codecConfig.codec); + /** @internal */ + this._abortController = null; + /** @internal */ + this._offsetTimestamps = true; this._encoder = new AudioEncoderWrapper(this, codecConfig); this._track = track; } @@ -3942,12 +3925,10 @@ ${cue.notes ?? ""}`; } }; var SubtitleSource = class extends MediaSource { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _codec; constructor(codec) { super(); + /** @internal */ + this._connectedTrack = null; if (!SUBTITLE_CODECS.includes(codec)) { throw new TypeError(`Invalid subtitle codec '${codec}'. Must be one of: ${SUBTITLE_CODECS.join(", ")}.`); } @@ -3955,8 +3936,6 @@ ${cue.notes ?? ""}`; } }; var TextSubtitleSource = class extends SubtitleSource { - /** @internal */ - _parser; constructor(codec) { super(codec); this._parser = new SubtitleParser({ @@ -3977,19 +3956,15 @@ ${cue.notes ?? ""}`; // src/output.ts var Output = class { - /** @internal */ - _muxer; - /** @internal */ - _writer; - /** @internal */ - _tracks = []; - /** @internal */ - _started = false; - /** @internal */ - _finalizing = false; - /** @internal */ - _mutex = new AsyncMutex(); constructor(options) { + /** @internal */ + this._tracks = []; + /** @internal */ + this._started = false; + /** @internal */ + this._finalizing = false; + /** @internal */ + this._mutex = new AsyncMutex(); if (!options || typeof options !== "object") { throw new TypeError("options must be an object."); } @@ -4095,8 +4070,10 @@ ${cue.notes ?? ""}`; // src/source.ts var Source = class { - /** @internal */ - _sizePromise = null; + constructor() { + /** @internal */ + this._sizePromise = null; + } /** @internal */ _getSize() { return this._sizePromise ??= this._retrieveSize(); @@ -4105,37 +4082,36 @@ ${cue.notes ?? ""}`; var ArrayBufferSource = class extends Source { constructor(buffer) { super(); - this.buffer = buffer; + this._buffer = buffer; } /** @internal */ async _read(start, end) { - return new Uint8Array(this.buffer, start, end - start); + return new Uint8Array(this._buffer, start, end - start); } /** @internal */ async _retrieveSize() { - return this.buffer.byteLength; + return this._buffer.byteLength; } }; var BlobSource = class extends Source { constructor(blob) { super(); - this.blob = blob; + this._blob = blob; } /** @internal */ async _read(start, end) { - const slice = this.blob.slice(start, end); + const slice = this._blob.slice(start, end); const buffer = await slice.arrayBuffer(); return new Uint8Array(buffer); } /** @internal */ async _retrieveSize() { - return this.blob.size; + return this._blob.size; } }; // src/demuxer.ts var Demuxer = class { - input; constructor(input) { this.input = input; } @@ -4143,8 +4119,6 @@ ${cue.notes ?? ""}`; // src/input-track.ts var InputTrack = class { - /** @internal */ - _backing; /** @internal */ constructor(backing) { this._backing = backing; @@ -4160,8 +4134,6 @@ ${cue.notes ?? ""}`; } }; var InputVideoTrack = class extends InputTrack { - /** @internal */ - _backing; /** @internal */ constructor(backing) { super(backing); @@ -4170,22 +4142,22 @@ ${cue.notes ?? ""}`; getCodec() { return this._backing.getCodec(); } - getWidth() { - return this._backing.getWidth(); + getCodedWidth() { + return this._backing.getCodedWidth(); } - getHeight() { - return this._backing.getHeight(); + getCodedHeight() { + return this._backing.getCodedHeight(); } getRotation() { return this._backing.getRotation(); } - async getRotatedWidth() { + async getDisplayWidth() { const rotation = await this._backing.getRotation(); - return rotation % 180 === 0 ? this._backing.getWidth() : this._backing.getHeight(); + return rotation % 180 === 0 ? this._backing.getCodedWidth() : this._backing.getCodedHeight(); } - async getRotatedHeight() { + async getDisplayHeight() { const rotation = await this._backing.getRotation(); - return rotation % 180 === 0 ? this._backing.getHeight() : this._backing.getWidth(); + return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth(); } getDecoderConfig() { return this._backing.getDecoderConfig(); @@ -4196,8 +4168,6 @@ ${cue.notes ?? ""}`; } }; var InputAudioTrack = class extends InputTrack { - /** @internal */ - _backing; /** @internal */ constructor(backing) { super(backing); @@ -4226,12 +4196,12 @@ ${cue.notes ?? ""}`; constructor(source, maxStorableBytes = Infinity) { this.source = source; this.maxStorableBytes = maxStorableBytes; + this.loadedSegments = []; + this.loadingSegments = []; + this.sourceSizePromise = null; + this.nextAge = 0; + this.totalStoredBytes = 0; } - loadedSegments = []; - loadingSegments = []; - sourceSizePromise = null; - nextAge = 0; - totalStoredBytes = 0; async loadRange(start, end) { end = Math.min(end, await this.source._getSize()); const matchingLoadingSegment = this.loadingSegments.find((x) => x.start <= start && x.end >= end); @@ -4334,8 +4304,8 @@ ${cue.notes ?? ""}`; var IsobmffReader = class { constructor(reader) { this.reader = reader; + this.pos = 0; } - pos = 0; readRange(start, end) { const { view: view2, offset } = this.reader.getViewAndOffset(start, end); return new Uint8Array(view2.buffer, offset, end - start); @@ -4425,20 +4395,18 @@ ${cue.notes ?? ""}`; // src/isobmff/isobmff-demuxer.ts var knownMatrixes = [rotationMatrix(0), rotationMatrix(90), rotationMatrix(180), rotationMatrix(270)]; var IsobmffDemuxer = class extends Demuxer { - isobmffReader; - currentTrack = null; - tracks = []; - metadataPromise = null; - movieTimescale = -1; - movieDurationInTimescale = -1; - isFragmented = false; - fragmentTrackDefaults = []; - fragments = []; - currentFragment = null; - fragmentLookupMutex = new AsyncMutex(); - chunkReader; constructor(input) { super(input); + this.currentTrack = null; + this.tracks = []; + this.metadataPromise = null; + this.movieTimescale = -1; + this.movieDurationInTimescale = -1; + this.isFragmented = false; + this.fragmentTrackDefaults = []; + this.fragments = []; + this.currentFragment = null; + this.fragmentLookupMutex = new AsyncMutex(); this.isobmffReader = new IsobmffReader(input._mainReader); this.chunkReader = new IsobmffReader(new Reader(input._source, 64 * 2 ** 20)); } @@ -5370,9 +5338,9 @@ ${cue.notes ?? ""}`; var IsobmffTrackBacking = class { constructor(internalTrack) { this.internalTrack = internalTrack; + this.chunkToSampleIndex = /* @__PURE__ */ new WeakMap(); + this.chunkToFragmentLocation = /* @__PURE__ */ new WeakMap(); } - chunkToSampleIndex = /* @__PURE__ */ new WeakMap(); - chunkToFragmentLocation = /* @__PURE__ */ new WeakMap(); getCodec() { throw new Error("Not implemented on base class."); } @@ -5645,7 +5613,7 @@ ${cue.notes ?? ""}`; if (fragmentIndex !== -1) { const fragment = this.internalTrack.fragments[fragmentIndex]; const trackData = fragment.trackData.get(this.internalTrack.id); - const index = trackData.presentationTimestamps.findLastIndex((x) => { + const index = findLastIndex(trackData.presentationTimestamps, (x) => { const sample = trackData.samples[x.sampleIndex]; return sample.isKeyFrame && x.presentationTimestamp <= timestampInTimescale; }); @@ -5745,7 +5713,6 @@ ${cue.notes ?? ""}`; } }; var IsobmffVideoTrackBacking = class extends IsobmffTrackBacking { - internalTrack; constructor(internalTrack) { super(internalTrack); this.internalTrack = internalTrack; @@ -5753,10 +5720,10 @@ ${cue.notes ?? ""}`; async getCodec() { return this.internalTrack.info.codec; } - async getWidth() { + async getCodedWidth() { return this.internalTrack.info.width; } - async getHeight() { + async getCodedHeight() { return this.internalTrack.info.height; } async getRotation() { @@ -5781,7 +5748,6 @@ ${cue.notes ?? ""}`; } }; var IsobmffAudioTrackBacking = class extends IsobmffTrackBacking { - internalTrack; constructor(internalTrack) { super(internalTrack); this.internalTrack = internalTrack; @@ -5896,10 +5862,6 @@ ${cue.notes ?? ""}`; } }; - // src/matroska/matroska-demuxer.ts - var MatroskaDemuxer = class extends Demuxer { - }; - // src/input-format.ts var InputFormat = class { }; @@ -5915,6 +5877,7 @@ ${cue.notes ?? ""}`; const fourCc = isobmffReader.readAscii(4); return fourCc === "ftyp"; } + /** @internal */ _createDemuxer(input) { return new IsobmffDemuxer(input); } @@ -5924,8 +5887,9 @@ ${cue.notes ?? ""}`; async _canReadInput() { return false; } - _createDemuxer(input) { - return new MatroskaDemuxer(input); + /** @internal */ + _createDemuxer() { + throw new Error("Not implemented"); } }; var ISOBMFF = new IsobmffInputFormat(); @@ -5938,17 +5902,11 @@ ${cue.notes ?? ""}`; // src/input.ts var Input = class { - /** @internal */ - _source; - /** @internal */ - _formats; - /** @internal */ - _mainReader; - /** @internal */ - _demuxerPromise = null; - /** @internal */ - _format = null; constructor(options) { + /** @internal */ + this._demuxerPromise = null; + /** @internal */ + this._format = null; this._formats = options.formats; this._source = options.source; this._mainReader = new Reader(options.source); @@ -6053,7 +6011,8 @@ ${cue.notes ?? ""}`; } }; var BaseMediaFrameDrain = class { - duplicateFrame(frame) { + /** @internal */ + _duplicateFrame(frame) { return structuredClone(frame); } async *mediaFramesAtTimestamps(timestamps) { @@ -6071,7 +6030,7 @@ ${cue.notes ?? ""}`; onQueueNotEmpty(); ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers()); }; - const decoder = await this.createDecoder((frame) => { + const decoder = await this._createDecoder((frame) => { onQueueDequeue(); if (ended) { frame.close(); @@ -6079,7 +6038,7 @@ ${cue.notes ?? ""}`; } let frameUsed = false; while (timestampsOfInterest.length > 0 && timestampsOfInterest[0] === frame.timestamp) { - pushToQueue(this.duplicateFrame(frame)); + pushToQueue(this._duplicateFrame(frame)); timestampsOfInterest.shift(); frameUsed = true; } @@ -6091,7 +6050,7 @@ ${cue.notes ?? ""}`; } }); void (async () => { - const chunkDrain = this.createChunkDrain(); + const chunkDrain = this._createChunkDrain(); let lastKeyChunk = null; let lastChunk = null; for await (const timestamp of timestampIterator) { @@ -6117,7 +6076,7 @@ ${cue.notes ?? ""}`; assert(lastChunk); if (targetChunk.timestamp === lastChunk.timestamp && timestampsOfInterest.length === 1) { if (lastUsedFrame) { - pushToQueue(this.duplicateFrame(lastUsedFrame)); + pushToQueue(this._duplicateFrame(lastUsedFrame)); } timestampsOfInterest.shift(); } @@ -6172,7 +6131,7 @@ ${cue.notes ?? ""}`; let decoderIsFlushed = false; let ended = false; const MAX_QUEUE_SIZE = 8; - const decoder = await this.createDecoder((frame) => { + const decoder = await this._createDecoder((frame) => { onQueueDequeue(); const frameTimestamp = frame.timestamp / 1e6; if (frameTimestamp >= endTimestamp) { @@ -6200,7 +6159,7 @@ ${cue.notes ?? ""}`; ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers()); } }); - const chunkDrain = this.createChunkDrain(); + const chunkDrain = this._createChunkDrain(); const keyChunk = await chunkDrain.getKeyChunk(startTimestamp) ?? await chunkDrain.getFirstChunk(); if (!keyChunk) { return; @@ -6262,41 +6221,44 @@ ${cue.notes ?? ""}`; var EncodedVideoChunkDrain = class extends BaseChunkDrain { constructor(videoTrack) { super(); - this.videoTrack = videoTrack; + this._videoTrack = videoTrack; } getFirstChunk(options = {}) { - return this.videoTrack._backing.getFirstChunk(options); + return this._videoTrack._backing.getFirstChunk(options); } getChunk(timestamp, options = {}) { - return this.videoTrack._backing.getChunk(timestamp, options); + return this._videoTrack._backing.getChunk(timestamp, options); } getNextChunk(chunk, options = {}) { - return this.videoTrack._backing.getNextChunk(chunk, options); + return this._videoTrack._backing.getNextChunk(chunk, options); } getKeyChunk(timestamp, options = {}) { - return this.videoTrack._backing.getKeyChunk(timestamp, options); + return this._videoTrack._backing.getKeyChunk(timestamp, options); } getNextKeyChunk(chunk, options = {}) { - return this.videoTrack._backing.getNextKeyChunk(chunk, options); + return this._videoTrack._backing.getNextKeyChunk(chunk, options); } }; var VideoFrameDrain = class extends BaseMediaFrameDrain { constructor(videoTrack) { super(); - this.videoTrack = videoTrack; + /** @internal */ + this._decoderConfig = null; + this._videoTrack = videoTrack; } - decoderConfig = null; - async createDecoder(onFrame) { - this.decoderConfig ??= await this.videoTrack.getDecoderConfig(); + /** @internal */ + async _createDecoder(onFrame) { + this._decoderConfig ??= await this._videoTrack.getDecoderConfig(); const decoder = new VideoDecoder({ output: onFrame, error: (error) => console.error(error) }); - decoder.configure(this.decoderConfig); + decoder.configure(this._decoderConfig); return decoder; } - createChunkDrain() { - return new EncodedVideoChunkDrain(this.videoTrack); + /** @internal */ + _createChunkDrain() { + return new EncodedVideoChunkDrain(this._videoTrack); } async getFrame(timestamp) { for await (const frame of this.mediaFramesAtTimestamps([timestamp])) { @@ -6313,15 +6275,15 @@ ${cue.notes ?? ""}`; }; var CanvasDrain = class { constructor(videoTrack, dimensions) { - this.videoTrack = videoTrack; - this.dimensions = dimensions; - this.videoFrameDrain = new VideoFrameDrain(videoTrack); + this._videoTrack = videoTrack; + this._dimensions = dimensions; + this._videoFrameDrain = new VideoFrameDrain(videoTrack); } - videoFrameDrain; - async videoFrameToWrappedCanvas(frame) { - const width = this.dimensions?.width ?? await this.videoTrack.getRotatedWidth(); - const height = this.dimensions?.height ?? await this.videoTrack.getRotatedHeight(); - const rotation = await this.videoTrack.getRotation(); + /** @internal */ + async _videoFrameToWrappedCanvas(frame) { + const width = this._dimensions?.width ?? await this._videoTrack.getDisplayWidth(); + const height = this._dimensions?.height ?? await this._videoTrack.getDisplayHeight(); + const rotation = await this._videoTrack.getRotation(); const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; @@ -6341,58 +6303,61 @@ ${cue.notes ?? ""}`; return result; } async getCanvas(timestamp) { - const frame = await this.videoFrameDrain.getFrame(timestamp); - return frame && this.videoFrameToWrappedCanvas(frame); + const frame = await this._videoFrameDrain.getFrame(timestamp); + return frame && this._videoFrameToWrappedCanvas(frame); } async *canvases(startTimestamp = 0, endTimestamp = Infinity) { - for await (const frame of this.videoFrameDrain.frames(startTimestamp, endTimestamp)) { - yield this.videoFrameToWrappedCanvas(frame); + for await (const frame of this._videoFrameDrain.frames(startTimestamp, endTimestamp)) { + yield this._videoFrameToWrappedCanvas(frame); } } async *canvasesAtTimestamps(timestamps) { - for await (const frame of this.videoFrameDrain.framesAtTimestamps(timestamps)) { - yield frame && this.videoFrameToWrappedCanvas(frame); + for await (const frame of this._videoFrameDrain.framesAtTimestamps(timestamps)) { + yield frame && this._videoFrameToWrappedCanvas(frame); } } }; var EncodedAudioChunkDrain = class extends BaseChunkDrain { constructor(audioTrack) { super(); - this.audioTrack = audioTrack; + this._audioTrack = audioTrack; } getFirstChunk(options = {}) { - return this.audioTrack._backing.getFirstChunk(options); + return this._audioTrack._backing.getFirstChunk(options); } getChunk(timestamp, options = {}) { - return this.audioTrack._backing.getChunk(timestamp, options); + return this._audioTrack._backing.getChunk(timestamp, options); } getNextChunk(chunk, options = {}) { - return this.audioTrack._backing.getNextChunk(chunk, options); + return this._audioTrack._backing.getNextChunk(chunk, options); } getKeyChunk(timestamp, options = {}) { - return this.audioTrack._backing.getKeyChunk(timestamp, options); + return this._audioTrack._backing.getKeyChunk(timestamp, options); } getNextKeyChunk(chunk, options = {}) { - return this.audioTrack._backing.getNextKeyChunk(chunk, options); + return this._audioTrack._backing.getNextKeyChunk(chunk, options); } }; var AudioDataDrain = class extends BaseMediaFrameDrain { constructor(audioTrack) { super(); - this.audioTrack = audioTrack; + /** @internal */ + this._decoderConfig = null; + this._audioTrack = audioTrack; } - decoderConfig = null; - async createDecoder(onData) { - this.decoderConfig ??= await this.audioTrack.getDecoderConfig(); + /** @internal */ + async _createDecoder(onData) { + this._decoderConfig ??= await this._audioTrack.getDecoderConfig(); const decoder = new AudioDecoder({ output: onData, error: (error) => console.error(error) }); - decoder.configure(this.decoderConfig); + decoder.configure(this._decoderConfig); return decoder; } - createChunkDrain() { - return new EncodedAudioChunkDrain(this.audioTrack); + /** @internal */ + _createChunkDrain() { + return new EncodedAudioChunkDrain(this._audioTrack); } async getData(timestamp) { for await (const data of this.mediaFramesAtTimestamps([timestamp])) { @@ -6409,11 +6374,10 @@ ${cue.notes ?? ""}`; }; var AudioBufferDrain = class { constructor(audioTrack) { - this.audioTrack = audioTrack; - this.audioDataDrain = new AudioDataDrain(audioTrack); + this._audioDataDrain = new AudioDataDrain(audioTrack); } - audioDataDrain; - audioDataToWrappedArrayBuffer(data) { + /** @internal */ + _audioDataToWrappedArrayBuffer(data) { const audioBuffer = new AudioBuffer({ numberOfChannels: data.numberOfChannels, length: data.numberOfFrames, @@ -6434,17 +6398,17 @@ ${cue.notes ?? ""}`; return result; } async getBuffer(timestamp) { - const data = await this.audioDataDrain.getData(timestamp); - return data && this.audioDataToWrappedArrayBuffer(data); + const data = await this._audioDataDrain.getData(timestamp); + return data && this._audioDataToWrappedArrayBuffer(data); } async *buffers(startTimestamp = 0, endTimestamp = Infinity) { - for await (const data of this.audioDataDrain.data(startTimestamp, endTimestamp)) { - yield this.audioDataToWrappedArrayBuffer(data); + for await (const data of this._audioDataDrain.data(startTimestamp, endTimestamp)) { + yield this._audioDataToWrappedArrayBuffer(data); } } async *buffersAtTimestamps(timestamps) { - for await (const data of this.audioDataDrain.dataAtTimestamps(timestamps)) { - yield data && this.audioDataToWrappedArrayBuffer(data); + for await (const data of this._audioDataDrain.dataAtTimestamps(timestamps)) { + yield data && this._audioDataToWrappedArrayBuffer(data); } } }; diff --git a/dist/metamuxer.min.js b/dist/metamuxer.min.js index 35fd022..3376f62 100644 --- a/dist/metamuxer.min.js +++ b/dist/metamuxer.min.js @@ -1,10 +1,10 @@ -"use strict";var Metamuxer=(()=>{var bt=Object.defineProperty;var xr=Object.getOwnPropertyDescriptor;var Cr=Object.getOwnPropertyNames;var Sr=Object.prototype.hasOwnProperty;var wr=(i,e)=>{for(var t in e)bt(i,t,{get:e[t],enumerable:!0})},yr=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Cr(e))!Sr.call(i,s)&&s!==t&&bt(i,s,{get:()=>e[s],enumerable:!(r=xr(e,s))||r.enumerable});return i};var vr=i=>yr(bt({},"__esModule",{value:!0}),i);var Pi={};wr(Pi,{ALL_FORMATS:()=>kr,AUDIO_CODECS:()=>J,ArrayBufferSource:()=>rt,ArrayBufferTarget:()=>ce,AudioBufferDrain:()=>pt,AudioBufferSource:()=>Ze,AudioDataDrain:()=>Oe,AudioDataSource:()=>Ye,AudioSource:()=>W,BlobSource:()=>it,CanvasDrain:()=>ft,CanvasSource:()=>qe,EncodedAudioChunkDrain:()=>Re,EncodedAudioChunkSource:()=>Ge,EncodedVideoChunkDrain:()=>Ie,EncodedVideoChunkSource:()=>$e,ISOBMFF:()=>ve,Input:()=>mt,MATROSKA:()=>ut,MKV:()=>Mt,MOV:()=>br,MP4:()=>hr,MediaSource:()=>te,MediaStreamAudioTrackSource:()=>Je,MediaStreamVideoTrackSource:()=>Xe,MkvOutputFormat:()=>xe,Mp4OutputFormat:()=>Ke,Output:()=>tt,OutputFormat:()=>K,SUBTITLE_CODECS:()=>ge,Source:()=>me,StreamTarget:()=>Be,SubtitleSource:()=>re,Target:()=>Q,TextSubtitleSource:()=>et,VIDEO_CODECS:()=>Z,VideoFrameDrain:()=>Ae,VideoFrameSource:()=>je,VideoSource:()=>B,WEBM:()=>gr,WebMOutputFormat:()=>ee});function l(i){if(!i)throw new Error("Assertion failed.")}var _=i=>i&&i[i.length-1],$=i=>i>=0&&i<2**32,E=(i,e,t)=>{let r=0;for(let s=e;s>c;r<<=1,r|=o}return r},Vt=(i,e,t,r)=>{for(let s=e;s>t-s-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),D=new TextEncoder,gt=i=>Object.fromEntries(Object.entries(i).map(([e,t])=>[t,e])),q={bt709:1,bt470bg:5,smpte170m:6},Dt=gt(q),X={bt709:1,smpte170m:6,"iec61966-2-1":13},Pt=gt(X),G={rgb:0,bt709:1,bt470bg:5,smpte170m:6},zt=gt(G),Ee=i=>!!i&&!!i.primaries&&!!i.transfer&&!!i.matrix&&i.fullRange!==void 0,kt=i=>i instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&i instanceof SharedArrayBuffer||ArrayBuffer.isView(i)&&!(i instanceof DataView),H=class{currentPromise=Promise.resolve();async acquire(){let e,t=new Promise(s=>{e=s}),r=this.currentPromise;return this.currentPromise=t,await r,e}},L=i=>{let e=i*(Math.PI/180),t=Math.cos(e),r=Math.sin(e);return[t,r,0,-r,t,0,0,0,1]},Tt=L(0),Ut=i=>[...i].map(e=>e.toString(16).padStart(2,"0")).join(""),Bt=i=>(i=i>>1&1431655765|(i&1431655765)<<1,i=i>>2&858993459|(i&858993459)<<2,i=i>>4&252645135|(i&252645135)<<4,i=i>>8&16711935|(i&16711935)<<8,i=i>>16&65535|(i&65535)<<16,i>>>0),N=(i,e,t)=>{let r=0,s=i.length-1,a=-1;for(;r<=s;){let n=r+s>>1,c=t(i[n]);c===e?(a=n,s=n-1):c{let r=-1,s=0,a=i.length-1;for(;s<=a;){let n=s+(a-s+1)/2|0;t(i[n])<=e?(r=n,s=n+1):a=n-1}return r},F=()=>{let i,e;return{promise:new Promise((r,s)=>{i=r,e=s}),resolve:i,reject:e}},Wt=(i,e)=>{let t=i.indexOf(e);t!==-1&&i.splice(t,1)},Nt=async function*(i){Symbol.iterator in i?yield*i[Symbol.iterator]():yield*i[Symbol.asyncIterator]()};var fe=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,Ir=/^WEBVTT(.|\n)*?\n{2}/,ae=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,Fe=class{options;preambleText=null;preambleEmitted=!1;constructor(e){this.options=e}parse(e){e=e.replaceAll(`\r +"use strict";var Metamuxer=(()=>{var gt=Object.defineProperty;var Cr=Object.getOwnPropertyDescriptor;var Sr=Object.getOwnPropertyNames;var wr=Object.prototype.hasOwnProperty;var yr=(i,t)=>{for(var e in t)gt(i,e,{get:t[e],enumerable:!0})},vr=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Sr(t))!wr.call(i,s)&&s!==e&>(i,s,{get:()=>t[s],enumerable:!(r=Cr(t,s))||r.enumerable});return i};var _r=i=>vr(gt({},"__esModule",{value:!0}),i);var zi={};yr(zi,{ALL_FORMATS:()=>Tr,AUDIO_CODECS:()=>ee,ArrayBufferSource:()=>ct,ArrayBufferTarget:()=>me,AudioBufferDrain:()=>bt,AudioBufferSource:()=>st,AudioDataDrain:()=>Ve,AudioDataSource:()=>it,AudioSource:()=>N,BaseChunkDrain:()=>be,BaseMediaFrameDrain:()=>ke,BlobSource:()=>ut,CanvasDrain:()=>ht,CanvasSource:()=>et,EncodedAudioChunkDrain:()=>Me,EncodedAudioChunkSource:()=>rt,EncodedVideoChunkDrain:()=>Ee,EncodedVideoChunkSource:()=>Ze,ISOBMFF:()=>Oe,Input:()=>pt,InputAudioTrack:()=>ae,InputFormat:()=>he,InputTrack:()=>fe,InputVideoTrack:()=>se,IsobmffInputFormat:()=>Ae,MATROSKA:()=>ft,MKV:()=>Mt,MOV:()=>kr,MP4:()=>br,MatroskaInputFormat:()=>Re,MediaSource:()=>re,MediaStreamAudioTrackSource:()=>at,MediaStreamVideoTrackSource:()=>tt,MkvOutputFormat:()=>ve,Mp4OutputFormat:()=>Ye,Output:()=>ot,OutputFormat:()=>$,SUBTITLE_CODECS:()=>Se,Source:()=>le,StreamTarget:()=>Ke,SubtitleSource:()=>ie,Target:()=>K,TextSubtitleSource:()=>nt,VIDEO_CODECS:()=>J,VideoFrameDrain:()=>Fe,VideoFrameSource:()=>Je,VideoSource:()=>W,WEBM:()=>gr,WebMOutputFormat:()=>te});function d(i){if(!i)throw new Error("Assertion failed.")}var R=i=>i&&i[i.length-1],j=i=>i>=0&&i<2**32,O=(i,t,e)=>{let r=0;for(let s=t;s>o;r<<=1,r|=c}return r},Vt=(i,t,e,r)=>{for(let s=t;s>e-s-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),D=new TextEncoder,Tt=i=>Object.fromEntries(Object.entries(i).map(([t,e])=>[e,t])),X={bt709:1,bt470bg:5,smpte170m:6},Dt=Tt(X),G={bt709:1,smpte170m:6,"iec61966-2-1":13},Pt=Tt(G),Y={rgb:0,bt709:1,bt470bg:5,smpte170m:6},zt=Tt(Y),ze=i=>!!i&&!!i.primaries&&!!i.transfer&&!!i.matrix&&i.fullRange!==void 0,xt=i=>i instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&i instanceof SharedArrayBuffer||ArrayBuffer.isView(i)&&!(i instanceof DataView),L=class{constructor(){this.currentPromise=Promise.resolve()}async acquire(){let t,e=new Promise(s=>{t=s}),r=this.currentPromise;return this.currentPromise=e,await r,t}},Q=i=>{let t=i*(Math.PI/180),e=Math.cos(t),r=Math.sin(t);return[e,r,0,-r,e,0,0,0,1]},Ct=Q(0),Ut=i=>[...i].map(t=>t.toString(16).padStart(2,"0")).join(""),Bt=i=>(i=i>>1&1431655765|(i&1431655765)<<1,i=i>>2&858993459|(i&858993459)<<2,i=i>>4&252645135|(i&252645135)<<4,i=i>>8&16711935|(i&16711935)<<8,i=i>>16&65535|(i&65535)<<16,i>>>0),H=(i,t,e)=>{let r=0,s=i.length-1,a=-1;for(;r<=s;){let n=r+s>>1,o=e(i[n]);o===t?(a=n,s=n-1):o{let r=-1,s=0,a=i.length-1;for(;s<=a;){let n=s+(a-s+1)/2|0;e(i[n])<=t?(r=n,s=n+1):a=n-1}return r},E=()=>{let i,t;return{promise:new Promise((r,s)=>{i=r,t=s}),resolve:i,reject:t}},Wt=(i,t)=>{let e=i.indexOf(t);e!==-1&&i.splice(e,1)},Nt=(i,t)=>{for(let e=i.length-1;e>=0;e--)if(t(i[e]))return e;return-1},Ht=async function*(i){Symbol.iterator in i?yield*i[Symbol.iterator]():yield*i[Symbol.asyncIterator]()};var ge=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,Ir=/^WEBVTT(.|\n)*?\n{2}/,oe=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,Ue=class{constructor(t){this.preambleText=null;this.preambleEmitted=!1;this.options=t}parse(t){t=t.replaceAll(`\r `,` `).replaceAll("\r",` -`),fe.lastIndex=0;let t;if(!this.preambleText){if(!Ir.test(e)){let s=new Error("WebVTT preamble incorrect.");throw this.options.error(s),s}t=fe.exec(e);let r=e.slice(0,t?.index??e.length).trimEnd();if(!r){let s=new Error("No WebVTT preamble provided.");throw this.options.error(s),s}this.preambleText=r,t&&(e=e.slice(t.index),fe.lastIndex=0)}for(;t=fe.exec(e);){let r=e.slice(0,t.index),s=t[1],a=t.index+t[0].length,n=e.indexOf(` -`,a)+1,c=e.slice(a,n).trim(),o=e.indexOf(` +`),ge.lastIndex=0;let e;if(!this.preambleText){if(!Ir.test(t)){let s=new Error("WebVTT preamble incorrect.");throw this.options.error(s),s}e=ge.exec(t);let r=t.slice(0,e?.index??t.length).trimEnd();if(!r){let s=new Error("No WebVTT preamble provided.");throw this.options.error(s),s}this.preambleText=r,e&&(t=t.slice(e.index),ge.lastIndex=0)}for(;e=ge.exec(t);){let r=t.slice(0,e.index),s=e[1],a=e.index+e[0].length,n=t.indexOf(` +`,a)+1,o=t.slice(a,n).trim(),c=t.indexOf(` -`,a);o===-1&&(o=e.length);let u=Me(t[2]),d=Me(t[3])-u,h=e.slice(n,o).trim();e=e.slice(o).trimStart(),fe.lastIndex=0;let g={timestamp:u/1e3,duration:d/1e3,text:h,identifier:s,settings:c,notes:r},b={};this.preambleEmitted||(b.config={description:this.preambleText},this.preambleEmitted=!0),this.options.output(g,b)}}},Ar=/(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/,Me=i=>{let e=Ar.exec(i);if(!e)throw new Error("Expected match.");return 60*60*1e3*Number(e[1]||"0")+60*1e3*Number(e[2])+1e3*Number(e[3])+Number(e[4])},Ve=i=>{let e=Math.floor(i/36e5),t=Math.floor(i%(60*60*1e3)/(60*1e3)),r=Math.floor(i%(60*1e3)/1e3),s=i%1e3;return e.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+":"+r.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")};var pe=class{constructor(e){this.writer=e}helper=new Uint8Array(8);helperView=new DataView(this.helper.buffer);offsets=new WeakMap;writeU32(e){this.helperView.setUint32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(e){this.helperView.setUint32(0,Math.floor(e/2**32),!1),this.helperView.setUint32(4,e,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(e){for(let t=0;t[(i%256+256)%256],x=i=>(U.setUint16(0,i,!1),[T[0],T[1]]),Rr=i=>(U.setInt16(0,i,!1),[T[0],T[1]]),Lt=i=>(U.setUint32(0,i,!1),[T[1],T[2],T[3]]),p=i=>(U.setUint32(0,i,!1),[T[0],T[1],T[2],T[3]]),Qt=i=>(U.setInt32(0,i,!1),[T[0],T[1],T[2],T[3]]),Y=i=>(U.setUint32(0,Math.floor(i/2**32),!1),U.setUint32(4,i,!1),[T[0],T[1],T[2],T[3],T[4],T[5],T[6],T[7]]),St=i=>(U.setInt16(0,2**8*i,!1),[T[0],T[1]]),z=i=>(U.setInt32(0,2**16*i,!1),[T[0],T[1],T[2],T[3]]),xt=i=>(U.setInt32(0,2**30*i,!1),[T[0],T[1],T[2],T[3]]),Ct=(i,e)=>{let t=[],r=i;do{let s=r&127;r>>=7,t.length>0&&(s|=128),t.push(s),e!==void 0&&e--}while(r>0||e);return t.reverse()},M=(i,e=!1)=>{let t=Array(i.length).fill(null).map((r,s)=>i.charCodeAt(s));return e&&t.push(0),t},wt=i=>{let e=null;for(let t of i)(!e||t.timestamp>e.timestamp)&&(e=t);return e},Kt=i=>[z(i[0]),z(i[1]),xt(i[2]),z(i[3]),z(i[4]),xt(i[5]),z(i[6]),z(i[7]),xt(i[8])],S=(i,e,t)=>({type:i,contents:e&&new Uint8Array(e.flat(10)),children:t}),y=(i,e,t,r,s)=>S(i,[I(e),Lt(t),r??[]],s),$t=i=>i.fragmented?S("ftyp",[M("iso5"),p(512),M("iso5"),M("iso6"),M("mp41")]):S("ftyp",[M("isom"),p(512),M("isom"),i.holdsAvc?M("avc1"):[],M("mp41")]),Pe=i=>({type:"mdat",largeSize:i}),jt=i=>({type:"free",size:i}),he=(i,e,t=!1)=>S("moov",void 0,[Or(e,i),...i.map(r=>_r(r,e)),t?ui(i):null]),Or=(i,e)=>{let t=P(Math.max(0,...e.filter(n=>n.samples.length>0).map(n=>{let c=wt(n.samples);return c.timestamp+c.duration})),De),r=Math.max(0,...e.map(n=>n.track.id))+1,s=!$(i)||!$(t),a=s?Y:p;return y("mvhd",+s,0,[a(i),a(i),p(De),a(t),z(1),St(1),Array(10).fill(0),Kt(Tt),Array(24).fill(0),p(r)])},_r=(i,e)=>S("trak",void 0,[Er(i,e),Fr(i,e)]),Er=(i,e)=>{let t=wt(i.samples),r=P(t?t.timestamp+t.duration:0,De),s=!$(e)||!$(r),a=s?Y:p,n;if(i.type==="video"){let c=i.track.metadata.rotation;n=c===void 0||typeof c=="number"?L(c??0):c}else n=Tt;return y("tkhd",+s,3,[a(e),a(e),p(i.track.id),p(0),a(r),Array(8).fill(0),x(0),x(i.track.id),St(i.type==="audio"?1:0),x(0),Kt(n),z(i.type==="video"?i.info.width:0),z(i.type==="video"?i.info.height:0)])},Fr=(i,e)=>S("mdia",void 0,[Mr(i,e),Pr(i),zr(i)]),Mr=(i,e)=>{let t=wt(i.samples),r=P(t?t.timestamp+t.duration:0,i.timescale),s=!$(e)||!$(r),a=s?Y:p;return y("mdhd",+s,0,[a(e),a(e),p(i.timescale),a(r),x(21956),x(0)])},Vr={video:"vide",audio:"soun",subtitle:"text"},Dr={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},Pr=i=>y("hdlr",0,0,[M("mhlr"),M(Vr[i.type]),p(0),p(0),p(0),M(Dr[i.type],!0)]),zr=i=>S("minf",void 0,[Nr[i.type](),Hr(),Kr(i)]),Ur=()=>y("vmhd",0,1,[x(0),x(0),x(0),x(0)]),Br=()=>y("smhd",0,0,[x(0),x(0)]),Wr=()=>y("nmhd",0,0),Nr={video:Ur,audio:Br,subtitle:Wr},Hr=()=>S("dinf",void 0,[Lr()]),Lr=()=>y("dref",0,0,[p(1)],[Qr()]),Qr=()=>y("url ",0,1),Kr=i=>{let e=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(t=>t.sampleCompositionTimeOffset!==0);return S("stbl",void 0,[$r(i),ii(i),si(i),ai(i),ni(i),oi(i),e?ci(i):null])},$r=i=>{let e;return i.type==="video"?e=jr(ki[i.track.source._codec],i):i.type==="audio"?e=Zr(xi[i.track.source._codec],i):i.type==="subtitle"&&(e=ti(Si[i.track.source._codec],i)),l(e),y("stsd",0,0,[p(1)],[e])},jr=(i,e)=>S(i,[Array(6).fill(0),x(1),x(0),x(0),Array(12).fill(0),x(e.info.width),x(e.info.height),p(4718592),p(4718592),p(0),x(1),Array(32).fill(0),x(24),Rr(65535)],[Ti[e.track.source._codec](e),Ee(e.info.decoderConfig.colorSpace)?qr(e):null]),qr=i=>S("colr",[M("nclx"),x(q[i.info.decoderConfig.colorSpace.primaries]),x(X[i.info.decoderConfig.colorSpace.transfer]),x(G[i.info.decoderConfig.colorSpace.matrix]),I((i.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),Xr=i=>i.info.decoderConfig&&S("avcC",[...j(i.info.decoderConfig.description)]),Gr=i=>i.info.decoderConfig&&S("hvcC",[...j(i.info.decoderConfig.description)]),Ht=i=>{if(!i.info.decoderConfig)return null;let e=i.info.decoderConfig;l(e.colorSpace);let t=e.codec.split("."),r=Number(t[1]),s=Number(t[2]),c=(Number(t[3])<<4)+(0<<1)+Number(e.colorSpace.fullRange);return y("vpcC",1,0,[I(r),I(s),I(c),I(2),I(2),I(2),x(0)])},Yr=()=>S("av1C",[129,0,0,0]),Zr=(i,e)=>S(i,[Array(6).fill(0),x(1),x(0),x(0),p(0),x(e.info.numberOfChannels),x(16),x(0),x(0),z(e.info.sampleRate)],[Ci[e.track.source._codec](e)]),Jr=i=>{let t=[...j(i.info.decoderConfig.description??new ArrayBuffer(0))];return t=[...I(64),...I(21),...Lt(0),...p(0),...p(0),...I(5),...Ct(t.length),...t],t=[...x(1),...I(0),...I(4),...Ct(t.length),...t,...I(6),...I(1),...I(2)],t=[...I(3),...Ct(t.length),...t],y("esds",0,0,t)},ei=i=>{let e=3840,t=0,r=i.info.decoderConfig?.description;if(r){l(r.byteLength>=18);let s=ArrayBuffer.isView(r)?new DataView(r.buffer,r.byteOffset,r.byteLength):new DataView(r);e=s.getUint16(10,!0),t=s.getInt16(14,!0)}return S("dOps",[I(0),I(i.info.numberOfChannels),x(e),p(i.info.sampleRate),St(t),I(0)])},ti=(i,e)=>S(i,[Array(6).fill(0),x(1)],[wi[e.track.source._codec](e)]),ri=i=>S("vttC",[...D.encode(i.info.config.description)]);var ii=i=>y("stts",0,0,[p(i.timeToSampleTable.length),i.timeToSampleTable.map(e=>[p(e.sampleCount),p(e.sampleDelta)])]),si=i=>{if(i.samples.every(t=>t.type==="key"))return null;let e=[...i.samples.entries()].filter(([,t])=>t.type==="key");return y("stss",0,0,[p(e.length),e.map(([t])=>p(t+1))])},ai=i=>y("stsc",0,0,[p(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(e=>[p(e.firstChunk),p(e.samplesPerChunk),p(1)])]),ni=i=>y("stsz",0,0,[p(0),p(i.samples.length),i.samples.map(e=>p(e.size))]),oi=i=>i.finalizedChunks.length>0&&_(i.finalizedChunks).offset>=2**32?y("co64",0,0,[p(i.finalizedChunks.length),i.finalizedChunks.map(e=>Y(e.offset))]):y("stco",0,0,[p(i.finalizedChunks.length),i.finalizedChunks.map(e=>p(e.offset))]),ci=i=>y("ctts",0,0,[p(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(e=>[p(e.sampleCount),p(e.sampleCompositionTimeOffset)])]),ui=i=>S("mvex",void 0,i.map(mi)),mi=i=>y("trex",0,0,[p(i.track.id),p(1),p(0),p(0),p(0)]),yt=(i,e)=>S("moof",void 0,[li(i),...e.map(di)]),li=i=>y("mfhd",0,0,[p(i)]),qt=i=>{let e=0,t=0,r=0,s=0,a=i.type==="delta";return t|=+a,a?e|=1:e|=2,e<<24|t<<16|r<<8|s},di=i=>S("traf",void 0,[fi(i),pi(i),hi(i)]),fi=i=>{l(i.currentChunk);let e=0;e|=8,e|=16,e|=32,e|=131072;let t=i.currentChunk.samples[1]??i.currentChunk.samples[0],r={duration:t.timescaleUnitsToNextSample,size:t.size,flags:qt(t)};return y("tfhd",0,e,[p(i.track.id),p(r.duration),p(r.size),p(r.flags)])},pi=i=>(l(i.currentChunk),y("tfdt",1,0,[Y(P(i.currentChunk.startTimestamp,i.timescale))])),hi=i=>{l(i.currentChunk);let e=i.currentChunk.samples.map(f=>f.timescaleUnitsToNextSample),t=i.currentChunk.samples.map(f=>f.size),r=i.currentChunk.samples.map(qt),s=i.currentChunk.samples.map(f=>P(f.timestamp-f.decodeTimestamp,i.timescale)),a=new Set(e),n=new Set(t),c=new Set(r),o=new Set(s),u=c.size===2&&r[0]!==r[1],m=a.size>1,d=n.size>1,h=!u&&c.size>1,g=o.size>1||[...o].some(f=>f!==0),b=0;return b|=1,b|=4*+u,b|=256*+m,b|=512*+d,b|=1024*+h,b|=2048*+g,y("trun",1,b,[p(i.currentChunk.samples.length),p(i.currentChunk.offset-i.currentChunk.moofOffset||0),u?p(r[0]):[],i.currentChunk.samples.map((f,k)=>[m?p(e[k]):[],d?p(t[k]):[],h?p(r[k]):[],g?Qt(s[k]):[]])])},Xt=i=>S("mfra",void 0,[...i.map(bi),gi()]),bi=(i,e)=>y("tfra",1,0,[p(i.track.id),p(63),p(i.finalizedChunks.length),i.finalizedChunks.map(r=>[Y(P(r.samples[0].timestamp,i.timescale)),Y(r.moofOffset),p(e+1),p(1),p(1)])]),gi=()=>y("mfro",0,0,[p(0)]),Gt=()=>S("vtte"),Yt=(i,e,t,r,s)=>S("vttc",void 0,[s!==null?S("vsid",[Qt(s)]):null,t!==null?S("iden",[...D.encode(t)]):null,e!==null?S("ctim",[...D.encode(Ve(e))]):null,r!==null?S("sttg",[...D.encode(r)]):null,S("payl",[...D.encode(i)])]),Zt=i=>S("vtta",[...D.encode(i)]),ki={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},Ti={avc:Xr,hevc:Gr,vp8:Ht,vp9:Ht,av1:Yr},xi={aac:"mp4a",opus:"Opus"},Ci={aac:Jr,opus:ei},Si={webvtt:"wvtt"},wi={webvtt:ri};var ne=class{output;mutex=new H;constructor(e){this.output=e}beforeTrackAdd(e){}onTrackClose(e){}trackTimestampInfo=new WeakMap;validateAndNormalizeTimestamp(e,t,r){let s=t/1e6,a=this.trackTimestampInfo.get(e);if(!a){if(!r)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&s>0)throw new Error(`Timestamps must start at zero (got ${s}s).`);a={timestampOffset:s,maxTimestamp:e.source._offsetTimestamps?0:s,lastKeyFrameTimestamp:e.source._offsetTimestamps?0:s},this.trackTimestampInfo.set(e,a)}if(e.source._offsetTimestamps&&(s-=a.timestampOffset),s<0)throw new Error(`Timestamps must be non-negative (got ${s}s).`);if(sr.start-s.start);e.push({start:t[0].start,size:t[0].data.byteLength});for(let r=1;ro.start<=t&&tvi){for(let o=0;o=e.written[a+1].start;)e.written[a].end=Math.max(e.written[a].end,e.written[a+1].end),e.written.splice(a+1,1)}createChunk(e){let r={start:Math.floor(e/this.chunkSize)*this.chunkSize,data:new Uint8Array(this.chunkSize),written:[],shouldFlush:!1};return this.chunks.push(r),this.chunks.sort((s,a)=>s.start-a.start),this.chunks.indexOf(r)}queueChunksForFlush(e=!1){l(this.writer);for(let t=0;t{if(i==="avc"){let a=Math.ceil(e/16)*Math.ceil(t/16),n=Jt.find(d=>a<=d.maxMacroblocks&&r<=d.maxBitrate)??_(Jt),c=n?n.level:0,o="64".padStart(2,"0"),u="00",m=c.toString(16).padStart(2,"0");return`avc1.${o}${u}${m}`}else if(i==="hevc"){let s="",n="6",c=e*t,o=er.find(m=>c<=m.maxPictureSize&&r<=m.maxBitrate)??_(er);return`hev1.${s}1.${n}.${o.tier}${o.level}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let s="00",a=e*t,n=tr.find(o=>a<=o.maxPictureSize&&r<=o.maxBitrate)??_(tr);return`vp09.${s}.${n.level}.08`}else if(i==="av1"){let a=e*t,n=rr.find(o=>a<=o.maxPictureSize&&r<=o.maxBitrate)??_(rr);return`av01.0.${n.level.toString().padStart(2,"0")}${n.tier}.08`}}throw new TypeError(`Unhandled codec '${i}'.`)},sr=(i,e)=>{if(i==="avc"){if(!e||e.byteLength<4)throw new TypeError("AVC description must be at least 4 bytes long.");return`avc1.${Ut(e.subarray(1,4))}`}else if(i==="hevc"){if(!e)throw new TypeError("HEVC description must be provided.");let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r="hev1.",s=e[1]>>6&3,a=e[1]&31;r+=["","A","B","C"][s]+a,r+=".";let n=Bt(t.getUint32(2));r+=n.toString(16),r+=".";let c=e[1]>>5&1,o=e[12];r+=c===0?"L":"H",r+=o,r+=".";let u=[];for(let m=0;m<6;m++){let d=e[m+13];u.push(d)}for(;u[u.length-1]===0;)u.pop();return r+=u.map(m=>m.toString(16)).join("."),r}throw new TypeError(`Unhandled codec '${i}'.`)},ar=(i,e,t)=>{if(i==="aac")return e>=2&&t<=24e3?"mp4a.40.29":t<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},nr=(i,e)=>{if(i==="aac")return`mp4a.40.${vt(e).objectType}`;if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},vt=i=>{if(!i||i.byteLength<2)throw new TypeError("AAC description must be at least 2 bytes long.");let e=0,t=E(i,e,e+5);e+=5,t===31&&(t=32+E(i,e,e+6),e+=6);let r=E(i,e,e+4);e+=4;let s=null;if(r===15)s=E(i,e,e+24),e+=24;else{let c=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];r=1&&a<=7&&(n={1:1,2:2,3:3,4:4,5:5,6:6,7:8}[a]),{objectType:t,frequencyIndex:r,sampleRate:s,channelConfiguration:a,numberOfChannels:n}},or=i=>i==="avc"?{avc:{format:"avc"}}:i==="hevc"?{hevc:{format:"hevc"}}:{},cr=i=>i==="aac"?{aac:{format:"aac"}}:i==="opus"?{opus:{format:"opus"}}:{},We=i=>{if(!i)throw new TypeError("Video chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Video chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Video chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Video chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Video chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.codedWidth)||i.decoderConfig.codedWidth<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).");if(!Number.isInteger(i.decoderConfig.codedHeight)||i.decoderConfig.codedHeight<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).");if(i.decoderConfig.description!==void 0&&!kt(i.decoderConfig.description))throw new TypeError("Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.colorSpace!==void 0){let{colorSpace:e}=i.decoderConfig;if(typeof e!="object")throw new TypeError("Video chunk metadata decoder configuration colorSpace, when provided, must be an object.");let t=Object.keys(q);if(e.primaries!=null&&!t.includes(e.primaries))throw new TypeError(`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of ${t.join(", ")}.`);let r=Object.keys(X);if(e.transfer!=null&&!r.includes(e.transfer))throw new TypeError(`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of ${r.join(", ")}.`);let s=Object.keys(G);if(e.matrix!=null&&!s.includes(e.matrix))throw new TypeError(`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of ${s.join(", ")}.`);if(e.fullRange!=null&&typeof e.fullRange!="boolean")throw new TypeError("Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.")}if((i.decoderConfig.codec.startsWith("avc1")||i.decoderConfig.codec.startsWith("avc3"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for AVC must include a description, which is expected to be an AVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec.startsWith("hev1")||i.decoderConfig.codec.startsWith("hvc1"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for HEVC must include a description, which is expected to be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec==="vp8"||i.decoderConfig.codec.startsWith("vp09"))&&i.decoderConfig.colorSpace===void 0)throw new TypeError("Video chunk metadata decoder configuration for VP8/VP9 must include a colorSpace.")},Ne=i=>{if(!i)throw new TypeError("Audio chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Audio chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Audio chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Audio chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Audio chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.sampleRate)||i.decoderConfig.sampleRate<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).");if(!Number.isInteger(i.decoderConfig.numberOfChannels)||i.decoderConfig.numberOfChannels<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).");if(i.decoderConfig.description!==void 0&&!kt(i.decoderConfig.description))throw new TypeError("Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.codec.startsWith("mp4a")&&!i.decoderConfig.description)throw new TypeError("Audio chunk metadata decoder configuration for AAC must include a description, which is expected to be an AudioSpecificConfig as specified in ISO 14496-3.");if(i.decoderConfig.codec==="opus"&&i.decoderConfig.description&&i.decoderConfig.description.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.")},He=i=>{if(!i)throw new TypeError("Subtitle metadata must be provided.");if(typeof i!="object")throw new TypeError("Subtitle metadata must be an object.");if(!i.config)throw new TypeError("Subtitle metadata must include a config object.");if(typeof i.config!="object")throw new TypeError("Subtitle metadata config must be an object.");if(typeof i.config.description!="string")throw new TypeError("Subtitle metadata config description must be a string.")};var De=1e3,Ii=2082844800,P=(i,e,t=!0)=>{let r=i*e;return t?Math.round(r):r},Le=class extends ne{timestampsMustStartAtZero=!0;writer;boxWriter;fastStart;auxTarget=new ce;auxWriter=this.auxTarget._createWriter();auxBoxWriter=new pe(this.auxWriter);ftypSize=null;mdat=null;trackDatas=[];creationTime=Math.floor(Date.now()/1e3)+Ii;finalizedChunks=[];nextFragmentNumber=1;constructor(e,t){super(e),this.writer=e._writer,this.boxWriter=new pe(this.writer);let r=this.writer instanceof oe?"in-memory":!1;this.fastStart=t._options.fastStart??r,(this.fastStart==="in-memory"||this.fastStart==="fragmented")&&(this.writer.ensureMonotonicity=!0)}async start(){let e=await this.mutex.acquire(),t=this.output._tracks.some(r=>r.type==="video"&&r.source._codec==="avc");this.boxWriter.writeBox($t({holdsAvc:t,fragmented:this.fastStart==="fragmented"})),this.ftypSize=this.writer.getPos(),this.fastStart==="in-memory"?this.mdat=Pe(!1):this.fastStart==="fragmented"||(this.mdat=Pe(!0),this.boxWriter.writeBox(this.mdat)),await this.writer.flush(),e()}getVideoTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;We(t),l(t),l(t.decoderConfig),l(t.decoderConfig.codedWidth!==void 0),l(t.decoderConfig.codedHeight!==void 0);let s={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getAudioTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;Ne(t),l(t),l(t.decoderConfig);let s={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},timescale:t.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getSubtitleTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;He(t),l(t),l(t.config);let s={track:e,type:"subtitle",info:{config:t.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),this.validateAndNormalizeTimestamp(e,0,!0),s}async addEncodedVideoChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getVideoTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=this.validateAndNormalizeTimestamp(a.track,t.timestamp,t.type==="key"),o=this.createSampleForTrack(a,n,c,(t.duration??0)/1e6,t.type);await this.registerSample(a,o)}finally{s()}}async addEncodedAudioChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getAudioTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=t.type,o=this.validateAndNormalizeTimestamp(a.track,t.timestamp,c==="key"),u=this.createSampleForTrack(a,n,o,(t.duration??0)/1e6,c);await this.registerSample(a,u)}finally{s()}}async addSubtitleCue(e,t,r){let s=await this.mutex.acquire();try{let a=this.getSubtitleTrackData(e,r);this.validateAndNormalizeTimestamp(a.track,1e6*t.timestamp,!0),e.source._codec==="webvtt"&&(a.cueQueue.push(t),await this.processWebVTTCues(a,t.timestamp))}finally{s()}}async processWebVTTCues(e,t){for(;e.cueQueue.length>0;){let r=new Set([]);for(let u of e.cueQueue)l(u.timestamp<=t),l(e.lastCueEndTimestamp<=u.timestamp+u.duration),r.add(Math.max(u.timestamp,e.lastCueEndTimestamp)),r.add(u.timestamp+u.duration);let s=[...r].sort((u,m)=>u-m),a=s[0],n=s[1]??a;if(t=n)break;ae.lastIndex=0;let d=ae.test(m.text),h=m.timestamp+m.duration,g=e.cueToSourceId.get(m);if(g===void 0&&nr.timestamp).sort((r,s)=>r-s);for(let r=0;r{if(e===n)return t.type==="key";let c=n.sampleQueue[0];return c&&c.type==="key"});s>=1&&a&&(r=!0,await this.finalizeFragment())}else r=s>=.5}r&&(e.currentChunk&&await this.finalizeCurrentChunk(e),e.currentChunk={startTimestamp:t.timestamp,samples:[],offset:null,moofOffset:null}),l(e.currentChunk),e.currentChunk.samples.push(t),e.timestampProcessingQueue.push(t)}async finalizeCurrentChunk(e){if(l(this.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||_(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.writer.getPos();for(let t of e.currentChunk.samples)l(t.data),this.writer.write(t.data),t.data=null;await this.writer.flush()}}async interleaveSamples(){l(this.fastStart==="fragmented");for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let s of this.trackDatas){if(s.sampleQueue.length===0&&!s.track.source._closed)break e;s.sampleQueue.length>0&&s.sampleQueue[0].timestampo.currentChunk),s=this.writer.getPos(),a=yt(t,r);this.boxWriter.writeBox(a);{let o=Pe(!1),u=0;for(let d of r)for(let h of d.currentChunk.samples)u+=h.size;let m=this.boxWriter.measureBox(o)+u;m>=2**32&&(o.largeSize=!0,m=this.boxWriter.measureBox(o)+u),o.size=m,this.boxWriter.writeBox(o)}for(let o of r){o.currentChunk.offset=this.writer.getPos(),o.currentChunk.moofOffset=s;for(let u of o.currentChunk.samples)this.writer.write(u.data),u.data=null}let n=this.writer.getPos();this.writer.seek(this.boxWriter.offsets.get(a));let c=yt(t,r);this.boxWriter.writeBox(c),this.writer.seek(n);for(let o of r)o.finalizedChunks.push(o.currentChunk),this.finalizedChunks.push(o.currentChunk),o.currentChunk=null;e&&await this.writer.flush()}async onTrackClose(e){let t=await this.mutex.acquire();if(e.type==="subtitle"&&e.source._codec==="webvtt"){let r=this.trackDatas.find(s=>s.track===e);r&&await this.processWebVTTCues(r,1/0)}this.fastStart==="fragmented"&&await this.interleaveSamples(),t()}async finalize(){let e=await this.mutex.acquire();for(let t of this.trackDatas)t.type==="subtitle"&&t.track.source._codec==="webvtt"&&await this.processWebVTTCues(t,1/0);if(this.fastStart==="fragmented"){for(let t of this.trackDatas){for(let r of t.sampleQueue)await this.addSampleToTrack(t,r);this.processTimestamps(t)}await this.finalizeFragment(!1)}else for(let t of this.trackDatas)this.processTimestamps(t),await this.finalizeCurrentChunk(t);if(this.fastStart==="in-memory"){l(this.mdat);let t;for(let s=0;s<2;s++){let a=he(this.trackDatas,this.creationTime),n=this.boxWriter.measureBox(a);t=this.boxWriter.measureBox(this.mdat);let c=this.writer.getPos()+n+t;for(let o of this.finalizedChunks){o.offset=c;for(let{data:u}of o.samples)l(u),c+=u.byteLength,t+=u.byteLength}if(c<2**32)break;t>=2**32&&(this.mdat.largeSize=!0)}let r=he(this.trackDatas,this.creationTime);this.boxWriter.writeBox(r),this.mdat.size=t,this.boxWriter.writeBox(this.mdat);for(let s of this.finalizedChunks)for(let a of s.samples)l(a.data),this.writer.write(a.data),a.data=null}else if(this.fastStart==="fragmented"){let t=this.writer.getPos(),r=Xt(this.trackDatas);this.boxWriter.writeBox(r);let s=this.writer.getPos()-t;this.writer.seek(this.writer.getPos()-4),this.boxWriter.writeU32(s)}else{l(this.mdat),l(this.ftypSize!==null);let t=this.boxWriter.offsets.get(this.mdat);l(t!==void 0);let r=this.writer.getPos()-t;this.mdat.size=r,this.mdat.largeSize=r>=2**32,this.boxWriter.patchBox(this.mdat);let s=he(this.trackDatas,this.creationTime);if(typeof this.fastStart=="object"){this.writer.seek(this.ftypSize),this.boxWriter.writeBox(s);let a=t-this.writer.getPos();this.boxWriter.writeBox(jt(a))}else this.boxWriter.writeBox(s)}e()}};var ke=class{value;constructor(e){this.value=e}},ue=class{value;constructor(e){this.value=e}},Te=class{value;constructor(e){this.value=e}};var It=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,At=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,ur=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var Rt=2**15,mr="https://github.com/Vanilagy/webm-muxer",lr=6,dr=5,Ai={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},Ri={video:1,audio:2,subtitle:17},Qe=class extends ne{timestampsMustStartAtZero=!1;writer;format;helper=new Uint8Array(8);helperView=new DataView(this.helper.buffer);offsets=new WeakMap;dataOffsets=new WeakMap;trackDatas=[];segment=null;segmentInfo=null;seekHead=null;tracksElement=null;segmentDuration=null;cues=null;currentCluster=null;currentClusterMsTimestamp=null;trackDatasInCurrentCluster=new Set;duration=0;constructor(e,t){super(e),this.writer=e._writer,this.format=t,this.format._options.streamable&&(this.writer.ensureMonotonicity=!0)}writeByte(e){this.helperView.setUint8(0,e),this.writer.write(this.helper.subarray(0,1))}writeFloat32(e){this.helperView.setFloat32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeFloat64(e){this.helperView.setFloat64(0,e,!1),this.writer.write(this.helper)}writeUnsignedInt(e,t=It(e)){let r=0;switch(t){case 6:this.helperView.setUint8(r++,e/2**40|0);case 5:this.helperView.setUint8(r++,e/2**32|0);case 4:this.helperView.setUint8(r++,e>>24);case 3:this.helperView.setUint8(r++,e>>16);case 2:this.helperView.setUint8(r++,e>>8);case 1:this.helperView.setUint8(r++,e);break;default:throw new Error("Bad UINT size "+t)}this.writer.write(this.helper.subarray(0,r))}writeSignedInt(e,t=At(e)){e<0&&(e+=2**(t*8)),this.writeUnsignedInt(e,t)}writeEBMLVarInt(e,t=ur(e)){let r=0;switch(t){case 1:this.helperView.setUint8(r++,128|e);break;case 2:this.helperView.setUint8(r++,64|e>>8),this.helperView.setUint8(r++,e);break;case 3:this.helperView.setUint8(r++,32|e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;case 4:this.helperView.setUint8(r++,16|e>>24),this.helperView.setUint8(r++,e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;case 5:this.helperView.setUint8(r++,8|e/2**32&7),this.helperView.setUint8(r++,e>>24),this.helperView.setUint8(r++,e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;case 6:this.helperView.setUint8(r++,4|e/2**40&3),this.helperView.setUint8(r++,e/2**32|0),this.helperView.setUint8(r++,e>>24),this.helperView.setUint8(r++,e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;default:throw new Error("Bad EBML VINT size "+t)}this.writer.write(this.helper.subarray(0,r))}writeString(e){this.writer.write(new Uint8Array(e.split("").map(t=>t.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.writer.write(e);else if(Array.isArray(e))for(let t of e)this.writeEBML(t);else if(this.offsets.set(e,this.writer.getPos()),this.writeUnsignedInt(e.id),Array.isArray(e.data)){let t=this.writer.getPos(),r=e.size===-1?1:e.size??4;e.size===-1?this.writeByte(255):this.writer.seek(this.writer.getPos()+r);let s=this.writer.getPos();if(this.dataOffsets.set(e,s),this.writeEBML(e.data),e.size!==-1){let a=this.writer.getPos()-s,n=this.writer.getPos();this.writer.seek(t),this.writeEBMLVarInt(a,r),this.writer.seek(n)}}else if(typeof e.data=="number"){let t=e.size??It(e.data);this.writeEBMLVarInt(t),this.writeUnsignedInt(e.data,t)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.writeString(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.writer.write(e.data);else if(e.data instanceof ke)this.writeEBMLVarInt(4),this.writeFloat32(e.data.value);else if(e.data instanceof ue)this.writeEBMLVarInt(8),this.writeFloat64(e.data.value);else if(e.data instanceof Te){let t=e.size??At(e.data.value);this.writeEBMLVarInt(t),this.writeSignedInt(e.data.value,t)}}}beforeTrackAdd(e){if(this.format instanceof ee)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source._codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source._codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source._codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}async start(){let e=await this.mutex.acquire();this.writeEBMLHeader(),this.format._options.streamable||this.createSeekHead(),this.createSegmentInfo(),this.createCues(),await this.writer.flush(),e()}writeEBMLHeader(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.format instanceof ee?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}createSeekHead(){let e=new Uint8Array([28,83,187,107]),t=new Uint8Array([21,73,169,102]),r=new Uint8Array([22,84,174,107]),s={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:t},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:r},{id:21420,size:5,data:0}]}]};this.seekHead=s}createSegmentInfo(){let e={id:17545,data:new ue(0)};this.segmentDuration=e;let t={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:mr},{id:22337,data:mr},this.format._options.streamable?null:e]};this.segmentInfo=t}createTracks(){let e={id:374648427,data:[]};this.tracksElement=e;for(let t of this.trackDatas)e.data.push({id:174,data:[{id:215,data:t.track.id},{id:29637,data:t.track.id},{id:131,data:Ri[t.type]},{id:134,data:Ai[t.track.source._codec]},t.type==="video"?this.videoSpecificTrackInfo(t):null,t.type==="audio"?this.audioSpecificTrackInfo(t):null,t.type==="subtitle"?this.subtitleSpecificTrackInfo(t):null]})}videoSpecificTrackInfo(e){let t=[e.info.decoderConfig.description?{id:25506,data:j(e.info.decoderConfig.description)}:null,e.track.metadata.frameRate?{id:2352003,data:1e9/e.track.metadata.frameRate}:null],r=e.info.decoderConfig.colorSpace,s={id:224,data:[{id:176,data:e.info.width},{id:186,data:e.info.height},Ee(r)?{id:21936,data:[{id:21937,data:G[r.matrix]},{id:21946,data:X[r.transfer]},{id:21947,data:q[r.primaries]},{id:21945,data:r.fullRange?2:1}]}:null]};return t.push(s),t}audioSpecificTrackInfo(e){return[e.info.decoderConfig.description?{id:25506,data:j(e.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new ke(e.info.sampleRate)},{id:159,data:e.info.numberOfChannels}]}]}subtitleSpecificTrackInfo(e){return[{id:25506,data:D.encode(e.info.config.description)}]}createSegment(){let e={id:408125543,size:this.format._options.streamable?-1:lr,data:[this.format._options.streamable?null:this.seekHead,this.segmentInfo,this.tracksElement]};this.segment=e,this.writeEBML(e)}createCues(){this.cues={id:475249515,data:[]}}get segmentDataOffset(){return l(this.segment),this.dataOffsets.get(this.segment)}getVideoTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;We(t),l(t),l(t.decoderConfig),l(t.decoderConfig.codedWidth!==void 0),l(t.decoderConfig.codedHeight!==void 0);let s={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getAudioTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;Ne(t),l(t),l(t.decoderConfig);let s={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getSubtitleTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;He(t),l(t),l(t.config);let s={track:e,type:"subtitle",info:{config:t.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}async addEncodedVideoChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getVideoTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=t.type==="key",o=this.validateAndNormalizeTimestamp(a.track,t.timestamp,c),u=this.createInternalChunk(n,o,(t.duration??0)/1e6,t.type);e.source._codec==="vp9"&&this.fixVP9ColorSpace(a,u),a.chunkQueue.push(u),await this.interleaveChunks()}finally{s()}}async addEncodedAudioChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getAudioTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=t.type,o=c==="key",u=this.validateAndNormalizeTimestamp(a.track,t.timestamp,o),m=this.createInternalChunk(n,u,(t.duration??0)/1e6,c);a.chunkQueue.push(m),await this.interleaveChunks()}finally{s()}}async addSubtitleCue(e,t,r){let s=await this.mutex.acquire();try{let a=this.getSubtitleTrackData(e,r),n=this.validateAndNormalizeTimestamp(a.track,1e6*t.timestamp,!0),c=t.text,o=Math.floor(n*1e3);ae.lastIndex=0,c=c.replace(ae,h=>{let b=Me(h.slice(1,-1))-o;return`<${Ve(b)}>`});let u=D.encode(c),m=`${t.settings??""} -${t.identifier??""} -${t.notes??""}`,d=this.createInternalChunk(u,n,t.duration,"key",m.trim()?D.encode(m):null);a.chunkQueue.push(d),await this.interleaveChunks()}finally{s()}}async interleaveChunks(){for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let s of this.trackDatas){if(s.chunkQueue.length===0&&!s.track.source._closed)break e;s.chunkQueue.length>0&&s.chunkQueue[0].timestamp=2&&r++;let o={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];Vt(t.data,r+0,r+3,o)}createInternalChunk(e,t,r,s,a=null){return{data:e,type:s,timestamp:t,duration:r,additions:a}}writeBlock(e,t){this.segment||(this.createTracks(),this.createSegment());let r=Math.floor(1e3*t.timestamp),s=this.trackDatas.every(m=>{if(m.track.source._closed)return!0;if(e===m)return t.type==="key";let d=m.chunkQueue[0];return d&&d.type==="key"});(!this.currentCluster||s&&r-this.currentClusterMsTimestamp>=1e3)&&this.createNewCluster(r);let a=r-this.currentClusterMsTimestamp;if(a<0)return;if(a>=Rt)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${Rt} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${Rt} milliseconds.`);let c=new Uint8Array(4),o=new DataView(c.buffer);o.setUint8(0,128|e.track.id),o.setInt16(1,a,!1);let u=Math.floor(1e3*t.duration);if(u===0&&!t.additions){o.setUint8(3,+(t.type==="key")<<7);let m={id:163,data:[c,t.data]};this.writeEBML(m)}else{let m={id:160,data:[{id:161,data:[c,t.data]},t.type==="delta"?{id:251,data:new Te(e.lastWrittenMsTimestamp-r)}:null,t.additions?{id:30113,data:[{id:166,data:[{id:165,data:t.additions},{id:238,data:1}]}]}:null,u>0?{id:155,data:u}:null]};this.writeEBML(m)}this.duration=Math.max(this.duration,r+u),e.lastWrittenMsTimestamp=r,this.trackDatasInCurrentCluster.add(e)}createNewCluster(e){this.currentCluster&&!this.format._options.streamable&&this.finalizeCurrentCluster(),this.currentCluster={id:524531317,size:this.format._options.streamable?-1:dr,data:[{id:231,data:e}]},this.writeEBML(this.currentCluster),this.currentClusterMsTimestamp=e,this.trackDatasInCurrentCluster.clear()}finalizeCurrentCluster(){l(this.currentCluster);let e=this.writer.getPos()-this.dataOffsets.get(this.currentCluster),t=this.writer.getPos();this.writer.seek(this.offsets.get(this.currentCluster)+4),this.writeEBMLVarInt(e,dr),this.writer.seek(t);let r=this.offsets.get(this.currentCluster)-this.segmentDataOffset;l(this.cues),this.cues.data.push({id:187,data:[{id:179,data:this.currentClusterMsTimestamp},...[...this.trackDatasInCurrentCluster].map(s=>({id:183,data:[{id:247,data:s.track.id},{id:241,data:r}]}))]})}async onTrackClose(){let e=await this.mutex.acquire();await this.interleaveChunks(),e()}async finalize(){let e=await this.mutex.acquire();this.segment||(this.createTracks(),this.createSegment());for(let t of this.trackDatas)for(;t.chunkQueue.length>0;)this.writeBlock(t,t.chunkQueue.shift());if(!this.format._options.streamable&&this.currentCluster&&this.finalizeCurrentCluster(),l(this.cues),this.writeEBML(this.cues),!this.format._options.streamable){let t=this.writer.getPos(),r=this.writer.getPos()-this.segmentDataOffset;this.writer.seek(this.offsets.get(this.segment)+4),this.writeEBMLVarInt(r,lr),this.segmentDuration.data=new ue(this.duration),this.writer.seek(this.offsets.get(this.segmentDuration)),this.writeEBML(this.segmentDuration),this.seekHead.data[0].data[1].data=this.offsets.get(this.cues)-this.segmentDataOffset,this.seekHead.data[1].data[1].data=this.offsets.get(this.segmentInfo)-this.segmentDataOffset,this.seekHead.data[2].data[1].data=this.offsets.get(this.tracksElement)-this.segmentDataOffset,this.writer.seek(this.offsets.get(this.seekHead)),this.writeEBML(this.seekHead),this.writer.seek(t)}e()}};var K=class{},Ke=class extends K{_options;constructor(e={}){if(!e||typeof e!="object")throw new TypeError("options must be an object.");if(e.fastStart!==void 0&&![!1,"in-memory","fragmented"].includes(e.fastStart))throw new TypeError('options.fastStart, when provided, must be false, "in-memory", or "fragmented".');super(),this._options=e}_createMuxer(e){return new Le(e,this)}},xe=class extends K{_options;constructor(e={}){if(!e||typeof e!="object")throw new TypeError("options must be an object.");if(e.streamable!==void 0&&typeof e.streamable!="boolean")throw new TypeError("options.streamable, when provided, must be a boolean.");super(),this._options=e}_createMuxer(e){return new Qe(e,this)}},ee=class extends xe{};var te=class{_connectedTrack=null;_closed=!1;_offsetTimestamps=!1;_ensureValidDigest(){if(!this._connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call digest before output has been started.");if(this._connectedTrack.output._finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this._closed)throw new Error("Cannot call digest after source has been closed.")}_start(){}async _flush(){}close(){if(this._closed)throw new Error("Source already closed.");if(!this._connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call close before output has been started.");this._closed=!0,!this._connectedTrack.output._finalizing&&this._connectedTrack.output._muxer.onTrackClose(this._connectedTrack)}},B=class extends te{_connectedTrack=null;_codec;constructor(e){if(super(),!Z.includes(e))throw new TypeError(`Invalid video codec '${e}'. Must be one of: ${Z.join(", ")}.`);this._codec=e}},$e=class extends B{constructor(e){super(e)}digest(e,t){if(!(e instanceof EncodedVideoChunk))throw new TypeError("chunk must be an EncodedVideoChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedVideoChunk(this._connectedTrack,e,t)}},Oi=5,_i=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!Z.includes(i.codec))throw new TypeError(`Invalid video codec '${i.codec}'. Must be one of: ${Z.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.");if(i.latencyMode!==void 0&&!["quality","realtime"].includes(i.latencyMode))throw new TypeError("config.latencyMode, when provided, must be 'quality' or 'realtime'.")},Ce=class{constructor(e,t){this.source=e;this.codecConfig=t;_i(t)}encoder=null;muxer=null;lastMultipleOfKeyFrameInterval=-1;lastWidth=null;lastHeight=null;async digest(e){if(this.source._ensureValidDigest(),this.lastWidth!==null&&this.lastHeight!==null){if(e.codedWidth!==this.lastWidth||e.codedHeight!==this.lastHeight)throw new Error(`Video frame size must remain constant. Expected ${this.lastWidth}x${this.lastHeight}, got ${e.codedWidth}x${e.codedHeight}.`)}else this.lastWidth=e.codedWidth,this.lastHeight=e.codedHeight;this.ensureEncoder(e),l(this.encoder);let t=Math.floor(e.timestamp/1e6/Oi);this.encoder.encode(e,{keyFrame:t!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=t,this.encoder.encodeQueueSize>=4&&await new Promise(r=>this.encoder.addEventListener("dequeue",r,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(e){this.encoder||(this.encoder=new VideoEncoder({output:(t,r)=>void this.muxer.addEncodedVideoChunk(this.source._connectedTrack,t,r),error:t=>console.error("Video encode error:",t)}),this.encoder.configure({codec:ir(this.codecConfig.codec,e.codedWidth,e.codedHeight,this.codecConfig.bitrate),width:e.codedWidth,height:e.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source._connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode,...or(this.codecConfig.codec)}),l(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},je=class extends B{_encoder;constructor(e){super(e.codec),this._encoder=new Ce(this,e)}digest(e){if(!(e instanceof VideoFrame))throw new TypeError("videoFrame must be a VideoFrame.");return this._encoder.digest(e)}_flush(){return this._encoder.flush()}},qe=class extends B{_encoder;_canvas;constructor(e,t){if(!(e instanceof HTMLCanvasElement))throw new TypeError("canvas must be an HTMLCanvasElement.");super(t.codec),this._encoder=new Ce(this,t),this._canvas=e}digest(e,t=0){if(!Number.isFinite(e)||e<0)throw new TypeError("timestamp must be a non-negative number.");if(!Number.isFinite(t)||t<0)throw new TypeError("duration must be a non-negative number.");let r=new VideoFrame(this._canvas,{timestamp:Math.round(1e6*e),duration:Math.round(1e6*t),alpha:"discard"}),s=this._encoder.digest(r);return r.close(),s}_flush(){return this._encoder.flush()}},Xe=class extends B{_encoder;_abortController=null;_track;_offsetTimestamps=!0;constructor(e,t){if(!(e instanceof MediaStreamTrack)||e.kind!=="video")throw new TypeError("track must be a video MediaStreamTrack.");t={...t,latencyMode:"realtime"},super(t.codec),this._encoder=new Ce(this,t),this._track=e}_start(){this._abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this._track}),t=new WritableStream({write:r=>{this._encoder.digest(r),r.close()}});e.readable.pipeTo(t,{signal:this._abortController.signal}).catch(r=>{r instanceof DOMException&&r.name==="AbortError"||console.error("Pipe error:",r)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},W=class extends te{_connectedTrack=null;_codec;constructor(e){if(super(),!J.includes(e))throw new TypeError(`Invalid audio codec '${e}'. Must be one of: ${J.join(", ")}.`);this._codec=e}},Ge=class extends W{constructor(e){super(e)}digest(e,t){if(!(e instanceof EncodedAudioChunk))throw new TypeError("chunk must be an EncodedAudioChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedAudioChunk(this._connectedTrack,e,t)}},Ei=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!J.includes(i.codec))throw new TypeError(`Invalid audio codec '${i.codec}'. Must be one of: ${J.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.")},Se=class{constructor(e,t){this.source=e;this.codecConfig=t;Ei(t)}encoder=null;muxer=null;lastNumberOfChannels=null;lastSampleRate=null;async digest(e){if(this.source._ensureValidDigest(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(e.numberOfChannels!==this.lastNumberOfChannels||e.sampleRate!==this.lastSampleRate)throw new Error(`Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${e.numberOfChannels} channels at ${e.sampleRate} Hz.`)}else this.lastNumberOfChannels=e.numberOfChannels,this.lastSampleRate=e.sampleRate;this.ensureEncoder(e),l(this.encoder),this.encoder.encode(e),this.encoder.encodeQueueSize>=4&&await new Promise(t=>this.encoder.addEventListener("dequeue",t,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(e){this.encoder||(this.encoder=new AudioEncoder({output:(t,r)=>void this.muxer.addEncodedAudioChunk(this.source._connectedTrack,t,r),error:t=>console.error("Audio encode error:",t)}),this.encoder.configure({codec:ar(this.codecConfig.codec,e.numberOfChannels,e.sampleRate),numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,bitrate:this.codecConfig.bitrate,...cr(this.codecConfig.codec)}),l(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},Ye=class extends W{_encoder;constructor(e){super(e.codec),this._encoder=new Se(this,e)}digest(e){if(!(e instanceof AudioData))throw new TypeError("audioData must be an AudioData.");return this._encoder.digest(e)}_flush(){return this._encoder.flush()}},Ze=class extends W{_encoder;_accumulatedFrameCount=0;constructor(e){super(e.codec),this._encoder=new Se(this,e)}digest(e){if(!(e instanceof AudioBuffer))throw new TypeError("audioBuffer must be an AudioBuffer.");let t=e.numberOfChannels,r=e.sampleRate,s=e.length,a=new Float32Array(t*s);for(let o=0;o{this._encoder.digest(r),r.close()}});e.readable.pipeTo(t,{signal:this._abortController.signal}).catch(r=>{r instanceof DOMException&&r.name==="AbortError"||console.error("Pipe error:",r)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},re=class extends te{_connectedTrack=null;_codec;constructor(e){if(super(),!ge.includes(e))throw new TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${ge.join(", ")}.`);this._codec=e}},et=class extends re{_parser;constructor(e){super(e),this._parser=new Fe({codec:e,output:(t,r)=>this._connectedTrack?.output._muxer.addSubtitleCue(this._connectedTrack,t,r),error:t=>console.error("Subtitle parse error:",t)})}digest(e){if(typeof e!="string")throw new TypeError("text must be a string.");return this._ensureValidDigest(),this._parser.parse(e),this._connectedTrack.output._muxer.mutex.currentPromise}};var tt=class{_muxer;_writer;_tracks=[];_started=!1;_finalizing=!1;_mutex=new H;constructor(e){if(!e||typeof e!="object")throw new TypeError("options must be an object.");if(!(e.format instanceof K))throw new TypeError("options.format must be an OutputFormat.");if(!(e.target instanceof Q))throw new TypeError("options.target must be a Target.");if(e.target._output)throw new Error("Target is already used for another output.");e.target._output=this,this._writer=e.target._createWriter(),this._muxer=e.format._createMuxer(this)}addVideoTrack(e,t={}){if(!(e instanceof B))throw new TypeError("source must be a VideoSource.");if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");if(typeof t.rotation=="number"&&![0,90,180,270].includes(t.rotation))throw new TypeError(`Invalid video rotation: ${t.rotation}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(t.rotation)&&(t.rotation.length!==9||t.rotation.some(r=>!Number.isFinite(r))))throw new TypeError(`Invalid video transformation matrix: ${t.rotation.join()}`);if(t.frameRate!==void 0&&(!Number.isInteger(t.frameRate)||t.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${t.frameRate}. Must be a positive integer.`);this._addTrack("video",e,t)}addAudioTrack(e,t={}){if(!(e instanceof W))throw new TypeError("source must be an AudioSource.");if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");this._addTrack("audio",e,t)}addSubtitleTrack(e,t={}){if(!(e instanceof re))throw new TypeError("source must be a SubtitleSource.");if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");this._addTrack("subtitle",e,t)}_addTrack(e,t,r){if(this._started)throw new Error("Cannot add track after output has started.");if(t._connectedTrack)throw new Error("Source is already used for a track.");let s={id:this._tracks.length+1,output:this,type:e,source:t,metadata:r};this._muxer.beforeTrackAdd(s),this._tracks.push(s),t._connectedTrack=s}async start(){if(this._started)throw new Error("Output already started.");this._started=!0,this._writer.start();let e=await this._mutex.acquire();await this._muxer.start();for(let t of this._tracks)t.source._start();e()}async finalize(){if(!this._started)throw new Error("Cannot finalize before starting.");if(this._finalizing)throw new Error("Cannot call finalize twice.");this._finalizing=!0;let e=await this._mutex.acquire(),t=this._tracks.map(r=>r.source._flush());await Promise.all(t),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),e()}};var me=class{_sizePromise=null;_getSize(){return this._sizePromise??=this._retrieveSize()}},rt=class extends me{constructor(t){super();this.buffer=t}async _read(t,r){return new Uint8Array(this.buffer,t,r-t)}async _retrieveSize(){return this.buffer.byteLength}},it=class extends me{constructor(t){super();this.blob=t}async _read(t,r){let a=await this.blob.slice(t,r).arrayBuffer();return new Uint8Array(a)}async _retrieveSize(){return this.blob.size}};var le=class{input;constructor(e){this.input=e}};var st=class{_backing;constructor(e){this._backing=e}isVideoTrack(){return this instanceof we}isAudioTrack(){return this instanceof ye}computeDuration(){return this._backing.computeDuration()}},we=class extends st{_backing;constructor(e){super(e),this._backing=e}getCodec(){return this._backing.getCodec()}getWidth(){return this._backing.getWidth()}getHeight(){return this._backing.getHeight()}getRotation(){return this._backing.getRotation()}async getRotatedWidth(){return await this._backing.getRotation()%180===0?this._backing.getWidth():this._backing.getHeight()}async getRotatedHeight(){return await this._backing.getRotation()%180===0?this._backing.getHeight():this._backing.getWidth()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}},ye=class extends st{_backing;constructor(e){super(e),this._backing=e}getCodec(){return this._backing.getCodec()}getNumberOfChannels(){return this._backing.getNumberOfChannels()}getSampleRate(){return this._backing.getSampleRate()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}};var de=class{constructor(e,t=1/0){this.source=e;this.maxStorableBytes=t}loadedSegments=[];loadingSegments=[];sourceSizePromise=null;nextAge=0;totalStoredBytes=0;async loadRange(e,t){t=Math.min(t,await this.source._getSize());let r=this.loadingSegments.find(o=>o.start<=e&&o.end>=t);if(r){await r.promise;return}if(this.loadedSegments.some(o=>o.start<=e&&o.end>=t))return;let a=this.source._read(e,t),n={start:e,end:t,promise:a};this.loadingSegments.push(n);let c=await a;Wt(this.loadingSegments,n),this.insertIntoLoadedSegments(e,c)}insertIntoLoadedSegments(e,t){let r={start:e,end:e+t.byteLength,bytes:t,view:new DataView(t.buffer),age:this.nextAge++},s=A(this.loadedSegments,e,a=>a.start);(s===-1||this.loadedSegments[s].start=r.end)break;r.start<=n.start&&n.end<=r.end&&(this.loadedSegments.splice(a,1),a--)}for(;this.totalStoredBytes>this.maxStorableBytes&&this.loadedSegments.length>1;){let a=null,n=-1;for(let c=0;ca.start),s=null;if(r!==-1)for(let a=r;ae)break;if(t<=n.end){s=n;break}}if(!s)throw new Error(`No segment loaded for range [${e}, ${t}).`);return s.age=this.nextAge++,{view:s.view,offset:s.bytes.byteOffset+e-s.start}}forgetRange(e,t){if(t<=e)return;let r=A(this.loadedSegments,e,a=>a.start);if(r===-1)return;let s=this.loadedSegments[r];s.start!==e||s.end!==t||(this.loadedSegments.splice(r,1),this.totalStoredBytes-=s.bytes.byteLength)}};var ie=class{constructor(e){this.reader=e}pos=0;readRange(e,t){let{view:r,offset:s}=this.reader.getViewAndOffset(e,t);return new Uint8Array(r.buffer,s,t-e)}readU8(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+1);return this.pos++,e.getUint8(t)}readU16(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+2);return this.pos+=2,e.getUint16(t,!1)}readU24(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+3);this.pos+=3;let r=e.getUint16(t,!1),s=e.getUint8(t+2);return r*256+s}readS32(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,e.getInt32(t,!1)}readU32(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,e.getUint32(t,!1)}readI32(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,e.getInt32(t,!1)}readU64(){let e=this.readU32(),t=this.readU32();return e*4294967296+t}readF64(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+8);return this.pos+=8,e.getFloat64(t,!1)}readFixed_16_16(){return this.readS32()/65536}readFixed_2_30(){return this.readS32()/1073741824}readAscii(e){let{view:t,offset:r}=this.reader.getViewAndOffset(this.pos,this.pos+e);this.pos+=e;let s="";for(let a=0;ar.computeDuration()));return Math.max(0,...t)}async getTracks(){return await this.readMetadata(),this.tracks.map(e=>e.inputTrack)}async getMimeType(){await this.readMetadata();let e="video/mp4";if(this.tracks.length>0){let t=await Promise.all(this.tracks.map(s=>s.inputTrack.getCodecMimeType())),r=[...new Set(t)];e+=`; codecs="${r.join(", ")}"`}return e}readMetadata(){return this.metadataPromise??=(async()=>{let e=await this.isobmffReader.reader.source._getSize();for(;this.isobmffReader.pos=0&&rr.presentationTimestamp-s.presentationTimestamp),e.sampleTable}async readFragment(){let e=this.isobmffReader.pos;await this.isobmffReader.reader.loadRange(this.isobmffReader.pos,this.isobmffReader.pos+16);let t=this.isobmffReader.readBoxHeader();l(t.name==="moof"),await this.isobmffReader.reader.loadRange(e,e+t.totalSize),this.isobmffReader.pos=e,this.traverseBox();let r=N(this.fragments,e,a=>a.moofOffset);l(r!==-1);let s=this.fragments[r];l(s.moofOffset===e),this.isobmffReader.reader.forgetRange(e,e+t.totalSize);for(let[a,n]of s.trackData){if(n.startTimestampIsFinal)continue;let c=this.tracks.find(d=>d.id===a);this.isobmffReader.pos=0;let o=null,u=null,m=A(c.fragments,e-1,d=>d.moofOffset);for(m!==-1&&(o=c.fragments[m],u=o,this.isobmffReader.pos=o.moofOffset+o.moofSize);this.isobmffReader.posb.moofOffset);if(g===-1){this.isobmffReader.pos=d;let b=await this.readFragment();o&&(o.nextFragment=b),o=b}else{let b=this.fragments[g];o&&(o.nextFragment=b),o=b}}this.isobmffReader.pos=d+h.totalSize}o&&o.trackData.has(a)&&(u=o)}if(u){let d=u.trackData.get(a);l(d.startTimestampIsFinal),pr(n,d.endTimestamp)}n.startTimestampIsFinal=!0}return s}readContiguousBoxes(e){let t=this.isobmffReader.pos;for(;this.isobmffReader.pos-tm.every((d,h)=>d===o[h]));u===-1?s.rotation=0:s.rotation=90*u}break;case"mdhd":{let s=this.currentTrack;l(s);let a=this.isobmffReader.readU8();this.isobmffReader.pos+=3,a===0?(this.isobmffReader.pos+=8,s.timescale=this.isobmffReader.readU32(),s.durationInTimescale=this.isobmffReader.readU32()):a===1&&(this.isobmffReader.pos+=16,s.timescale=this.isobmffReader.readU32(),s.durationInTimescale=this.isobmffReader.readU64())}break;case"hdlr":{let s=this.currentTrack;l(s),this.isobmffReader.pos+=8;let a=this.isobmffReader.readAscii(4);a==="vide"?s.info={type:"video",width:-1,height:-1,codec:null,codecDescription:null,colorSpace:null}:a==="soun"&&(s.info={type:"audio",numberOfChannels:-1,sampleRate:-1,codec:null,codecDescription:null})}break;case"stbl":{let s=this.currentTrack;l(s),s.sampleTableOffset=e,this.readContiguousBoxes(t.contentSize)}break;case"stsd":{let s=this.currentTrack;if(l(s),s.info===null||s.sampleTable)break;let a=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let n=this.isobmffReader.readU32();for(let c=0;c0){if(u===1)this.isobmffReader.pos+=4*4;else if(u===2){this.isobmffReader.pos+=4,d=this.isobmffReader.readF64(),m=this.isobmffReader.readU32(),this.isobmffReader.pos+=4;let h=this.isobmffReader.readU32(),g=this.isobmffReader.readU32(),b=this.isobmffReader.readU32(),f=this.isobmffReader.readU32()}}s.info.numberOfChannels=m,s.info.sampleRate=d,this.readContiguousBoxes(e+o.totalSize-this.isobmffReader.pos)}}}break;case"avcC":{let s=this.currentTrack;l(s&&s.info),s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+t.contentSize)}break;case"hvcC":{let s=this.currentTrack;l(s&&s.info),s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+t.contentSize)}break;case"colr":{let s=this.currentTrack;if(l(s&&s.info?.type==="video"),this.isobmffReader.readAscii(4)!=="nclx")break;let n=this.isobmffReader.readU16(),c=this.isobmffReader.readU16(),o=this.isobmffReader.readU16(),u=!!(this.isobmffReader.readU8()&128);s.info.colorSpace={primaries:Dt[n],transfer:Pt[c],matrix:zt[o],fullRange:u}}break;case"wave":t.totalSize>8&&this.readContiguousBoxes(t.contentSize);break;case"esds":{let s=this.currentTrack;l(s&&s.info),this.isobmffReader.pos+=4;let a=this.isobmffReader.readU8();l(a===3),this.isobmffReader.readIsomVariableInteger(),this.isobmffReader.pos+=2;let n=this.isobmffReader.readU8(),c=(n&128)!==0,o=(n&64)!==0,u=(n&32)!==0;if(c&&(this.isobmffReader.pos+=2),o){let b=this.isobmffReader.readU8();this.isobmffReader.pos+=b}u&&(this.isobmffReader.pos+=2);let m=this.isobmffReader.readU8();l(m===4),this.isobmffReader.readIsomVariableInteger();let d=this.isobmffReader.readU8();l(d===64),this.isobmffReader.pos+=12;let h=this.isobmffReader.readU8();l(h===5);let g=this.isobmffReader.readIsomVariableInteger();s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+g)}break;case"stts":{let s=this.currentTrack;if(l(s),!s.sampleTable)break;this.isobmffReader.pos+=4;let a=this.isobmffReader.readU32(),n=0,c=0;for(let o=0;oC.id===a);if(!n)break;n.fragmentLookupTable=[];let c=this.isobmffReader.readU32(),o=(c&48)>>4,u=(c&12)>>2,m=c&3,d=this.isobmffReader,h=[d.readU8.bind(d),d.readU16.bind(d),d.readU24.bind(d),d.readU32.bind(d)],g=h[o],b=h[u],f=h[m],k=this.isobmffReader.readU32();for(let C=0;Ca.moofOffset);this.fragments.splice(s+1,0,this.currentFragment);for(let[,a]of this.currentFragment.trackData){let n=a.samples[0],c=_(a.samples);this.currentFragment.dataStart=Math.min(this.currentFragment.dataStart,n.byteOffset),this.currentFragment.dataEnd=Math.max(this.currentFragment.dataEnd,c.byteOffset+c.byteSize)}this.currentFragment=null}break;case"traf":if(l(this.currentFragment),this.readContiguousBoxes(t.contentSize),this.currentTrack){let s=this.currentFragment.trackData.get(this.currentTrack.id);if(s){let a=A(this.currentTrack.fragments,this.currentFragment.moofOffset,c=>c.moofOffset);this.currentTrack.fragments.splice(a+1,0,this.currentFragment);let{currentFragmentState:n}=this.currentTrack;l(n),n.startTimestamp!==null&&(pr(s,n.startTimestamp),s.startTimestampIsFinal=!0)}this.currentTrack.currentFragmentState=null,this.currentTrack=null}break;case"tfhd":{l(this.currentFragment),this.isobmffReader.pos+=1;let s=this.isobmffReader.readU24(),a=!!(s&1),n=!!(s&2),c=!!(s&8),o=!!(s&16),u=!!(s&32),m=!!(s&65536),d=!!(s&131072),h=this.isobmffReader.readU32(),g=this.tracks.find(f=>f.id===h);if(!g)break;let b=this.fragmentTrackDefaults.find(f=>f.trackId===h);this.currentTrack=g,g.currentFragmentState={baseDataOffset:this.currentFragment.implicitBaseDataOffset,sampleDescriptionIndex:b?.defaultSampleDescriptionIndex??null,defaultSampleDuration:b?.defaultSampleDuration??null,defaultSampleSize:b?.defaultSampleSize??null,defaultSampleFlags:b?.defaultSampleFlags??null,startTimestamp:null},a?g.currentFragmentState.baseDataOffset=this.isobmffReader.readU64():d&&(g.currentFragmentState.baseDataOffset=this.currentFragment.moofOffset),n&&(g.currentFragmentState.sampleDescriptionIndex=this.isobmffReader.readU32()),c&&(g.currentFragmentState.defaultSampleDuration=this.isobmffReader.readU32()),o&&(g.currentFragmentState.defaultSampleSize=this.isobmffReader.readU32()),u&&(g.currentFragmentState.defaultSampleFlags=this.isobmffReader.readU32()),m&&(g.currentFragmentState.defaultSampleDuration=0)}break;case"tfdt":{let s=this.currentTrack;if(!s)break;l(s.currentFragmentState);let a=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let n=a===0?this.isobmffReader.readU32():this.isobmffReader.readU64();s.currentFragmentState.startTimestamp=n}break;case"trun":{let s=this.currentTrack;if(!s)break;if(l(this.currentFragment),l(s.currentFragmentState),this.currentFragment.trackData.has(s.id))throw new Error("Can't have two trun boxes for the same track in one fragment.");let a=this.isobmffReader.readU8(),n=this.isobmffReader.readU24(),c=!!(n&1),o=!!(n&4),u=!!(n&256),m=!!(n&512),d=!!(n&1024),h=!!(n&2048),g=this.isobmffReader.readU32(),b=s.currentFragmentState.baseDataOffset;c&&(b+=this.isobmffReader.readI32());let f=null;o&&(f=this.isobmffReader.readU32());let k=b;if(g===0){this.currentFragment.implicitBaseDataOffset=k;break}let C=0,v={startTimestamp:0,endTimestamp:0,samples:[],presentationTimestamps:[],startTimestampIsFinal:!1};this.currentFragment.trackData.set(s.id,v);for(let R=0;R({presentationTimestamp:R.presentationTimestamp,sampleIndex:V})).sort((R,V)=>R.presentationTimestamp-V.presentationTimestamp);let w=v.samples[v.presentationTimestamps[0].sampleIndex],O=v.samples[_(v.presentationTimestamps).sampleIndex];v.startTimestamp=w.presentationTimestamp,v.endTimestamp=O.presentationTimestamp+O.duration,this.currentFragment.implicitBaseDataOffset=k}break}this.isobmffReader.pos=r}},nt=class{constructor(e){this.internalTrack=e}chunkToSampleIndex=new WeakMap;chunkToFragmentLocation=new WeakMap;getCodec(){throw new Error("Not implemented on base class.")}async computeDuration(){let t=(await this.getChunk(1/0,{metadataOnly:!0}))?.timestamp;return t?t/1e6:0}async getFirstChunk(e){return this.internalTrack.demuxer.isFragmented?this.performFragmentedLookup(()=>{let t=this.internalTrack.fragments[0];return{fragmentIndex:t?0:-1,sampleIndex:t?0:-1,correctSampleFound:!!t}},0,1/0,e):this.fetchChunkForSampleIndex(0,e)}roundToMicrosecond(e){return(Math.floor(e*1e6)+.99999999)/1e6}async getChunk(e,t){e=this.roundToMicrosecond(e);let r=e*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findSampleInFragmentsForTimestamp(r),r,r,t);{let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=fr(s,r);return this.fetchChunkForSampleIndex(a,t)}}async getNextChunk(e,t){if(this.internalTrack.demuxer.isFragmented){let s=this.chunkToFragmentLocation.get(e);if(s===void 0)throw new Error("Chunk was not created from this track.");let a=s.fragment.trackData.get(this.internalTrack.id),n=a.samples[s.sampleIndex],c=N(this.internalTrack.fragments,s.fragment.moofOffset,o=>o.moofOffset);return l(c!==-1),this.performFragmentedLookup(()=>{if(s.sampleIndex+1d.moofOffset);return l(m!==-1),{fragmentIndex:m,sampleIndex:0,correctSampleFound:!0}}return{fragmentIndex:c,sampleIndex:-1,correctSampleFound:!1}}},n.presentationTimestamp,1/0,t)}let r=this.chunkToSampleIndex.get(e);if(r===void 0)throw new Error("Chunk was not created from this track.");return this.fetchChunkForSampleIndex(r+1,t)}async getKeyChunk(e,t){e=this.roundToMicrosecond(e);let r=e*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findKeySampleInFragmentsForTimestamp(r),r,r,t);let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=fr(s,r),n=a===-1?-1:Vi(s,a);return this.fetchChunkForSampleIndex(n,t)}async getNextKeyChunk(e,t){if(this.internalTrack.demuxer.isFragmented){let n=this.chunkToFragmentLocation.get(e);if(n===void 0)throw new Error("Chunk was not created from this track.");let c=n.fragment.trackData.get(this.internalTrack.id),o=c.samples[n.sampleIndex],u=N(this.internalTrack.fragments,n.fragment.moofOffset,m=>m.moofOffset);return l(u!==-1),this.performFragmentedLookup(()=>{let m=c.samples.findIndex((d,h)=>d.isKeyFrame&&h>n.sampleIndex);if(m!==-1)return{fragmentIndex:u,sampleIndex:m,correctSampleFound:!0};{let d=n.fragment;for(;d.nextFragment;){d=d.nextFragment;let h=d.trackData.get(this.internalTrack.id);if(h){let g=N(this.internalTrack.fragments,d.moofOffset,f=>f.moofOffset);l(g!==-1);let b=h.samples.findIndex(f=>f.isKeyFrame);if(b===-1)throw new Error("Not supported: Fragment does not contain key sample.");return{fragmentIndex:g,sampleIndex:b,correctSampleFound:!0}}}return{fragmentIndex:u,sampleIndex:-1,correctSampleFound:!1}}},o.presentationTimestamp,1/0,t)}let r=this.chunkToSampleIndex.get(e);if(r===void 0)throw new Error("Chunk was not created from this track.");let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=Di(s,r);return this.fetchChunkForSampleIndex(a,t)}async fetchChunkForSampleIndex(e,t){if(e===-1)return null;let r=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),s=Mi(r,e);if(!s)return null;let a;t.metadataOnly?a=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(s.chunkOffset,s.chunkOffset+s.chunkSize),a=this.internalTrack.demuxer.chunkReader.readRange(s.sampleOffset,s.sampleOffset+s.sampleSize));let n=1e6*s.presentationTimestamp/this.internalTrack.timescale,c=1e6*s.duration/this.internalTrack.timescale,o=this.createChunk(a,n,c,s.isKeyFrame);return this.chunkToSampleIndex.set(o,e),o}async fetchChunkInFragment(e,t,r){if(t===-1)return null;let a=e.trackData.get(this.internalTrack.id).samples[t];l(a);let n;r.metadataOnly?n=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(e.dataStart,e.dataEnd),n=this.internalTrack.demuxer.chunkReader.readRange(a.byteOffset,a.byteOffset+a.byteSize));let c=1e6*a.presentationTimestamp/this.internalTrack.timescale,o=1e6*a.duration/this.internalTrack.timescale,u=this.createChunk(n,c,o,a.isKeyFrame);return this.chunkToFragmentLocation.set(u,{fragment:e,sampleIndex:t}),u}findSampleInFragmentsForTimestamp(e){let t=A(this.internalTrack.fragments,e,a=>a.trackData.get(this.internalTrack.id).startTimestamp),r=-1,s=!1;if(t!==-1){let n=this.internalTrack.fragments[t].trackData.get(this.internalTrack.id),c=A(n.presentationTimestamps,e,o=>o.presentationTimestamp);l(c!==-1),r=n.presentationTimestamps[c].sampleIndex,s=ea.trackData.get(this.internalTrack.id).startTimestamp),r=-1,s=!1;if(t!==-1){let n=this.internalTrack.fragments[t].trackData.get(this.internalTrack.id),c=n.presentationTimestamps.findLastIndex(u=>n.samples[u.sampleIndex].isKeyFrame&&u.presentationTimestamp<=e);if(c===-1)throw new Error("Not supported: Fragment does not begin with a key sample.");r=n.presentationTimestamps[c].sampleIndex,s=eC.timestamp);k!==-1&&(f=this.internalTrack.fragmentLookupTable[k])}if(c===-1)m.pos=f?.moofOffset??0;else{let k=this.internalTrack.fragments[c];!f||k.moofOffset>=k.moofOffset?(m.pos=k.moofOffset+k.moofSize,h=k):m.pos=f.moofOffset}for(;m.posr)break;if(h.nextFragment){m.pos=h.nextFragment.moofOffset+h.nextFragment.moofSize,h=h.nextFragment;continue}}await m.reader.loadRange(m.pos,m.pos+16);let k=m.pos,C=m.readBoxHeader();if(C.name==="moof"){let v=N(a.fragments,k,w=>w.moofOffset);if(v===-1){m.pos=k;let w=await a.readFragment();h&&(h.nextFragment=w),h=w;let{fragmentIndex:O,sampleIndex:R,correctSampleFound:V}=e();if(V){let se=this.internalTrack.fragments[O];return this.fetchChunkInFragment(se,R,s)}O!==-1&&(g=O,b=R)}else{let w=a.fragments[v];h&&(h.nextFragment=w),h=w}}m.pos=k+C.totalSize}if(g!==-1){let k=this.internalTrack.fragments[g];return this.fetchChunkInFragment(k,b,s)}return null}finally{n()}}},Ot=class extends nt{internalTrack;constructor(e){super(e),this.internalTrack=e}async getCodec(){return this.internalTrack.info.codec}async getWidth(){return this.internalTrack.info.width}async getHeight(){return this.internalTrack.info.height}async getRotation(){return this.internalTrack.rotation}async getDecoderConfig(){return{codec:sr(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),codedWidth:this.internalTrack.info.width,codedHeight:this.internalTrack.info.height,description:this.internalTrack.info.codecDescription??void 0,colorSpace:this.internalTrack.info.colorSpace??void 0}}createChunk(e,t,r,s){return new EncodedVideoChunk({data:e,timestamp:t,duration:r,type:s?"key":"delta"})}},_t=class extends nt{internalTrack;constructor(e){super(e),this.internalTrack=e}async getCodec(){return this.internalTrack.info.codec}async getNumberOfChannels(){return this.internalTrack.info.numberOfChannels}async getSampleRate(){return this.internalTrack.info.sampleRate}async getDecoderConfig(){return{codec:nr(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),numberOfChannels:this.internalTrack.info.numberOfChannels,sampleRate:this.internalTrack.info.sampleRate,description:this.internalTrack.info.codecDescription??void 0}}createChunk(e,t,r,s){return new EncodedAudioChunk({data:e,timestamp:t,duration:r,type:s?"key":"delta"})}},fr=(i,e)=>{let t=A(i.presentationTimestamps,e,r=>r.presentationTimestamp);return t===-1?-1:i.presentationTimestamps[t].sampleIndex},Mi=(i,e)=>{let t=A(i.sampleTimingEntries,e,f=>f.startIndex),r=i.sampleTimingEntries[t];if(!r||r.startIndex+r.count<=e)return null;let a=r.startDecodeTimestamp+(e-r.startIndex)*r.delta,n=A(i.sampleCompositionTimeOffsets,e,f=>f.startIndex),c=i.sampleCompositionTimeOffsets[n];c&&(a+=c.offset);let o=i.sampleSizes[Math.min(e,i.sampleSizes.length-1)],u=A(i.sampleToChunk,e,f=>f.startSampleIndex),m=i.sampleToChunk[u];l(m);let d=m.startChunkIndex+Math.floor((e-m.startSampleIndex)/m.samplesPerChunk),h=i.chunkOffsets[d],g=0,b=h;if(i.sampleSizes.length===1)b+=o*(e-m.startSampleIndex),g+=o*m.samplesPerChunk;else{let f=m.startSampleIndex+(d-m.startChunkIndex)*m.samplesPerChunk;for(let k=f;kf)!==-1:!0}},Vi=(i,e)=>{if(!i.keySampleIndices)return e;let t=A(i.keySampleIndices,e,r=>r);return i.keySampleIndices[t]??-1},Di=(i,e)=>{if(!i.keySampleIndices)return e+1;let t=A(i.keySampleIndices,e,r=>r);return i.keySampleIndices[t+1]??-1},pr=(i,e)=>{i.startTimestamp+=e,i.endTimestamp+=e;for(let t of i.samples)t.presentationTimestamp+=e;for(let t of i.presentationTimestamps)t.presentationTimestamp+=e};var ot=class extends le{};var ct=class{},Et=class extends ct{async _canReadInput(e){if(await e._mainReader.source._getSize()<8)return!1;let r=new ie(e._mainReader);return r.pos=4,r.readAscii(4)==="ftyp"}_createDemuxer(e){return new at(e)}},Ft=class extends ct{async _canReadInput(){return!1}_createDemuxer(e){return new ot(e)}},ve=new Et,hr=ve,br=ve,ut=new Ft,Mt=ut,gr=ut,kr=[ve,Mt];var mt=class{_source;_formats;_mainReader;_demuxerPromise=null;_format=null;constructor(e){this._formats=e.formats,this._source=e.source,this._mainReader=new de(e.source)}_getDemuxer(){return this._demuxerPromise??=(async()=>{await this._mainReader.loadRange(0,4096);for(let e of this._formats)if(await e._canReadInput(this))return this._format=e,e._createDemuxer(this);throw new Error("Input has an unrecognizable format.")})()}async getFormat(){return await this._getDemuxer(),l(this._format),this._format}async computeDuration(){return(await this._getDemuxer()).computeDuration()}async getTracks(){return(await this._getDemuxer()).getTracks()}async getVideoTracks(){return(await this.getTracks()).filter(t=>t.isVideoTrack())}async getPrimaryVideoTrack(){return(await this.getTracks()).find(t=>t.isVideoTrack())??null}async getAudioTracks(){return(await this.getTracks()).filter(t=>t.isAudioTrack())}async getPrimaryAudioTrack(){return(await this.getTracks()).find(t=>t.isAudioTrack())??null}async getMimeType(){return(await this._getDemuxer()).getMimeType()}};var lt=class{async*chunks(e,t=1/0){let r=[],{promise:s,resolve:a}=F(),{promise:n,resolve:c}=F(),o=!1,u=[],m=()=>Math.max(2,u.length);(async()=>{let d=e??await this.getFirstChunk();for(;d&&!o&&!(d.timestamp/1e6>=t);){if(r.length>m()){({promise:n,resolve:c}=F()),await n;continue}r.push(d),a(),{promise:s,resolve:a}=F(),d=await this.getNextChunk(d)}o=!0,a()})();try{for(;;)if(r.length>0){yield r.shift();let d=performance.now();for(u.push(d);u.length>0&&d-u[0]>=1e3;)u.shift();c()}else if(!o)await s;else break}finally{o=!0,c()}}},dt=class{duplicateFrame(e){return structuredClone(e)}async*mediaFramesAtTimestamps(e){let t=Nt(e),r=[],s=[],{promise:a,resolve:n}=F(),{promise:c,resolve:o}=F(),u=!1,m=!1,d=8,h=null,g=f=>{s.push(f),n(),{promise:a,resolve:n}=F()},b=await this.createDecoder(f=>{if(o(),m){f.close();return}let k=!1;for(;r.length>0&&r[0]===f.timestamp;)g(this.duplicateFrame(f)),r.shift(),k=!0;k?(h?.close(),h=f):f.close()});(async()=>{let f=this.createChunkDrain(),k=null,C=null;for await(let v of t){for(;s.length+b.decodeQueueSize>d;)({promise:c,resolve:o}=F()),await c;if(m)break;let w=await f.getChunk(v);if(!w){g(null);continue}let O=await f.getKeyChunk(v);if(!O){g(null);continue}for(r.push(w.timestamp),k&&O.timestamp===k.timestamp&&w.timestamp>=C.timestamp?(l(C),w.timestamp===C.timestamp&&r.length===1&&(h&&g(this.duplicateFrame(h)),r.shift())):(k=O,C=O,b.decode(O));C.timestamp!==w.timestamp;){let R=await f.getNextChunk(C);l(R),C=R,b.decode(R)}b.decodeQueueSize>=10&&await new Promise(R=>b.addEventListener("dequeue",R,{once:!0}))}await b.flush(),b.close(),u=!0,n()})();try{for(;;)if(s.length>0){let f=s.shift();l(f!==void 0),yield f,o()}else if(!u)await a;else break}finally{m=!0,o();for(let f of s)f?.close();h?.close()}}async*mediaFramesInRange(e=0,t=1/0){let r=[],s=!1,a=null,{promise:n,resolve:c}=F(),{promise:o,resolve:u}=F(),m=!1,d=!1,h=8,g=await this.createDecoder(k=>{u();let C=k.timestamp/1e6;if(C>=t&&(d=!0),d){k.close();return}a&&(C>e?(r.push(a),s=!0):a.close()),C>=e&&(r.push(k),s=!0),a=s?null:k,r.length>0&&(c(),{promise:n,resolve:c}=F())}),b=this.createChunkDrain(),f=await b.getKeyChunk(e)??await b.getFirstChunk();if(f){(async()=>{let k=f,C=1/0;if(t<1/0){let w=await b.getChunk(t),O=w?w.type==="key"&&w.timestamp/1e6===t?w:await b.getNextKeyChunk(w):null;O&&(C=O.timestamp/1e6)}let v=b.chunks(f,C);for(await v.next();k&&!d;){if(r.length+g.decodeQueueSize>h){({promise:o,resolve:u}=F()),await o;continue}g.decode(k);let w=await v.next();if(w.done)break;k=w.value}await v.return(),await g.flush(),g.close(),!s&&a&&r.push(a),m=!0,c()})();try{for(;;)if(r.length>0)yield r.shift(),u();else if(!m)await n;else break}finally{d=!0,u();for(let k of r)k.close()}}}},Ie=class extends lt{constructor(t){super();this.videoTrack=t}getFirstChunk(t={}){return this.videoTrack._backing.getFirstChunk(t)}getChunk(t,r={}){return this.videoTrack._backing.getChunk(t,r)}getNextChunk(t,r={}){return this.videoTrack._backing.getNextChunk(t,r)}getKeyChunk(t,r={}){return this.videoTrack._backing.getKeyChunk(t,r)}getNextKeyChunk(t,r={}){return this.videoTrack._backing.getNextKeyChunk(t,r)}},Ae=class extends dt{constructor(t){super();this.videoTrack=t}decoderConfig=null;async createDecoder(t){this.decoderConfig??=await this.videoTrack.getDecoderConfig();let r=new VideoDecoder({output:t,error:s=>console.error(s)});return r.configure(this.decoderConfig),r}createChunkDrain(){return new Ie(this.videoTrack)}async getFrame(t){for await(let r of this.mediaFramesAtTimestamps([t]))return r;throw new Error("Internal error: Iterator returned nothing.")}frames(t=0,r=1/0){return this.mediaFramesInRange(t,r)}framesAtTimestamps(t){return this.mediaFramesAtTimestamps(t)}},ft=class{constructor(e,t){this.videoTrack=e;this.dimensions=t;this.videoFrameDrain=new Ae(e)}videoFrameDrain;async videoFrameToWrappedCanvas(e){let t=this.dimensions?.width??await this.videoTrack.getRotatedWidth(),r=this.dimensions?.height??await this.videoTrack.getRotatedHeight(),s=await this.videoTrack.getRotation(),a=document.createElement("canvas");a.width=t,a.height=r;let n=a.getContext("2d",{alpha:!1});l(n),n.translate(t/2,r/2),n.rotate(s*Math.PI/180),n.translate(-t/2,-r/2);let[c,o]=s%180===0?[t,r]:[r,t];n.drawImage(e,(t-c)/2,(r-o)/2,c,o);let u={canvas:a,timestamp:e.timestamp/1e6,duration:(e.duration??0)/1e6};return e.close(),u}async getCanvas(e){let t=await this.videoFrameDrain.getFrame(e);return t&&this.videoFrameToWrappedCanvas(t)}async*canvases(e=0,t=1/0){for await(let r of this.videoFrameDrain.frames(e,t))yield this.videoFrameToWrappedCanvas(r)}async*canvasesAtTimestamps(e){for await(let t of this.videoFrameDrain.framesAtTimestamps(e))yield t&&this.videoFrameToWrappedCanvas(t)}},Re=class extends lt{constructor(t){super();this.audioTrack=t}getFirstChunk(t={}){return this.audioTrack._backing.getFirstChunk(t)}getChunk(t,r={}){return this.audioTrack._backing.getChunk(t,r)}getNextChunk(t,r={}){return this.audioTrack._backing.getNextChunk(t,r)}getKeyChunk(t,r={}){return this.audioTrack._backing.getKeyChunk(t,r)}getNextKeyChunk(t,r={}){return this.audioTrack._backing.getNextKeyChunk(t,r)}},Oe=class extends dt{constructor(t){super();this.audioTrack=t}decoderConfig=null;async createDecoder(t){this.decoderConfig??=await this.audioTrack.getDecoderConfig();let r=new AudioDecoder({output:t,error:s=>console.error(s)});return r.configure(this.decoderConfig),r}createChunkDrain(){return new Re(this.audioTrack)}async getData(t){for await(let r of this.mediaFramesAtTimestamps([t]))return r;throw new Error("Internal error: Iterator returned nothing.")}data(t=0,r=1/0){return this.mediaFramesInRange(t,r)}dataAtTimestamps(t){return this.mediaFramesAtTimestamps(t)}},pt=class{constructor(e){this.audioTrack=e;this.audioDataDrain=new Oe(e)}audioDataDrain;audioDataToWrappedArrayBuffer(e){let t=new AudioBuffer({numberOfChannels:e.numberOfChannels,length:e.numberOfFrames,sampleRate:e.sampleRate}),r=new Float32Array(e.allocationSize({planeIndex:0,format:"f32-planar"})/4);for(let n=0;n{let t=Ar.exec(i);if(!t)throw new Error("Expected match.");return 60*60*1e3*Number(t[1]||"0")+60*1e3*Number(t[2])+1e3*Number(t[3])+Number(t[4])},We=i=>{let t=Math.floor(i/36e5),e=Math.floor(i%(60*60*1e3)/(60*1e3)),r=Math.floor(i%(60*1e3)/1e3),s=i%1e3;return t.toString().padStart(2,"0")+":"+e.toString().padStart(2,"0")+":"+r.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")};var Te=class{constructor(t){this.writer=t;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap}writeU32(t){this.helperView.setUint32(0,t,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(t){this.helperView.setUint32(0,Math.floor(t/2**32),!1),this.helperView.setUint32(4,t,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(t){for(let e=0;e[(i%256+256)%256],C=i=>(B.setUint16(0,i,!1),[x[0],x[1]]),Rr=i=>(B.setInt16(0,i,!1),[x[0],x[1]]),Qt=i=>(B.setUint32(0,i,!1),[x[1],x[2],x[3]]),h=i=>(B.setUint32(0,i,!1),[x[0],x[1],x[2],x[3]]),Kt=i=>(B.setInt32(0,i,!1),[x[0],x[1],x[2],x[3]]),Z=i=>(B.setUint32(0,Math.floor(i/2**32),!1),B.setUint32(4,i,!1),[x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7]]),yt=i=>(B.setInt16(0,2**8*i,!1),[x[0],x[1]]),U=i=>(B.setInt32(0,2**16*i,!1),[x[0],x[1],x[2],x[3]]),St=i=>(B.setInt32(0,2**30*i,!1),[x[0],x[1],x[2],x[3]]),wt=(i,t)=>{let e=[],r=i;do{let s=r&127;r>>=7,e.length>0&&(s|=128),e.push(s),t!==void 0&&t--}while(r>0||t);return e.reverse()},M=(i,t=!1)=>{let e=Array(i.length).fill(null).map((r,s)=>i.charCodeAt(s));return t&&e.push(0),e},vt=i=>{let t=null;for(let e of i)(!t||e.timestamp>t.timestamp)&&(t=e);return t},$t=i=>[U(i[0]),U(i[1]),St(i[2]),U(i[3]),U(i[4]),St(i[5]),U(i[6]),U(i[7]),St(i[8])],S=(i,t,e)=>({type:i,contents:t&&new Uint8Array(t.flat(10)),children:e}),y=(i,t,e,r,s)=>S(i,[_(t),Qt(e),r??[]],s),jt=i=>i.fragmented?S("ftyp",[M("iso5"),h(512),M("iso5"),M("iso6"),M("mp41")]):S("ftyp",[M("isom"),h(512),M("isom"),i.holdsAvc?M("avc1"):[],M("mp41")]),He=i=>({type:"mdat",largeSize:i}),qt=i=>({type:"free",size:i}),xe=(i,t,e=!1)=>S("moov",void 0,[Or(t,i),...i.map(r=>Er(r,t)),e?mi(i):null]),Or=(i,t)=>{let e=P(Math.max(0,...t.filter(n=>n.samples.length>0).map(n=>{let o=vt(n.samples);return o.timestamp+o.duration})),Ne),r=Math.max(0,...t.map(n=>n.track.id))+1,s=!j(i)||!j(e),a=s?Z:h;return y("mvhd",+s,0,[a(i),a(i),h(Ne),a(e),U(1),yt(1),Array(10).fill(0),$t(Ct),Array(24).fill(0),h(r)])},Er=(i,t)=>S("trak",void 0,[Fr(i,t),Mr(i,t)]),Fr=(i,t)=>{let e=vt(i.samples),r=P(e?e.timestamp+e.duration:0,Ne),s=!j(t)||!j(r),a=s?Z:h,n;if(i.type==="video"){let o=i.track.metadata.rotation;n=o===void 0||typeof o=="number"?Q(o??0):o}else n=Ct;return y("tkhd",+s,3,[a(t),a(t),h(i.track.id),h(0),a(r),Array(8).fill(0),C(0),C(i.track.id),yt(i.type==="audio"?1:0),C(0),$t(n),U(i.type==="video"?i.info.width:0),U(i.type==="video"?i.info.height:0)])},Mr=(i,t)=>S("mdia",void 0,[Vr(i,t),zr(i),Ur(i)]),Vr=(i,t)=>{let e=vt(i.samples),r=P(e?e.timestamp+e.duration:0,i.timescale),s=!j(t)||!j(r),a=s?Z:h;return y("mdhd",+s,0,[a(t),a(t),h(i.timescale),a(r),C(21956),C(0)])},Dr={video:"vide",audio:"soun",subtitle:"text"},Pr={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},zr=i=>y("hdlr",0,0,[M("mhlr"),M(Dr[i.type]),h(0),h(0),h(0),M(Pr[i.type],!0)]),Ur=i=>S("minf",void 0,[Hr[i.type](),Lr(),$r(i)]),Br=()=>y("vmhd",0,1,[C(0),C(0),C(0),C(0)]),Wr=()=>y("smhd",0,0,[C(0),C(0)]),Nr=()=>y("nmhd",0,0),Hr={video:Br,audio:Wr,subtitle:Nr},Lr=()=>S("dinf",void 0,[Qr()]),Qr=()=>y("dref",0,0,[h(1)],[Kr()]),Kr=()=>y("url ",0,1),$r=i=>{let t=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return S("stbl",void 0,[jr(i),si(i),ai(i),ni(i),oi(i),ci(i),t?ui(i):null])},jr=i=>{let t;return i.type==="video"?t=qr(Ti[i.track.source._codec],i):i.type==="audio"?t=Jr(Ci[i.track.source._codec],i):i.type==="subtitle"&&(t=ri(wi[i.track.source._codec],i)),d(t),y("stsd",0,0,[h(1)],[t])},qr=(i,t)=>S(i,[Array(6).fill(0),C(1),C(0),C(0),Array(12).fill(0),C(t.info.width),C(t.info.height),h(4718592),h(4718592),h(0),C(1),Array(32).fill(0),C(24),Rr(65535)],[xi[t.track.source._codec](t),ze(t.info.decoderConfig.colorSpace)?Xr(t):null]),Xr=i=>S("colr",[M("nclx"),C(X[i.info.decoderConfig.colorSpace.primaries]),C(G[i.info.decoderConfig.colorSpace.transfer]),C(Y[i.info.decoderConfig.colorSpace.matrix]),_((i.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),Gr=i=>i.info.decoderConfig&&S("avcC",[...q(i.info.decoderConfig.description)]),Yr=i=>i.info.decoderConfig&&S("hvcC",[...q(i.info.decoderConfig.description)]),Lt=i=>{if(!i.info.decoderConfig)return null;let t=i.info.decoderConfig;d(t.colorSpace);let e=t.codec.split("."),r=Number(e[1]),s=Number(e[2]),o=(Number(e[3])<<4)+(0<<1)+Number(t.colorSpace.fullRange);return y("vpcC",1,0,[_(r),_(s),_(o),_(2),_(2),_(2),C(0)])},Zr=()=>S("av1C",[129,0,0,0]),Jr=(i,t)=>S(i,[Array(6).fill(0),C(1),C(0),C(0),h(0),C(t.info.numberOfChannels),C(16),C(0),C(0),U(t.info.sampleRate)],[Si[t.track.source._codec](t)]),ei=i=>{let e=[...q(i.info.decoderConfig.description??new ArrayBuffer(0))];return e=[..._(64),..._(21),...Qt(0),...h(0),...h(0),..._(5),...wt(e.length),...e],e=[...C(1),..._(0),..._(4),...wt(e.length),...e,..._(6),..._(1),..._(2)],e=[..._(3),...wt(e.length),...e],y("esds",0,0,e)},ti=i=>{let t=3840,e=0,r=i.info.decoderConfig?.description;if(r){d(r.byteLength>=18);let s=ArrayBuffer.isView(r)?new DataView(r.buffer,r.byteOffset,r.byteLength):new DataView(r);t=s.getUint16(10,!0),e=s.getInt16(14,!0)}return S("dOps",[_(0),_(i.info.numberOfChannels),C(t),h(i.info.sampleRate),yt(e),_(0)])},ri=(i,t)=>S(i,[Array(6).fill(0),C(1)],[yi[t.track.source._codec](t)]),ii=i=>S("vttC",[...D.encode(i.info.config.description)]);var si=i=>y("stts",0,0,[h(i.timeToSampleTable.length),i.timeToSampleTable.map(t=>[h(t.sampleCount),h(t.sampleDelta)])]),ai=i=>{if(i.samples.every(e=>e.type==="key"))return null;let t=[...i.samples.entries()].filter(([,e])=>e.type==="key");return y("stss",0,0,[h(t.length),t.map(([e])=>h(e+1))])},ni=i=>y("stsc",0,0,[h(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(t=>[h(t.firstChunk),h(t.samplesPerChunk),h(1)])]),oi=i=>y("stsz",0,0,[h(0),h(i.samples.length),i.samples.map(t=>h(t.size))]),ci=i=>i.finalizedChunks.length>0&&R(i.finalizedChunks).offset>=2**32?y("co64",0,0,[h(i.finalizedChunks.length),i.finalizedChunks.map(t=>Z(t.offset))]):y("stco",0,0,[h(i.finalizedChunks.length),i.finalizedChunks.map(t=>h(t.offset))]),ui=i=>y("ctts",0,0,[h(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(t=>[h(t.sampleCount),h(t.sampleCompositionTimeOffset)])]),mi=i=>S("mvex",void 0,i.map(di)),di=i=>y("trex",0,0,[h(i.track.id),h(1),h(0),h(0),h(0)]),_t=(i,t)=>S("moof",void 0,[li(i),...t.map(fi)]),li=i=>y("mfhd",0,0,[h(i)]),Xt=i=>{let t=0,e=0,r=0,s=0,a=i.type==="delta";return e|=+a,a?t|=1:t|=2,t<<24|e<<16|r<<8|s},fi=i=>S("traf",void 0,[pi(i),hi(i),bi(i)]),pi=i=>{d(i.currentChunk);let t=0;t|=8,t|=16,t|=32,t|=131072;let e=i.currentChunk.samples[1]??i.currentChunk.samples[0],r={duration:e.timescaleUnitsToNextSample,size:e.size,flags:Xt(e)};return y("tfhd",0,t,[h(i.track.id),h(r.duration),h(r.size),h(r.flags)])},hi=i=>(d(i.currentChunk),y("tfdt",1,0,[Z(P(i.currentChunk.startTimestamp,i.timescale))])),bi=i=>{d(i.currentChunk);let t=i.currentChunk.samples.map(p=>p.timescaleUnitsToNextSample),e=i.currentChunk.samples.map(p=>p.size),r=i.currentChunk.samples.map(Xt),s=i.currentChunk.samples.map(p=>P(p.timestamp-p.decodeTimestamp,i.timescale)),a=new Set(t),n=new Set(e),o=new Set(r),c=new Set(s),u=o.size===2&&r[0]!==r[1],m=a.size>1,l=n.size>1,f=!u&&o.size>1,g=c.size>1||[...c].some(p=>p!==0),b=0;return b|=1,b|=4*+u,b|=256*+m,b|=512*+l,b|=1024*+f,b|=2048*+g,y("trun",1,b,[h(i.currentChunk.samples.length),h(i.currentChunk.offset-i.currentChunk.moofOffset||0),u?h(r[0]):[],i.currentChunk.samples.map((p,k)=>[m?h(t[k]):[],l?h(e[k]):[],f?h(r[k]):[],g?Kt(s[k]):[]])])},Gt=i=>S("mfra",void 0,[...i.map(ki),gi()]),ki=(i,t)=>y("tfra",1,0,[h(i.track.id),h(63),h(i.finalizedChunks.length),i.finalizedChunks.map(r=>[Z(P(r.samples[0].timestamp,i.timescale)),Z(r.moofOffset),h(t+1),h(1),h(1)])]),gi=()=>y("mfro",0,0,[h(0)]),Yt=()=>S("vtte"),Zt=(i,t,e,r,s)=>S("vttc",void 0,[s!==null?S("vsid",[Kt(s)]):null,e!==null?S("iden",[...D.encode(e)]):null,t!==null?S("ctim",[...D.encode(We(t))]):null,r!==null?S("sttg",[...D.encode(r)]):null,S("payl",[...D.encode(i)])]),Jt=i=>S("vtta",[...D.encode(i)]),Ti={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},xi={avc:Gr,hevc:Yr,vp8:Lt,vp9:Lt,av1:Zr},Ci={aac:"mp4a",opus:"Opus"},Si={aac:ei,opus:ti},wi={webvtt:"wvtt"},yi={webvtt:ii};var ce=class{constructor(t){this.mutex=new L;this.trackTimestampInfo=new WeakMap;this.output=t}beforeTrackAdd(t){}onTrackClose(t){}validateAndNormalizeTimestamp(t,e,r){let s=e/1e6,a=this.trackTimestampInfo.get(t);if(!a){if(!r)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&s>0)throw new Error(`Timestamps must start at zero (got ${s}s).`);a={timestampOffset:s,maxTimestamp:t.source._offsetTimestamps?0:s,lastKeyFrameTimestamp:t.source._offsetTimestamps?0:s},this.trackTimestampInfo.set(t,a)}if(t.source._offsetTimestamps&&(s-=a.timestampOffset),s<0)throw new Error(`Timestamps must be non-negative (got ${s}s).`);if(ss.start-a.start);e.push({start:r[0].start,size:r[0].data.byteLength});for(let s=1;su.start<=r&&r_i){for(let u=0;u=e.written[n+1].start;)e.written[n].end=Math.max(e.written[n].end,e.written[n+1].end),e.written.splice(n+1,1)}createChunk(e){let s={start:Math.floor(e/this.chunkSize)*this.chunkSize,data:new Uint8Array(this.chunkSize),written:[],shouldFlush:!1};return this.chunks.push(s),this.chunks.sort((a,n)=>a.start-n.start),this.chunks.indexOf(s)}queueChunksForFlush(e=!1){d(this.writer);for(let r=0;r{if(i==="avc"){let a=Math.ceil(t/16)*Math.ceil(e/16),n=er.find(l=>a<=l.maxMacroblocks&&r<=l.maxBitrate)??R(er),o=n?n.level:0,c="64".padStart(2,"0"),u="00",m=o.toString(16).padStart(2,"0");return`avc1.${c}${u}${m}`}else if(i==="hevc"){let s="",n="6",o=t*e,c=tr.find(m=>o<=m.maxPictureSize&&r<=m.maxBitrate)??R(tr);return`hev1.${s}1.${n}.${c.tier}${c.level}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let s="00",a=t*e,n=rr.find(c=>a<=c.maxPictureSize&&r<=c.maxBitrate)??R(rr);return`vp09.${s}.${n.level}.08`}else if(i==="av1"){let a=t*e,n=ir.find(c=>a<=c.maxPictureSize&&r<=c.maxBitrate)??R(ir);return`av01.0.${n.level.toString().padStart(2,"0")}${n.tier}.08`}}throw new TypeError(`Unhandled codec '${i}'.`)},ar=(i,t)=>{if(i==="avc"){if(!t||t.byteLength<4)throw new TypeError("AVC description must be at least 4 bytes long.");return`avc1.${Ut(t.subarray(1,4))}`}else if(i==="hevc"){if(!t)throw new TypeError("HEVC description must be provided.");let e=new DataView(t.buffer,t.byteOffset,t.byteLength),r="hev1.",s=t[1]>>6&3,a=t[1]&31;r+=["","A","B","C"][s]+a,r+=".";let n=Bt(e.getUint32(2));r+=n.toString(16),r+=".";let o=t[1]>>5&1,c=t[12];r+=o===0?"L":"H",r+=c,r+=".";let u=[];for(let m=0;m<6;m++){let l=t[m+13];u.push(l)}for(;u[u.length-1]===0;)u.pop();return r+=u.map(m=>m.toString(16)).join("."),r}throw new TypeError(`Unhandled codec '${i}'.`)},nr=(i,t,e)=>{if(i==="aac")return t>=2&&e<=24e3?"mp4a.40.29":e<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},or=(i,t)=>{if(i==="aac")return`mp4a.40.${It(t).objectType}`;if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},It=i=>{if(!i||i.byteLength<2)throw new TypeError("AAC description must be at least 2 bytes long.");let t=0,e=O(i,t,t+5);t+=5,e===31&&(e=32+O(i,t,t+6),t+=6);let r=O(i,t,t+4);t+=4;let s=null;if(r===15)s=O(i,t,t+24),t+=24;else{let o=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];r=1&&a<=7&&(n={1:1,2:2,3:3,4:4,5:5,6:6,7:8}[a]),{objectType:e,frequencyIndex:r,sampleRate:s,channelConfiguration:a,numberOfChannels:n}},cr=i=>i==="avc"?{avc:{format:"avc"}}:i==="hevc"?{hevc:{format:"hevc"}}:{},ur=i=>i==="aac"?{aac:{format:"aac"}}:i==="opus"?{opus:{format:"opus"}}:{},$e=i=>{if(!i)throw new TypeError("Video chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Video chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Video chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Video chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Video chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.codedWidth)||i.decoderConfig.codedWidth<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).");if(!Number.isInteger(i.decoderConfig.codedHeight)||i.decoderConfig.codedHeight<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).");if(i.decoderConfig.description!==void 0&&!xt(i.decoderConfig.description))throw new TypeError("Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.colorSpace!==void 0){let{colorSpace:t}=i.decoderConfig;if(typeof t!="object")throw new TypeError("Video chunk metadata decoder configuration colorSpace, when provided, must be an object.");let e=Object.keys(X);if(t.primaries!=null&&!e.includes(t.primaries))throw new TypeError(`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of ${e.join(", ")}.`);let r=Object.keys(G);if(t.transfer!=null&&!r.includes(t.transfer))throw new TypeError(`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of ${r.join(", ")}.`);let s=Object.keys(Y);if(t.matrix!=null&&!s.includes(t.matrix))throw new TypeError(`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of ${s.join(", ")}.`);if(t.fullRange!=null&&typeof t.fullRange!="boolean")throw new TypeError("Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.")}if((i.decoderConfig.codec.startsWith("avc1")||i.decoderConfig.codec.startsWith("avc3"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for AVC must include a description, which is expected to be an AVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec.startsWith("hev1")||i.decoderConfig.codec.startsWith("hvc1"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for HEVC must include a description, which is expected to be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec==="vp8"||i.decoderConfig.codec.startsWith("vp09"))&&i.decoderConfig.colorSpace===void 0)throw new TypeError("Video chunk metadata decoder configuration for VP8/VP9 must include a colorSpace.")},je=i=>{if(!i)throw new TypeError("Audio chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Audio chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Audio chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Audio chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Audio chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.sampleRate)||i.decoderConfig.sampleRate<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).");if(!Number.isInteger(i.decoderConfig.numberOfChannels)||i.decoderConfig.numberOfChannels<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).");if(i.decoderConfig.description!==void 0&&!xt(i.decoderConfig.description))throw new TypeError("Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.codec.startsWith("mp4a")&&!i.decoderConfig.description)throw new TypeError("Audio chunk metadata decoder configuration for AAC must include a description, which is expected to be an AudioSpecificConfig as specified in ISO 14496-3.");if(i.decoderConfig.codec==="opus"&&i.decoderConfig.description&&i.decoderConfig.description.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.")},qe=i=>{if(!i)throw new TypeError("Subtitle metadata must be provided.");if(typeof i!="object")throw new TypeError("Subtitle metadata must be an object.");if(!i.config)throw new TypeError("Subtitle metadata must include a config object.");if(typeof i.config!="object")throw new TypeError("Subtitle metadata config must be an object.");if(typeof i.config.description!="string")throw new TypeError("Subtitle metadata config description must be a string.")};var Ne=1e3,Ii=2082844800,P=(i,t,e=!0)=>{let r=i*t;return e?Math.round(r):r},Xe=class extends ce{constructor(e,r){super(e);this.timestampsMustStartAtZero=!0;this.auxTarget=new me;this.auxWriter=this.auxTarget._createWriter();this.auxBoxWriter=new Te(this.auxWriter);this.ftypSize=null;this.mdat=null;this.trackDatas=[];this.creationTime=Math.floor(Date.now()/1e3)+Ii;this.finalizedChunks=[];this.nextFragmentNumber=1;this.writer=e._writer,this.boxWriter=new Te(this.writer);let s=this.writer instanceof ue?"in-memory":!1;this.fastStart=r._options.fastStart??s,(this.fastStart==="in-memory"||this.fastStart==="fragmented")&&(this.writer.ensureMonotonicity=!0)}async start(){let e=await this.mutex.acquire(),r=this.output._tracks.some(s=>s.type==="video"&&s.source._codec==="avc");this.boxWriter.writeBox(jt({holdsAvc:r,fragmented:this.fastStart==="fragmented"})),this.ftypSize=this.writer.getPos(),this.fastStart==="in-memory"?this.mdat=He(!1):this.fastStart==="fragmented"||(this.mdat=He(!0),this.boxWriter.writeBox(this.mdat)),await this.writer.flush(),e()}getVideoTrackData(e,r){let s=this.trackDatas.find(n=>n.track===e);if(s)return s;$e(r),d(r),d(r.decoderConfig),d(r.decoderConfig.codedWidth!==void 0),d(r.decoderConfig.codedHeight!==void 0);let a={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(a),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),a}getAudioTrackData(e,r){let s=this.trackDatas.find(n=>n.track===e);if(s)return s;je(r),d(r),d(r.decoderConfig);let a={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},timescale:r.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(a),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),a}getSubtitleTrackData(e,r){let s=this.trackDatas.find(n=>n.track===e);if(s)return s;qe(r),d(r),d(r.config);let a={track:e,type:"subtitle",info:{config:r.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.trackDatas.push(a),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),this.validateAndNormalizeTimestamp(e,0,!0),a}async addEncodedVideoChunk(e,r,s){let a=await this.mutex.acquire();try{let n=this.getVideoTrackData(e,s),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=this.validateAndNormalizeTimestamp(n.track,r.timestamp,r.type==="key"),u=this.createSampleForTrack(n,o,c,(r.duration??0)/1e6,r.type);await this.registerSample(n,u)}finally{a()}}async addEncodedAudioChunk(e,r,s){let a=await this.mutex.acquire();try{let n=this.getAudioTrackData(e,s),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=r.type,u=this.validateAndNormalizeTimestamp(n.track,r.timestamp,c==="key"),m=this.createSampleForTrack(n,o,u,(r.duration??0)/1e6,c);await this.registerSample(n,m)}finally{a()}}async addSubtitleCue(e,r,s){let a=await this.mutex.acquire();try{let n=this.getSubtitleTrackData(e,s);this.validateAndNormalizeTimestamp(n.track,1e6*r.timestamp,!0),e.source._codec==="webvtt"&&(n.cueQueue.push(r),await this.processWebVTTCues(n,r.timestamp))}finally{a()}}async processWebVTTCues(e,r){for(;e.cueQueue.length>0;){let s=new Set([]);for(let m of e.cueQueue)d(m.timestamp<=r),d(e.lastCueEndTimestamp<=m.timestamp+m.duration),s.add(Math.max(m.timestamp,e.lastCueEndTimestamp)),s.add(m.timestamp+m.duration);let a=[...s].sort((m,l)=>m-l),n=a[0],o=a[1]??n;if(r=o)break;oe.lastIndex=0;let f=oe.test(l.text),g=l.timestamp+l.duration,b=e.cueToSourceId.get(l);if(b===void 0&&os.timestamp).sort((s,a)=>s-a);for(let s=0;s{if(e===o)return r.type==="key";let c=o.sampleQueue[0];return c&&c.type==="key"});a>=1&&n&&(s=!0,await this.finalizeFragment())}else s=a>=.5}s&&(e.currentChunk&&await this.finalizeCurrentChunk(e),e.currentChunk={startTimestamp:r.timestamp,samples:[],offset:null,moofOffset:null}),d(e.currentChunk),e.currentChunk.samples.push(r),e.timestampProcessingQueue.push(r)}async finalizeCurrentChunk(e){if(d(this.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||R(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.writer.getPos();for(let r of e.currentChunk.samples)d(r.data),this.writer.write(r.data),r.data=null;await this.writer.flush()}}async interleaveSamples(){d(this.fastStart==="fragmented");for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let a of this.trackDatas){if(a.sampleQueue.length===0&&!a.track.source._closed)break e;a.sampleQueue.length>0&&a.sampleQueue[0].timestampu.currentChunk),a=this.writer.getPos(),n=_t(r,s);this.boxWriter.writeBox(n);{let u=He(!1),m=0;for(let f of s)for(let g of f.currentChunk.samples)m+=g.size;let l=this.boxWriter.measureBox(u)+m;l>=2**32&&(u.largeSize=!0,l=this.boxWriter.measureBox(u)+m),u.size=l,this.boxWriter.writeBox(u)}for(let u of s){u.currentChunk.offset=this.writer.getPos(),u.currentChunk.moofOffset=a;for(let m of u.currentChunk.samples)this.writer.write(m.data),m.data=null}let o=this.writer.getPos();this.writer.seek(this.boxWriter.offsets.get(n));let c=_t(r,s);this.boxWriter.writeBox(c),this.writer.seek(o);for(let u of s)u.finalizedChunks.push(u.currentChunk),this.finalizedChunks.push(u.currentChunk),u.currentChunk=null;e&&await this.writer.flush()}async onTrackClose(e){let r=await this.mutex.acquire();if(e.type==="subtitle"&&e.source._codec==="webvtt"){let s=this.trackDatas.find(a=>a.track===e);s&&await this.processWebVTTCues(s,1/0)}this.fastStart==="fragmented"&&await this.interleaveSamples(),r()}async finalize(){let e=await this.mutex.acquire();for(let r of this.trackDatas)r.type==="subtitle"&&r.track.source._codec==="webvtt"&&await this.processWebVTTCues(r,1/0);if(this.fastStart==="fragmented"){for(let r of this.trackDatas){for(let s of r.sampleQueue)await this.addSampleToTrack(r,s);this.processTimestamps(r)}await this.finalizeFragment(!1)}else for(let r of this.trackDatas)this.processTimestamps(r),await this.finalizeCurrentChunk(r);if(this.fastStart==="in-memory"){d(this.mdat);let r;for(let a=0;a<2;a++){let n=xe(this.trackDatas,this.creationTime),o=this.boxWriter.measureBox(n);r=this.boxWriter.measureBox(this.mdat);let c=this.writer.getPos()+o+r;for(let u of this.finalizedChunks){u.offset=c;for(let{data:m}of u.samples)d(m),c+=m.byteLength,r+=m.byteLength}if(c<2**32)break;r>=2**32&&(this.mdat.largeSize=!0)}let s=xe(this.trackDatas,this.creationTime);this.boxWriter.writeBox(s),this.mdat.size=r,this.boxWriter.writeBox(this.mdat);for(let a of this.finalizedChunks)for(let n of a.samples)d(n.data),this.writer.write(n.data),n.data=null}else if(this.fastStart==="fragmented"){let r=this.writer.getPos(),s=Gt(this.trackDatas);this.boxWriter.writeBox(s);let a=this.writer.getPos()-r;this.writer.seek(this.writer.getPos()-4),this.boxWriter.writeU32(a)}else{d(this.mdat),d(this.ftypSize!==null);let r=this.boxWriter.offsets.get(this.mdat);d(r!==void 0);let s=this.writer.getPos()-r;this.mdat.size=s,this.mdat.largeSize=s>=2**32,this.boxWriter.patchBox(this.mdat);let a=xe(this.trackDatas,this.creationTime);if(typeof this.fastStart=="object"){this.writer.seek(this.ftypSize),this.boxWriter.writeBox(a);let n=r-this.writer.getPos();this.boxWriter.writeBox(qt(n))}else this.boxWriter.writeBox(a)}e()}};var we=class{constructor(t){this.value=t}},de=class{constructor(t){this.value=t}},ye=class{constructor(t){this.value=t}};var At=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,Rt=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,mr=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var Ot=2**15,dr="https://github.com/Vanilagy/webm-muxer",lr=6,fr=5,Ai={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},Ri={video:1,audio:2,subtitle:17},Ge=class extends ce{constructor(e,r){super(e);this.timestampsMustStartAtZero=!1;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap;this.dataOffsets=new WeakMap;this.trackDatas=[];this.segment=null;this.segmentInfo=null;this.seekHead=null;this.tracksElement=null;this.segmentDuration=null;this.cues=null;this.currentCluster=null;this.currentClusterMsTimestamp=null;this.trackDatasInCurrentCluster=new Set;this.duration=0;this.writer=e._writer,this.format=r,this.format._options.streamable&&(this.writer.ensureMonotonicity=!0)}writeByte(e){this.helperView.setUint8(0,e),this.writer.write(this.helper.subarray(0,1))}writeFloat32(e){this.helperView.setFloat32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeFloat64(e){this.helperView.setFloat64(0,e,!1),this.writer.write(this.helper)}writeUnsignedInt(e,r=At(e)){let s=0;switch(r){case 6:this.helperView.setUint8(s++,e/2**40|0);case 5:this.helperView.setUint8(s++,e/2**32|0);case 4:this.helperView.setUint8(s++,e>>24);case 3:this.helperView.setUint8(s++,e>>16);case 2:this.helperView.setUint8(s++,e>>8);case 1:this.helperView.setUint8(s++,e);break;default:throw new Error("Bad UINT size "+r)}this.writer.write(this.helper.subarray(0,s))}writeSignedInt(e,r=Rt(e)){e<0&&(e+=2**(r*8)),this.writeUnsignedInt(e,r)}writeEBMLVarInt(e,r=mr(e)){let s=0;switch(r){case 1:this.helperView.setUint8(s++,128|e);break;case 2:this.helperView.setUint8(s++,64|e>>8),this.helperView.setUint8(s++,e);break;case 3:this.helperView.setUint8(s++,32|e>>16),this.helperView.setUint8(s++,e>>8),this.helperView.setUint8(s++,e);break;case 4:this.helperView.setUint8(s++,16|e>>24),this.helperView.setUint8(s++,e>>16),this.helperView.setUint8(s++,e>>8),this.helperView.setUint8(s++,e);break;case 5:this.helperView.setUint8(s++,8|e/2**32&7),this.helperView.setUint8(s++,e>>24),this.helperView.setUint8(s++,e>>16),this.helperView.setUint8(s++,e>>8),this.helperView.setUint8(s++,e);break;case 6:this.helperView.setUint8(s++,4|e/2**40&3),this.helperView.setUint8(s++,e/2**32|0),this.helperView.setUint8(s++,e>>24),this.helperView.setUint8(s++,e>>16),this.helperView.setUint8(s++,e>>8),this.helperView.setUint8(s++,e);break;default:throw new Error("Bad EBML VINT size "+r)}this.writer.write(this.helper.subarray(0,s))}writeString(e){this.writer.write(new Uint8Array(e.split("").map(r=>r.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.writer.write(e);else if(Array.isArray(e))for(let r of e)this.writeEBML(r);else if(this.offsets.set(e,this.writer.getPos()),this.writeUnsignedInt(e.id),Array.isArray(e.data)){let r=this.writer.getPos(),s=e.size===-1?1:e.size??4;e.size===-1?this.writeByte(255):this.writer.seek(this.writer.getPos()+s);let a=this.writer.getPos();if(this.dataOffsets.set(e,a),this.writeEBML(e.data),e.size!==-1){let n=this.writer.getPos()-a,o=this.writer.getPos();this.writer.seek(r),this.writeEBMLVarInt(n,s),this.writer.seek(o)}}else if(typeof e.data=="number"){let r=e.size??At(e.data);this.writeEBMLVarInt(r),this.writeUnsignedInt(e.data,r)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.writeString(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.writer.write(e.data);else if(e.data instanceof we)this.writeEBMLVarInt(4),this.writeFloat32(e.data.value);else if(e.data instanceof de)this.writeEBMLVarInt(8),this.writeFloat64(e.data.value);else if(e.data instanceof ye){let r=e.size??Rt(e.data.value);this.writeEBMLVarInt(r),this.writeSignedInt(e.data.value,r)}}}beforeTrackAdd(e){if(this.format instanceof te)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source._codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source._codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source._codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}async start(){let e=await this.mutex.acquire();this.writeEBMLHeader(),this.format._options.streamable||this.createSeekHead(),this.createSegmentInfo(),this.createCues(),await this.writer.flush(),e()}writeEBMLHeader(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.format instanceof te?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}createSeekHead(){let e=new Uint8Array([28,83,187,107]),r=new Uint8Array([21,73,169,102]),s=new Uint8Array([22,84,174,107]),a={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:r},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:s},{id:21420,size:5,data:0}]}]};this.seekHead=a}createSegmentInfo(){let e={id:17545,data:new de(0)};this.segmentDuration=e;let r={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:dr},{id:22337,data:dr},this.format._options.streamable?null:e]};this.segmentInfo=r}createTracks(){let e={id:374648427,data:[]};this.tracksElement=e;for(let r of this.trackDatas)e.data.push({id:174,data:[{id:215,data:r.track.id},{id:29637,data:r.track.id},{id:131,data:Ri[r.type]},{id:134,data:Ai[r.track.source._codec]},r.type==="video"?this.videoSpecificTrackInfo(r):null,r.type==="audio"?this.audioSpecificTrackInfo(r):null,r.type==="subtitle"?this.subtitleSpecificTrackInfo(r):null]})}videoSpecificTrackInfo(e){let r=[e.info.decoderConfig.description?{id:25506,data:q(e.info.decoderConfig.description)}:null,e.track.metadata.frameRate?{id:2352003,data:1e9/e.track.metadata.frameRate}:null],s=e.info.decoderConfig.colorSpace,a={id:224,data:[{id:176,data:e.info.width},{id:186,data:e.info.height},ze(s)?{id:21936,data:[{id:21937,data:Y[s.matrix]},{id:21946,data:G[s.transfer]},{id:21947,data:X[s.primaries]},{id:21945,data:s.fullRange?2:1}]}:null]};return r.push(a),r}audioSpecificTrackInfo(e){return[e.info.decoderConfig.description?{id:25506,data:q(e.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new we(e.info.sampleRate)},{id:159,data:e.info.numberOfChannels}]}]}subtitleSpecificTrackInfo(e){return[{id:25506,data:D.encode(e.info.config.description)}]}createSegment(){let e={id:408125543,size:this.format._options.streamable?-1:lr,data:[this.format._options.streamable?null:this.seekHead,this.segmentInfo,this.tracksElement]};this.segment=e,this.writeEBML(e)}createCues(){this.cues={id:475249515,data:[]}}get segmentDataOffset(){return d(this.segment),this.dataOffsets.get(this.segment)}getVideoTrackData(e,r){let s=this.trackDatas.find(n=>n.track===e);if(s)return s;$e(r),d(r),d(r.decoderConfig),d(r.decoderConfig.codedWidth!==void 0),d(r.decoderConfig.codedHeight!==void 0);let a={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(a),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),a}getAudioTrackData(e,r){let s=this.trackDatas.find(n=>n.track===e);if(s)return s;je(r),d(r),d(r.decoderConfig);let a={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(a),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),a}getSubtitleTrackData(e,r){let s=this.trackDatas.find(n=>n.track===e);if(s)return s;qe(r),d(r),d(r.config);let a={track:e,type:"subtitle",info:{config:r.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(a),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),a}async addEncodedVideoChunk(e,r,s){let a=await this.mutex.acquire();try{let n=this.getVideoTrackData(e,s),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=r.type==="key",u=this.validateAndNormalizeTimestamp(n.track,r.timestamp,c),m=this.createInternalChunk(o,u,(r.duration??0)/1e6,r.type);e.source._codec==="vp9"&&this.fixVP9ColorSpace(n,m),n.chunkQueue.push(m),await this.interleaveChunks()}finally{a()}}async addEncodedAudioChunk(e,r,s){let a=await this.mutex.acquire();try{let n=this.getAudioTrackData(e,s),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=r.type,u=c==="key",m=this.validateAndNormalizeTimestamp(n.track,r.timestamp,u),l=this.createInternalChunk(o,m,(r.duration??0)/1e6,c);n.chunkQueue.push(l),await this.interleaveChunks()}finally{a()}}async addSubtitleCue(e,r,s){let a=await this.mutex.acquire();try{let n=this.getSubtitleTrackData(e,s),o=this.validateAndNormalizeTimestamp(n.track,1e6*r.timestamp,!0),c=r.text,u=Math.floor(o*1e3);oe.lastIndex=0,c=c.replace(oe,g=>{let p=Be(g.slice(1,-1))-u;return`<${We(p)}>`});let m=D.encode(c),l=`${r.settings??""} +${r.identifier??""} +${r.notes??""}`,f=this.createInternalChunk(m,o,r.duration,"key",l.trim()?D.encode(l):null);n.chunkQueue.push(f),await this.interleaveChunks()}finally{a()}}async interleaveChunks(){for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let a of this.trackDatas){if(a.chunkQueue.length===0&&!a.track.source._closed)break e;a.chunkQueue.length>0&&a.chunkQueue[0].timestamp=2&&s++;let u={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];Vt(r.data,s+0,s+3,u)}createInternalChunk(e,r,s,a,n=null){return{data:e,type:a,timestamp:r,duration:s,additions:n}}writeBlock(e,r){this.segment||(this.createTracks(),this.createSegment());let s=Math.floor(1e3*r.timestamp),a=this.trackDatas.every(l=>{if(l.track.source._closed)return!0;if(e===l)return r.type==="key";let f=l.chunkQueue[0];return f&&f.type==="key"});(!this.currentCluster||a&&s-this.currentClusterMsTimestamp>=1e3)&&this.createNewCluster(s);let n=s-this.currentClusterMsTimestamp;if(n<0)return;if(n>=Ot)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${Ot} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${Ot} milliseconds.`);let c=new Uint8Array(4),u=new DataView(c.buffer);u.setUint8(0,128|e.track.id),u.setInt16(1,n,!1);let m=Math.floor(1e3*r.duration);if(m===0&&!r.additions){u.setUint8(3,+(r.type==="key")<<7);let l={id:163,data:[c,r.data]};this.writeEBML(l)}else{let l={id:160,data:[{id:161,data:[c,r.data]},r.type==="delta"?{id:251,data:new ye(e.lastWrittenMsTimestamp-s)}:null,r.additions?{id:30113,data:[{id:166,data:[{id:165,data:r.additions},{id:238,data:1}]}]}:null,m>0?{id:155,data:m}:null]};this.writeEBML(l)}this.duration=Math.max(this.duration,s+m),e.lastWrittenMsTimestamp=s,this.trackDatasInCurrentCluster.add(e)}createNewCluster(e){this.currentCluster&&!this.format._options.streamable&&this.finalizeCurrentCluster(),this.currentCluster={id:524531317,size:this.format._options.streamable?-1:fr,data:[{id:231,data:e}]},this.writeEBML(this.currentCluster),this.currentClusterMsTimestamp=e,this.trackDatasInCurrentCluster.clear()}finalizeCurrentCluster(){d(this.currentCluster);let e=this.writer.getPos()-this.dataOffsets.get(this.currentCluster),r=this.writer.getPos();this.writer.seek(this.offsets.get(this.currentCluster)+4),this.writeEBMLVarInt(e,fr),this.writer.seek(r);let s=this.offsets.get(this.currentCluster)-this.segmentDataOffset;d(this.cues),this.cues.data.push({id:187,data:[{id:179,data:this.currentClusterMsTimestamp},...[...this.trackDatasInCurrentCluster].map(a=>({id:183,data:[{id:247,data:a.track.id},{id:241,data:s}]}))]})}async onTrackClose(){let e=await this.mutex.acquire();await this.interleaveChunks(),e()}async finalize(){let e=await this.mutex.acquire();this.segment||(this.createTracks(),this.createSegment());for(let r of this.trackDatas)for(;r.chunkQueue.length>0;)this.writeBlock(r,r.chunkQueue.shift());if(!this.format._options.streamable&&this.currentCluster&&this.finalizeCurrentCluster(),d(this.cues),this.writeEBML(this.cues),!this.format._options.streamable){let r=this.writer.getPos(),s=this.writer.getPos()-this.segmentDataOffset;this.writer.seek(this.offsets.get(this.segment)+4),this.writeEBMLVarInt(s,lr),this.segmentDuration.data=new de(this.duration),this.writer.seek(this.offsets.get(this.segmentDuration)),this.writeEBML(this.segmentDuration),this.seekHead.data[0].data[1].data=this.offsets.get(this.cues)-this.segmentDataOffset,this.seekHead.data[1].data[1].data=this.offsets.get(this.segmentInfo)-this.segmentDataOffset,this.seekHead.data[2].data[1].data=this.offsets.get(this.tracksElement)-this.segmentDataOffset,this.writer.seek(this.offsets.get(this.seekHead)),this.writeEBML(this.seekHead),this.writer.seek(r)}e()}};var $=class{},Ye=class extends ${constructor(t={}){if(!t||typeof t!="object")throw new TypeError("options must be an object.");if(t.fastStart!==void 0&&![!1,"in-memory","fragmented"].includes(t.fastStart))throw new TypeError('options.fastStart, when provided, must be false, "in-memory", or "fragmented".');super(),this._options=t}_createMuxer(t){return new Xe(t,this)}},ve=class extends ${constructor(t={}){if(!t||typeof t!="object")throw new TypeError("options must be an object.");if(t.streamable!==void 0&&typeof t.streamable!="boolean")throw new TypeError("options.streamable, when provided, must be a boolean.");super(),this._options=t}_createMuxer(t){return new Ge(t,this)}},te=class extends ve{};var re=class{constructor(){this._connectedTrack=null;this._closed=!1;this._offsetTimestamps=!1}_ensureValidDigest(){if(!this._connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call digest before output has been started.");if(this._connectedTrack.output._finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this._closed)throw new Error("Cannot call digest after source has been closed.")}_start(){}async _flush(){}close(){if(this._closed)throw new Error("Source already closed.");if(!this._connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call close before output has been started.");this._closed=!0,!this._connectedTrack.output._finalizing&&this._connectedTrack.output._muxer.onTrackClose(this._connectedTrack)}},W=class extends re{constructor(e){super();this._connectedTrack=null;if(!J.includes(e))throw new TypeError(`Invalid video codec '${e}'. Must be one of: ${J.join(", ")}.`);this._codec=e}},Ze=class extends W{constructor(t){super(t)}digest(t,e){if(!(t instanceof EncodedVideoChunk))throw new TypeError("chunk must be an EncodedVideoChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedVideoChunk(this._connectedTrack,t,e)}},Oi=5,Ei=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!J.includes(i.codec))throw new TypeError(`Invalid video codec '${i.codec}'. Must be one of: ${J.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.");if(i.latencyMode!==void 0&&!["quality","realtime"].includes(i.latencyMode))throw new TypeError("config.latencyMode, when provided, must be 'quality' or 'realtime'.")},_e=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null;this.muxer=null;this.lastMultipleOfKeyFrameInterval=-1;this.lastWidth=null;this.lastHeight=null;Ei(e)}async digest(t){if(this.source._ensureValidDigest(),this.lastWidth!==null&&this.lastHeight!==null){if(t.codedWidth!==this.lastWidth||t.codedHeight!==this.lastHeight)throw new Error(`Video frame size must remain constant. Expected ${this.lastWidth}x${this.lastHeight}, got ${t.codedWidth}x${t.codedHeight}.`)}else this.lastWidth=t.codedWidth,this.lastHeight=t.codedHeight;this.ensureEncoder(t),d(this.encoder);let e=Math.floor(t.timestamp/1e6/Oi);this.encoder.encode(t,{keyFrame:e!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=e,this.encoder.encodeQueueSize>=4&&await new Promise(r=>this.encoder.addEventListener("dequeue",r,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(t){this.encoder||(this.encoder=new VideoEncoder({output:(e,r)=>void this.muxer.addEncodedVideoChunk(this.source._connectedTrack,e,r),error:e=>console.error("Video encode error:",e)}),this.encoder.configure({codec:sr(this.codecConfig.codec,t.codedWidth,t.codedHeight,this.codecConfig.bitrate),width:t.codedWidth,height:t.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source._connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode,...cr(this.codecConfig.codec)}),d(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},Je=class extends W{constructor(t){super(t.codec),this._encoder=new _e(this,t)}digest(t){if(!(t instanceof VideoFrame))throw new TypeError("videoFrame must be a VideoFrame.");return this._encoder.digest(t)}_flush(){return this._encoder.flush()}},et=class extends W{constructor(t,e){if(!(t instanceof HTMLCanvasElement))throw new TypeError("canvas must be an HTMLCanvasElement.");super(e.codec),this._encoder=new _e(this,e),this._canvas=t}digest(t,e=0){if(!Number.isFinite(t)||t<0)throw new TypeError("timestamp must be a non-negative number.");if(!Number.isFinite(e)||e<0)throw new TypeError("duration must be a non-negative number.");let r=new VideoFrame(this._canvas,{timestamp:Math.round(1e6*t),duration:Math.round(1e6*e),alpha:"discard"}),s=this._encoder.digest(r);return r.close(),s}_flush(){return this._encoder.flush()}},tt=class extends W{constructor(e,r){if(!(e instanceof MediaStreamTrack)||e.kind!=="video")throw new TypeError("track must be a video MediaStreamTrack.");r={...r,latencyMode:"realtime"};super(r.codec);this._abortController=null;this._offsetTimestamps=!0;this._encoder=new _e(this,r),this._track=e}_start(){this._abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this._track}),r=new WritableStream({write:s=>{this._encoder.digest(s),s.close()}});e.readable.pipeTo(r,{signal:this._abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},N=class extends re{constructor(e){super();this._connectedTrack=null;if(!ee.includes(e))throw new TypeError(`Invalid audio codec '${e}'. Must be one of: ${ee.join(", ")}.`);this._codec=e}},rt=class extends N{constructor(t){super(t)}digest(t,e){if(!(t instanceof EncodedAudioChunk))throw new TypeError("chunk must be an EncodedAudioChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedAudioChunk(this._connectedTrack,t,e)}},Fi=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!ee.includes(i.codec))throw new TypeError(`Invalid audio codec '${i.codec}'. Must be one of: ${ee.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.")},Ie=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null;this.muxer=null;this.lastNumberOfChannels=null;this.lastSampleRate=null;Fi(e)}async digest(t){if(this.source._ensureValidDigest(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(t.numberOfChannels!==this.lastNumberOfChannels||t.sampleRate!==this.lastSampleRate)throw new Error(`Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${t.numberOfChannels} channels at ${t.sampleRate} Hz.`)}else this.lastNumberOfChannels=t.numberOfChannels,this.lastSampleRate=t.sampleRate;this.ensureEncoder(t),d(this.encoder),this.encoder.encode(t),this.encoder.encodeQueueSize>=4&&await new Promise(e=>this.encoder.addEventListener("dequeue",e,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(t){this.encoder||(this.encoder=new AudioEncoder({output:(e,r)=>void this.muxer.addEncodedAudioChunk(this.source._connectedTrack,e,r),error:e=>console.error("Audio encode error:",e)}),this.encoder.configure({codec:nr(this.codecConfig.codec,t.numberOfChannels,t.sampleRate),numberOfChannels:t.numberOfChannels,sampleRate:t.sampleRate,bitrate:this.codecConfig.bitrate,...ur(this.codecConfig.codec)}),d(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},it=class extends N{constructor(t){super(t.codec),this._encoder=new Ie(this,t)}digest(t){if(!(t instanceof AudioData))throw new TypeError("audioData must be an AudioData.");return this._encoder.digest(t)}_flush(){return this._encoder.flush()}},st=class extends N{constructor(e){super(e.codec);this._accumulatedFrameCount=0;this._encoder=new Ie(this,e)}digest(e){if(!(e instanceof AudioBuffer))throw new TypeError("audioBuffer must be an AudioBuffer.");let r=e.numberOfChannels,s=e.sampleRate,a=e.length,n=new Float32Array(r*a);for(let u=0;u{this._encoder.digest(s),s.close()}});e.readable.pipeTo(r,{signal:this._abortController.signal}).catch(s=>{s instanceof DOMException&&s.name==="AbortError"||console.error("Pipe error:",s)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},ie=class extends re{constructor(e){super();this._connectedTrack=null;if(!Se.includes(e))throw new TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${Se.join(", ")}.`);this._codec=e}},nt=class extends ie{constructor(t){super(t),this._parser=new Ue({codec:t,output:(e,r)=>this._connectedTrack?.output._muxer.addSubtitleCue(this._connectedTrack,e,r),error:e=>console.error("Subtitle parse error:",e)})}digest(t){if(typeof t!="string")throw new TypeError("text must be a string.");return this._ensureValidDigest(),this._parser.parse(t),this._connectedTrack.output._muxer.mutex.currentPromise}};var ot=class{constructor(t){this._tracks=[];this._started=!1;this._finalizing=!1;this._mutex=new L;if(!t||typeof t!="object")throw new TypeError("options must be an object.");if(!(t.format instanceof $))throw new TypeError("options.format must be an OutputFormat.");if(!(t.target instanceof K))throw new TypeError("options.target must be a Target.");if(t.target._output)throw new Error("Target is already used for another output.");t.target._output=this,this._writer=t.target._createWriter(),this._muxer=t.format._createMuxer(this)}addVideoTrack(t,e={}){if(!(t instanceof W))throw new TypeError("source must be a VideoSource.");if(!e||typeof e!="object")throw new TypeError("metadata must be an object.");if(typeof e.rotation=="number"&&![0,90,180,270].includes(e.rotation))throw new TypeError(`Invalid video rotation: ${e.rotation}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(e.rotation)&&(e.rotation.length!==9||e.rotation.some(r=>!Number.isFinite(r))))throw new TypeError(`Invalid video transformation matrix: ${e.rotation.join()}`);if(e.frameRate!==void 0&&(!Number.isInteger(e.frameRate)||e.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${e.frameRate}. Must be a positive integer.`);this._addTrack("video",t,e)}addAudioTrack(t,e={}){if(!(t instanceof N))throw new TypeError("source must be an AudioSource.");if(!e||typeof e!="object")throw new TypeError("metadata must be an object.");this._addTrack("audio",t,e)}addSubtitleTrack(t,e={}){if(!(t instanceof ie))throw new TypeError("source must be a SubtitleSource.");if(!e||typeof e!="object")throw new TypeError("metadata must be an object.");this._addTrack("subtitle",t,e)}_addTrack(t,e,r){if(this._started)throw new Error("Cannot add track after output has started.");if(e._connectedTrack)throw new Error("Source is already used for a track.");let s={id:this._tracks.length+1,output:this,type:t,source:e,metadata:r};this._muxer.beforeTrackAdd(s),this._tracks.push(s),e._connectedTrack=s}async start(){if(this._started)throw new Error("Output already started.");this._started=!0,this._writer.start();let t=await this._mutex.acquire();await this._muxer.start();for(let e of this._tracks)e.source._start();t()}async finalize(){if(!this._started)throw new Error("Cannot finalize before starting.");if(this._finalizing)throw new Error("Cannot call finalize twice.");this._finalizing=!0;let t=await this._mutex.acquire(),e=this._tracks.map(r=>r.source._flush());await Promise.all(e),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),t()}};var le=class{constructor(){this._sizePromise=null}_getSize(){return this._sizePromise??=this._retrieveSize()}},ct=class extends le{constructor(t){super(),this._buffer=t}async _read(t,e){return new Uint8Array(this._buffer,t,e-t)}async _retrieveSize(){return this._buffer.byteLength}},ut=class extends le{constructor(t){super(),this._blob=t}async _read(t,e){let s=await this._blob.slice(t,e).arrayBuffer();return new Uint8Array(s)}async _retrieveSize(){return this._blob.size}};var mt=class{constructor(t){this.input=t}};var fe=class{constructor(t){this._backing=t}isVideoTrack(){return this instanceof se}isAudioTrack(){return this instanceof ae}computeDuration(){return this._backing.computeDuration()}},se=class extends fe{constructor(t){super(t),this._backing=t}getCodec(){return this._backing.getCodec()}getCodedWidth(){return this._backing.getCodedWidth()}getCodedHeight(){return this._backing.getCodedHeight()}getRotation(){return this._backing.getRotation()}async getDisplayWidth(){return await this._backing.getRotation()%180===0?this._backing.getCodedWidth():this._backing.getCodedHeight()}async getDisplayHeight(){return await this._backing.getRotation()%180===0?this._backing.getCodedHeight():this._backing.getCodedWidth()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}},ae=class extends fe{constructor(t){super(t),this._backing=t}getCodec(){return this._backing.getCodec()}getNumberOfChannels(){return this._backing.getNumberOfChannels()}getSampleRate(){return this._backing.getSampleRate()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}};var pe=class{constructor(t,e=1/0){this.source=t;this.maxStorableBytes=e;this.loadedSegments=[];this.loadingSegments=[];this.sourceSizePromise=null;this.nextAge=0;this.totalStoredBytes=0}async loadRange(t,e){e=Math.min(e,await this.source._getSize());let r=this.loadingSegments.find(c=>c.start<=t&&c.end>=e);if(r){await r.promise;return}if(this.loadedSegments.some(c=>c.start<=t&&c.end>=e))return;let a=this.source._read(t,e),n={start:t,end:e,promise:a};this.loadingSegments.push(n);let o=await a;Wt(this.loadingSegments,n),this.insertIntoLoadedSegments(t,o)}insertIntoLoadedSegments(t,e){let r={start:t,end:t+e.byteLength,bytes:e,view:new DataView(e.buffer),age:this.nextAge++},s=I(this.loadedSegments,t,a=>a.start);(s===-1||this.loadedSegments[s].start=r.end)break;r.start<=n.start&&n.end<=r.end&&(this.loadedSegments.splice(a,1),a--)}for(;this.totalStoredBytes>this.maxStorableBytes&&this.loadedSegments.length>1;){let a=null,n=-1;for(let o=0;oa.start),s=null;if(r!==-1)for(let a=r;at)break;if(e<=n.end){s=n;break}}if(!s)throw new Error(`No segment loaded for range [${t}, ${e}).`);return s.age=this.nextAge++,{view:s.view,offset:s.bytes.byteOffset+t-s.start}}forgetRange(t,e){if(e<=t)return;let r=I(this.loadedSegments,t,a=>a.start);if(r===-1)return;let s=this.loadedSegments[r];s.start!==t||s.end!==e||(this.loadedSegments.splice(r,1),this.totalStoredBytes-=s.bytes.byteLength)}};var ne=class{constructor(t){this.reader=t;this.pos=0}readRange(t,e){let{view:r,offset:s}=this.reader.getViewAndOffset(t,e);return new Uint8Array(r.buffer,s,e-t)}readU8(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+1);return this.pos++,t.getUint8(e)}readU16(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+2);return this.pos+=2,t.getUint16(e,!1)}readU24(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+3);this.pos+=3;let r=t.getUint16(e,!1),s=t.getUint8(e+2);return r*256+s}readS32(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,t.getInt32(e,!1)}readU32(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,t.getUint32(e,!1)}readI32(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,t.getInt32(e,!1)}readU64(){let t=this.readU32(),e=this.readU32();return t*4294967296+e}readF64(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+8);return this.pos+=8,t.getFloat64(e,!1)}readFixed_16_16(){return this.readS32()/65536}readFixed_2_30(){return this.readS32()/1073741824}readAscii(t){let{view:e,offset:r}=this.reader.getViewAndOffset(this.pos,this.pos+t);this.pos+=t;let s="";for(let a=0;as.computeDuration()));return Math.max(0,...r)}async getTracks(){return await this.readMetadata(),this.tracks.map(e=>e.inputTrack)}async getMimeType(){await this.readMetadata();let e="video/mp4";if(this.tracks.length>0){let r=await Promise.all(this.tracks.map(a=>a.inputTrack.getCodecMimeType())),s=[...new Set(r)];e+=`; codecs="${s.join(", ")}"`}return e}readMetadata(){return this.metadataPromise??=(async()=>{let e=await this.isobmffReader.reader.source._getSize();for(;this.isobmffReader.pos=0&&ss.presentationTimestamp-a.presentationTimestamp),e.sampleTable}async readFragment(){let e=this.isobmffReader.pos;await this.isobmffReader.reader.loadRange(this.isobmffReader.pos,this.isobmffReader.pos+16);let r=this.isobmffReader.readBoxHeader();d(r.name==="moof"),await this.isobmffReader.reader.loadRange(e,e+r.totalSize),this.isobmffReader.pos=e,this.traverseBox();let s=H(this.fragments,e,n=>n.moofOffset);d(s!==-1);let a=this.fragments[s];d(a.moofOffset===e),this.isobmffReader.reader.forgetRange(e,e+r.totalSize);for(let[n,o]of a.trackData){if(o.startTimestampIsFinal)continue;let c=this.tracks.find(f=>f.id===n);this.isobmffReader.pos=0;let u=null,m=null,l=I(c.fragments,e-1,f=>f.moofOffset);for(l!==-1&&(u=c.fragments[l],m=u,this.isobmffReader.pos=u.moofOffset+u.moofSize);this.isobmffReader.posp.moofOffset);if(b===-1){this.isobmffReader.pos=f;let p=await this.readFragment();u&&(u.nextFragment=p),u=p}else{let p=this.fragments[b];u&&(u.nextFragment=p),u=p}}this.isobmffReader.pos=f+g.totalSize}u&&u.trackData.has(n)&&(m=u)}if(m){let f=m.trackData.get(n);d(f.startTimestampIsFinal),hr(o,f.endTimestamp)}o.startTimestampIsFinal=!0}return a}readContiguousBoxes(e){let r=this.isobmffReader.pos;for(;this.isobmffReader.pos-rl.every((f,g)=>f===u[g]));m===-1?a.rotation=0:a.rotation=90*m}break;case"mdhd":{let a=this.currentTrack;d(a);let n=this.isobmffReader.readU8();this.isobmffReader.pos+=3,n===0?(this.isobmffReader.pos+=8,a.timescale=this.isobmffReader.readU32(),a.durationInTimescale=this.isobmffReader.readU32()):n===1&&(this.isobmffReader.pos+=16,a.timescale=this.isobmffReader.readU32(),a.durationInTimescale=this.isobmffReader.readU64())}break;case"hdlr":{let a=this.currentTrack;d(a),this.isobmffReader.pos+=8;let n=this.isobmffReader.readAscii(4);n==="vide"?a.info={type:"video",width:-1,height:-1,codec:null,codecDescription:null,colorSpace:null}:n==="soun"&&(a.info={type:"audio",numberOfChannels:-1,sampleRate:-1,codec:null,codecDescription:null})}break;case"stbl":{let a=this.currentTrack;d(a),a.sampleTableOffset=e,this.readContiguousBoxes(r.contentSize)}break;case"stsd":{let a=this.currentTrack;if(d(a),a.info===null||a.sampleTable)break;let n=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let o=this.isobmffReader.readU32();for(let c=0;c0){if(m===1)this.isobmffReader.pos+=4*4;else if(m===2){this.isobmffReader.pos+=4,f=this.isobmffReader.readF64(),l=this.isobmffReader.readU32(),this.isobmffReader.pos+=4;let g=this.isobmffReader.readU32(),b=this.isobmffReader.readU32(),p=this.isobmffReader.readU32(),k=this.isobmffReader.readU32()}}a.info.numberOfChannels=l,a.info.sampleRate=f,this.readContiguousBoxes(e+u.totalSize-this.isobmffReader.pos)}}}break;case"avcC":{let a=this.currentTrack;d(a&&a.info),a.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+r.contentSize)}break;case"hvcC":{let a=this.currentTrack;d(a&&a.info),a.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+r.contentSize)}break;case"colr":{let a=this.currentTrack;if(d(a&&a.info?.type==="video"),this.isobmffReader.readAscii(4)!=="nclx")break;let o=this.isobmffReader.readU16(),c=this.isobmffReader.readU16(),u=this.isobmffReader.readU16(),m=!!(this.isobmffReader.readU8()&128);a.info.colorSpace={primaries:Dt[o],transfer:Pt[c],matrix:zt[u],fullRange:m}}break;case"wave":r.totalSize>8&&this.readContiguousBoxes(r.contentSize);break;case"esds":{let a=this.currentTrack;d(a&&a.info),this.isobmffReader.pos+=4;let n=this.isobmffReader.readU8();d(n===3),this.isobmffReader.readIsomVariableInteger(),this.isobmffReader.pos+=2;let o=this.isobmffReader.readU8(),c=(o&128)!==0,u=(o&64)!==0,m=(o&32)!==0;if(c&&(this.isobmffReader.pos+=2),u){let p=this.isobmffReader.readU8();this.isobmffReader.pos+=p}m&&(this.isobmffReader.pos+=2);let l=this.isobmffReader.readU8();d(l===4),this.isobmffReader.readIsomVariableInteger();let f=this.isobmffReader.readU8();d(f===64),this.isobmffReader.pos+=12;let g=this.isobmffReader.readU8();d(g===5);let b=this.isobmffReader.readIsomVariableInteger();a.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+b)}break;case"stts":{let a=this.currentTrack;if(d(a),!a.sampleTable)break;this.isobmffReader.pos+=4;let n=this.isobmffReader.readU32(),o=0,c=0;for(let u=0;uv.id===n);if(!o)break;o.fragmentLookupTable=[];let c=this.isobmffReader.readU32(),u=(c&48)>>4,m=(c&12)>>2,l=c&3,f=this.isobmffReader,g=[f.readU8.bind(f),f.readU16.bind(f),f.readU24.bind(f),f.readU32.bind(f)],b=g[u],p=g[m],k=g[l],w=this.isobmffReader.readU32();for(let v=0;vn.moofOffset);this.fragments.splice(a+1,0,this.currentFragment);for(let[,n]of this.currentFragment.trackData){let o=n.samples[0],c=R(n.samples);this.currentFragment.dataStart=Math.min(this.currentFragment.dataStart,o.byteOffset),this.currentFragment.dataEnd=Math.max(this.currentFragment.dataEnd,c.byteOffset+c.byteSize)}this.currentFragment=null}break;case"traf":if(d(this.currentFragment),this.readContiguousBoxes(r.contentSize),this.currentTrack){let a=this.currentFragment.trackData.get(this.currentTrack.id);if(a){let n=I(this.currentTrack.fragments,this.currentFragment.moofOffset,c=>c.moofOffset);this.currentTrack.fragments.splice(n+1,0,this.currentFragment);let{currentFragmentState:o}=this.currentTrack;d(o),o.startTimestamp!==null&&(hr(a,o.startTimestamp),a.startTimestampIsFinal=!0)}this.currentTrack.currentFragmentState=null,this.currentTrack=null}break;case"tfhd":{d(this.currentFragment),this.isobmffReader.pos+=1;let a=this.isobmffReader.readU24(),n=!!(a&1),o=!!(a&2),c=!!(a&8),u=!!(a&16),m=!!(a&32),l=!!(a&65536),f=!!(a&131072),g=this.isobmffReader.readU32(),b=this.tracks.find(k=>k.id===g);if(!b)break;let p=this.fragmentTrackDefaults.find(k=>k.trackId===g);this.currentTrack=b,b.currentFragmentState={baseDataOffset:this.currentFragment.implicitBaseDataOffset,sampleDescriptionIndex:p?.defaultSampleDescriptionIndex??null,defaultSampleDuration:p?.defaultSampleDuration??null,defaultSampleSize:p?.defaultSampleSize??null,defaultSampleFlags:p?.defaultSampleFlags??null,startTimestamp:null},n?b.currentFragmentState.baseDataOffset=this.isobmffReader.readU64():f&&(b.currentFragmentState.baseDataOffset=this.currentFragment.moofOffset),o&&(b.currentFragmentState.sampleDescriptionIndex=this.isobmffReader.readU32()),c&&(b.currentFragmentState.defaultSampleDuration=this.isobmffReader.readU32()),u&&(b.currentFragmentState.defaultSampleSize=this.isobmffReader.readU32()),m&&(b.currentFragmentState.defaultSampleFlags=this.isobmffReader.readU32()),l&&(b.currentFragmentState.defaultSampleDuration=0)}break;case"tfdt":{let a=this.currentTrack;if(!a)break;d(a.currentFragmentState);let n=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let o=n===0?this.isobmffReader.readU32():this.isobmffReader.readU64();a.currentFragmentState.startTimestamp=o}break;case"trun":{let a=this.currentTrack;if(!a)break;if(d(this.currentFragment),d(a.currentFragmentState),this.currentFragment.trackData.has(a.id))throw new Error("Can't have two trun boxes for the same track in one fragment.");let n=this.isobmffReader.readU8(),o=this.isobmffReader.readU24(),c=!!(o&1),u=!!(o&4),m=!!(o&256),l=!!(o&512),f=!!(o&1024),g=!!(o&2048),b=this.isobmffReader.readU32(),p=a.currentFragmentState.baseDataOffset;c&&(p+=this.isobmffReader.readI32());let k=null;u&&(k=this.isobmffReader.readU32());let w=p;if(b===0){this.currentFragment.implicitBaseDataOffset=w;break}let v=0,T={startTimestamp:0,endTimestamp:0,samples:[],presentationTimestamps:[],startTimestampIsFinal:!1};this.currentFragment.trackData.set(a.id,T);for(let z=0;z({presentationTimestamp:z.presentationTimestamp,sampleIndex:V})).sort((z,V)=>z.presentationTimestamp-V.presentationTimestamp);let A=T.samples[T.presentationTimestamps[0].sampleIndex],F=T.samples[R(T.presentationTimestamps).sampleIndex];T.startTimestamp=A.presentationTimestamp,T.endTimestamp=F.presentationTimestamp+F.duration,this.currentFragment.implicitBaseDataOffset=w}break}this.isobmffReader.pos=s}},lt=class{constructor(t){this.internalTrack=t;this.chunkToSampleIndex=new WeakMap;this.chunkToFragmentLocation=new WeakMap}getCodec(){throw new Error("Not implemented on base class.")}async computeDuration(){let e=(await this.getChunk(1/0,{metadataOnly:!0}))?.timestamp;return e?e/1e6:0}async getFirstChunk(t){return this.internalTrack.demuxer.isFragmented?this.performFragmentedLookup(()=>{let e=this.internalTrack.fragments[0];return{fragmentIndex:e?0:-1,sampleIndex:e?0:-1,correctSampleFound:!!e}},0,1/0,t):this.fetchChunkForSampleIndex(0,t)}roundToMicrosecond(t){return(Math.floor(t*1e6)+.99999999)/1e6}async getChunk(t,e){t=this.roundToMicrosecond(t);let r=t*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findSampleInFragmentsForTimestamp(r),r,r,e);{let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=pr(s,r);return this.fetchChunkForSampleIndex(a,e)}}async getNextChunk(t,e){if(this.internalTrack.demuxer.isFragmented){let s=this.chunkToFragmentLocation.get(t);if(s===void 0)throw new Error("Chunk was not created from this track.");let a=s.fragment.trackData.get(this.internalTrack.id),n=a.samples[s.sampleIndex],o=H(this.internalTrack.fragments,s.fragment.moofOffset,c=>c.moofOffset);return d(o!==-1),this.performFragmentedLookup(()=>{if(s.sampleIndex+1l.moofOffset);return d(m!==-1),{fragmentIndex:m,sampleIndex:0,correctSampleFound:!0}}return{fragmentIndex:o,sampleIndex:-1,correctSampleFound:!1}}},n.presentationTimestamp,1/0,e)}let r=this.chunkToSampleIndex.get(t);if(r===void 0)throw new Error("Chunk was not created from this track.");return this.fetchChunkForSampleIndex(r+1,e)}async getKeyChunk(t,e){t=this.roundToMicrosecond(t);let r=t*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findKeySampleInFragmentsForTimestamp(r),r,r,e);let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=pr(s,r),n=a===-1?-1:Di(s,a);return this.fetchChunkForSampleIndex(n,e)}async getNextKeyChunk(t,e){if(this.internalTrack.demuxer.isFragmented){let n=this.chunkToFragmentLocation.get(t);if(n===void 0)throw new Error("Chunk was not created from this track.");let o=n.fragment.trackData.get(this.internalTrack.id),c=o.samples[n.sampleIndex],u=H(this.internalTrack.fragments,n.fragment.moofOffset,m=>m.moofOffset);return d(u!==-1),this.performFragmentedLookup(()=>{let m=o.samples.findIndex((l,f)=>l.isKeyFrame&&f>n.sampleIndex);if(m!==-1)return{fragmentIndex:u,sampleIndex:m,correctSampleFound:!0};{let l=n.fragment;for(;l.nextFragment;){l=l.nextFragment;let f=l.trackData.get(this.internalTrack.id);if(f){let g=H(this.internalTrack.fragments,l.moofOffset,p=>p.moofOffset);d(g!==-1);let b=f.samples.findIndex(p=>p.isKeyFrame);if(b===-1)throw new Error("Not supported: Fragment does not contain key sample.");return{fragmentIndex:g,sampleIndex:b,correctSampleFound:!0}}}return{fragmentIndex:u,sampleIndex:-1,correctSampleFound:!1}}},c.presentationTimestamp,1/0,e)}let r=this.chunkToSampleIndex.get(t);if(r===void 0)throw new Error("Chunk was not created from this track.");let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=Pi(s,r);return this.fetchChunkForSampleIndex(a,e)}async fetchChunkForSampleIndex(t,e){if(t===-1)return null;let r=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),s=Vi(r,t);if(!s)return null;let a;e.metadataOnly?a=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(s.chunkOffset,s.chunkOffset+s.chunkSize),a=this.internalTrack.demuxer.chunkReader.readRange(s.sampleOffset,s.sampleOffset+s.sampleSize));let n=1e6*s.presentationTimestamp/this.internalTrack.timescale,o=1e6*s.duration/this.internalTrack.timescale,c=this.createChunk(a,n,o,s.isKeyFrame);return this.chunkToSampleIndex.set(c,t),c}async fetchChunkInFragment(t,e,r){if(e===-1)return null;let a=t.trackData.get(this.internalTrack.id).samples[e];d(a);let n;r.metadataOnly?n=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(t.dataStart,t.dataEnd),n=this.internalTrack.demuxer.chunkReader.readRange(a.byteOffset,a.byteOffset+a.byteSize));let o=1e6*a.presentationTimestamp/this.internalTrack.timescale,c=1e6*a.duration/this.internalTrack.timescale,u=this.createChunk(n,o,c,a.isKeyFrame);return this.chunkToFragmentLocation.set(u,{fragment:t,sampleIndex:e}),u}findSampleInFragmentsForTimestamp(t){let e=I(this.internalTrack.fragments,t,a=>a.trackData.get(this.internalTrack.id).startTimestamp),r=-1,s=!1;if(e!==-1){let n=this.internalTrack.fragments[e].trackData.get(this.internalTrack.id),o=I(n.presentationTimestamps,t,c=>c.presentationTimestamp);d(o!==-1),r=n.presentationTimestamps[o].sampleIndex,s=ta.trackData.get(this.internalTrack.id).startTimestamp),r=-1,s=!1;if(e!==-1){let n=this.internalTrack.fragments[e].trackData.get(this.internalTrack.id),o=Nt(n.presentationTimestamps,u=>n.samples[u.sampleIndex].isKeyFrame&&u.presentationTimestamp<=t);if(o===-1)throw new Error("Not supported: Fragment does not begin with a key sample.");r=n.presentationTimestamps[o].sampleIndex,s=tw.timestamp);k!==-1&&(p=this.internalTrack.fragmentLookupTable[k])}if(o===-1)m.pos=p?.moofOffset??0;else{let k=this.internalTrack.fragments[o];!p||k.moofOffset>=k.moofOffset?(m.pos=k.moofOffset+k.moofSize,f=k):m.pos=p.moofOffset}for(;m.posr)break;if(f.nextFragment){m.pos=f.nextFragment.moofOffset+f.nextFragment.moofSize,f=f.nextFragment;continue}}await m.reader.loadRange(m.pos,m.pos+16);let k=m.pos,w=m.readBoxHeader();if(w.name==="moof"){let v=H(a.fragments,k,T=>T.moofOffset);if(v===-1){m.pos=k;let T=await a.readFragment();f&&(f.nextFragment=T),f=T;let{fragmentIndex:A,sampleIndex:F,correctSampleFound:z}=t();if(z){let V=this.internalTrack.fragments[A];return this.fetchChunkInFragment(V,F,s)}A!==-1&&(g=A,b=F)}else{let T=a.fragments[v];f&&(f.nextFragment=T),f=T}}m.pos=k+w.totalSize}if(g!==-1){let k=this.internalTrack.fragments[g];return this.fetchChunkInFragment(k,b,s)}return null}finally{n()}}},Et=class extends lt{constructor(t){super(t),this.internalTrack=t}async getCodec(){return this.internalTrack.info.codec}async getCodedWidth(){return this.internalTrack.info.width}async getCodedHeight(){return this.internalTrack.info.height}async getRotation(){return this.internalTrack.rotation}async getDecoderConfig(){return{codec:ar(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),codedWidth:this.internalTrack.info.width,codedHeight:this.internalTrack.info.height,description:this.internalTrack.info.codecDescription??void 0,colorSpace:this.internalTrack.info.colorSpace??void 0}}createChunk(t,e,r,s){return new EncodedVideoChunk({data:t,timestamp:e,duration:r,type:s?"key":"delta"})}},Ft=class extends lt{constructor(t){super(t),this.internalTrack=t}async getCodec(){return this.internalTrack.info.codec}async getNumberOfChannels(){return this.internalTrack.info.numberOfChannels}async getSampleRate(){return this.internalTrack.info.sampleRate}async getDecoderConfig(){return{codec:or(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),numberOfChannels:this.internalTrack.info.numberOfChannels,sampleRate:this.internalTrack.info.sampleRate,description:this.internalTrack.info.codecDescription??void 0}}createChunk(t,e,r,s){return new EncodedAudioChunk({data:t,timestamp:e,duration:r,type:s?"key":"delta"})}},pr=(i,t)=>{let e=I(i.presentationTimestamps,t,r=>r.presentationTimestamp);return e===-1?-1:i.presentationTimestamps[e].sampleIndex},Vi=(i,t)=>{let e=I(i.sampleTimingEntries,t,p=>p.startIndex),r=i.sampleTimingEntries[e];if(!r||r.startIndex+r.count<=t)return null;let a=r.startDecodeTimestamp+(t-r.startIndex)*r.delta,n=I(i.sampleCompositionTimeOffsets,t,p=>p.startIndex),o=i.sampleCompositionTimeOffsets[n];o&&(a+=o.offset);let c=i.sampleSizes[Math.min(t,i.sampleSizes.length-1)],u=I(i.sampleToChunk,t,p=>p.startSampleIndex),m=i.sampleToChunk[u];d(m);let l=m.startChunkIndex+Math.floor((t-m.startSampleIndex)/m.samplesPerChunk),f=i.chunkOffsets[l],g=0,b=f;if(i.sampleSizes.length===1)b+=c*(t-m.startSampleIndex),g+=c*m.samplesPerChunk;else{let p=m.startSampleIndex+(l-m.startChunkIndex)*m.samplesPerChunk;for(let k=p;kp)!==-1:!0}},Di=(i,t)=>{if(!i.keySampleIndices)return t;let e=I(i.keySampleIndices,t,r=>r);return i.keySampleIndices[e]??-1},Pi=(i,t)=>{if(!i.keySampleIndices)return t+1;let e=I(i.keySampleIndices,t,r=>r);return i.keySampleIndices[e+1]??-1},hr=(i,t)=>{i.startTimestamp+=t,i.endTimestamp+=t;for(let e of i.samples)e.presentationTimestamp+=t;for(let e of i.presentationTimestamps)e.presentationTimestamp+=t};var he=class{},Ae=class extends he{async _canReadInput(t){if(await t._mainReader.source._getSize()<8)return!1;let r=new ne(t._mainReader);return r.pos=4,r.readAscii(4)==="ftyp"}_createDemuxer(t){return new dt(t)}},Re=class extends he{async _canReadInput(){return!1}_createDemuxer(){throw new Error("Not implemented")}},Oe=new Ae,br=Oe,kr=Oe,ft=new Re,Mt=ft,gr=ft,Tr=[Oe,Mt];var pt=class{constructor(t){this._demuxerPromise=null;this._format=null;this._formats=t.formats,this._source=t.source,this._mainReader=new pe(t.source)}_getDemuxer(){return this._demuxerPromise??=(async()=>{await this._mainReader.loadRange(0,4096);for(let t of this._formats)if(await t._canReadInput(this))return this._format=t,t._createDemuxer(this);throw new Error("Input has an unrecognizable format.")})()}async getFormat(){return await this._getDemuxer(),d(this._format),this._format}async computeDuration(){return(await this._getDemuxer()).computeDuration()}async getTracks(){return(await this._getDemuxer()).getTracks()}async getVideoTracks(){return(await this.getTracks()).filter(e=>e.isVideoTrack())}async getPrimaryVideoTrack(){return(await this.getTracks()).find(e=>e.isVideoTrack())??null}async getAudioTracks(){return(await this.getTracks()).filter(e=>e.isAudioTrack())}async getPrimaryAudioTrack(){return(await this.getTracks()).find(e=>e.isAudioTrack())??null}async getMimeType(){return(await this._getDemuxer()).getMimeType()}};var be=class{async*chunks(t,e=1/0){let r=[],{promise:s,resolve:a}=E(),{promise:n,resolve:o}=E(),c=!1,u=[],m=()=>Math.max(2,u.length);(async()=>{let l=t??await this.getFirstChunk();for(;l&&!c&&!(l.timestamp/1e6>=e);){if(r.length>m()){({promise:n,resolve:o}=E()),await n;continue}r.push(l),a(),{promise:s,resolve:a}=E(),l=await this.getNextChunk(l)}c=!0,a()})();try{for(;;)if(r.length>0){yield r.shift();let l=performance.now();for(u.push(l);u.length>0&&l-u[0]>=1e3;)u.shift();o()}else if(!c)await s;else break}finally{c=!0,o()}}},ke=class{_duplicateFrame(t){return structuredClone(t)}async*mediaFramesAtTimestamps(t){let e=Ht(t),r=[],s=[],{promise:a,resolve:n}=E(),{promise:o,resolve:c}=E(),u=!1,m=!1,l=8,f=null,g=p=>{s.push(p),n(),{promise:a,resolve:n}=E()},b=await this._createDecoder(p=>{if(c(),m){p.close();return}let k=!1;for(;r.length>0&&r[0]===p.timestamp;)g(this._duplicateFrame(p)),r.shift(),k=!0;k?(f?.close(),f=p):p.close()});(async()=>{let p=this._createChunkDrain(),k=null,w=null;for await(let v of e){for(;s.length+b.decodeQueueSize>l;)({promise:o,resolve:c}=E()),await o;if(m)break;let T=await p.getChunk(v);if(!T){g(null);continue}let A=await p.getKeyChunk(v);if(!A){g(null);continue}for(r.push(T.timestamp),k&&A.timestamp===k.timestamp&&T.timestamp>=w.timestamp?(d(w),T.timestamp===w.timestamp&&r.length===1&&(f&&g(this._duplicateFrame(f)),r.shift())):(k=A,w=A,b.decode(A));w.timestamp!==T.timestamp;){let F=await p.getNextChunk(w);d(F),w=F,b.decode(F)}b.decodeQueueSize>=10&&await new Promise(F=>b.addEventListener("dequeue",F,{once:!0}))}await b.flush(),b.close(),u=!0,n()})();try{for(;;)if(s.length>0){let p=s.shift();d(p!==void 0),yield p,c()}else if(!u)await a;else break}finally{m=!0,c();for(let p of s)p?.close();f?.close()}}async*mediaFramesInRange(t=0,e=1/0){let r=[],s=!1,a=null,{promise:n,resolve:o}=E(),{promise:c,resolve:u}=E(),m=!1,l=!1,f=8,g=await this._createDecoder(k=>{u();let w=k.timestamp/1e6;if(w>=e&&(l=!0),l){k.close();return}a&&(w>t?(r.push(a),s=!0):a.close()),w>=t&&(r.push(k),s=!0),a=s?null:k,r.length>0&&(o(),{promise:n,resolve:o}=E())}),b=this._createChunkDrain(),p=await b.getKeyChunk(t)??await b.getFirstChunk();if(p){(async()=>{let k=p,w=1/0;if(e<1/0){let T=await b.getChunk(e),A=T?T.type==="key"&&T.timestamp/1e6===e?T:await b.getNextKeyChunk(T):null;A&&(w=A.timestamp/1e6)}let v=b.chunks(p,w);for(await v.next();k&&!l;){if(r.length+g.decodeQueueSize>f){({promise:c,resolve:u}=E()),await c;continue}g.decode(k);let T=await v.next();if(T.done)break;k=T.value}await v.return(),await g.flush(),g.close(),!s&&a&&r.push(a),m=!0,o()})();try{for(;;)if(r.length>0)yield r.shift(),u();else if(!m)await n;else break}finally{l=!0,u();for(let k of r)k.close()}}}},Ee=class extends be{constructor(t){super(),this._videoTrack=t}getFirstChunk(t={}){return this._videoTrack._backing.getFirstChunk(t)}getChunk(t,e={}){return this._videoTrack._backing.getChunk(t,e)}getNextChunk(t,e={}){return this._videoTrack._backing.getNextChunk(t,e)}getKeyChunk(t,e={}){return this._videoTrack._backing.getKeyChunk(t,e)}getNextKeyChunk(t,e={}){return this._videoTrack._backing.getNextKeyChunk(t,e)}},Fe=class extends ke{constructor(e){super();this._decoderConfig=null;this._videoTrack=e}async _createDecoder(e){this._decoderConfig??=await this._videoTrack.getDecoderConfig();let r=new VideoDecoder({output:e,error:s=>console.error(s)});return r.configure(this._decoderConfig),r}_createChunkDrain(){return new Ee(this._videoTrack)}async getFrame(e){for await(let r of this.mediaFramesAtTimestamps([e]))return r;throw new Error("Internal error: Iterator returned nothing.")}frames(e=0,r=1/0){return this.mediaFramesInRange(e,r)}framesAtTimestamps(e){return this.mediaFramesAtTimestamps(e)}},ht=class{constructor(t,e){this._videoTrack=t,this._dimensions=e,this._videoFrameDrain=new Fe(t)}async _videoFrameToWrappedCanvas(t){let e=this._dimensions?.width??await this._videoTrack.getDisplayWidth(),r=this._dimensions?.height??await this._videoTrack.getDisplayHeight(),s=await this._videoTrack.getRotation(),a=document.createElement("canvas");a.width=e,a.height=r;let n=a.getContext("2d",{alpha:!1});d(n),n.translate(e/2,r/2),n.rotate(s*Math.PI/180),n.translate(-e/2,-r/2);let[o,c]=s%180===0?[e,r]:[r,e];n.drawImage(t,(e-o)/2,(r-c)/2,o,c);let u={canvas:a,timestamp:t.timestamp/1e6,duration:(t.duration??0)/1e6};return t.close(),u}async getCanvas(t){let e=await this._videoFrameDrain.getFrame(t);return e&&this._videoFrameToWrappedCanvas(e)}async*canvases(t=0,e=1/0){for await(let r of this._videoFrameDrain.frames(t,e))yield this._videoFrameToWrappedCanvas(r)}async*canvasesAtTimestamps(t){for await(let e of this._videoFrameDrain.framesAtTimestamps(t))yield e&&this._videoFrameToWrappedCanvas(e)}},Me=class extends be{constructor(t){super(),this._audioTrack=t}getFirstChunk(t={}){return this._audioTrack._backing.getFirstChunk(t)}getChunk(t,e={}){return this._audioTrack._backing.getChunk(t,e)}getNextChunk(t,e={}){return this._audioTrack._backing.getNextChunk(t,e)}getKeyChunk(t,e={}){return this._audioTrack._backing.getKeyChunk(t,e)}getNextKeyChunk(t,e={}){return this._audioTrack._backing.getNextKeyChunk(t,e)}},Ve=class extends ke{constructor(e){super();this._decoderConfig=null;this._audioTrack=e}async _createDecoder(e){this._decoderConfig??=await this._audioTrack.getDecoderConfig();let r=new AudioDecoder({output:e,error:s=>console.error(s)});return r.configure(this._decoderConfig),r}_createChunkDrain(){return new Me(this._audioTrack)}async getData(e){for await(let r of this.mediaFramesAtTimestamps([e]))return r;throw new Error("Internal error: Iterator returned nothing.")}data(e=0,r=1/0){return this.mediaFramesInRange(e,r)}dataAtTimestamps(e){return this.mediaFramesAtTimestamps(e)}},bt=class{constructor(t){this._audioDataDrain=new Ve(t)}_audioDataToWrappedArrayBuffer(t){let e=new AudioBuffer({numberOfChannels:t.numberOfChannels,length:t.numberOfFrames,sampleRate:t.sampleRate}),r=new Float32Array(t.allocationSize({planeIndex:0,format:"f32-planar"})/4);for(let n=0;ni&&i[i.length-1],Q=i=>i>=0&&i<2**32,E=(i,e,t)=>{let r=0;for(let s=e;s>c;r<<=1,r|=o}return r},Ft=(i,e,t,r)=>{for(let s=e;s>t-s-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),D=new TextEncoder,Ze=i=>Object.fromEntries(Object.entries(i).map(([e,t])=>[t,e])),$={bt709:1,bt470bg:5,smpte170m:6},Mt=Ze($),j={bt709:1,smpte170m:6,"iec61966-2-1":13},Vt=Ze(j),q={rgb:0,bt709:1,bt470bg:5,smpte170m:6},Dt=Ze(q),ye=i=>!!i&&!!i.primaries&&!!i.transfer&&!!i.matrix&&i.fullRange!==void 0,Je=i=>i instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&i instanceof SharedArrayBuffer||ArrayBuffer.isView(i)&&!(i instanceof DataView),H=class{currentPromise=Promise.resolve();async acquire(){let e,t=new Promise(s=>{e=s}),r=this.currentPromise;return this.currentPromise=t,await r,e}},L=i=>{let e=i*(Math.PI/180),t=Math.cos(e),r=Math.sin(e);return[t,r,0,-r,t,0,0,0,1]},et=L(0),Pt=i=>[...i].map(e=>e.toString(16).padStart(2,"0")).join(""),zt=i=>(i=i>>1&1431655765|(i&1431655765)<<1,i=i>>2&858993459|(i&858993459)<<2,i=i>>4&252645135|(i&252645135)<<4,i=i>>8&16711935|(i&16711935)<<8,i=i>>16&65535|(i&65535)<<16,i>>>0),B=(i,e,t)=>{let r=0,s=i.length-1,a=-1;for(;r<=s;){let n=r+s>>1,c=t(i[n]);c===e?(a=n,s=n-1):c{let r=-1,s=0,a=i.length-1;for(;s<=a;){let n=s+(a-s+1)/2|0;t(i[n])<=e?(r=n,s=n+1):a=n-1}return r},F=()=>{let i,e;return{promise:new Promise((r,s)=>{i=r,e=s}),resolve:i,reject:e}},Ut=(i,e)=>{let t=i.indexOf(e);t!==-1&&i.splice(t,1)},Bt=async function*(i){Symbol.iterator in i?yield*i[Symbol.iterator]():yield*i[Symbol.asyncIterator]()};var le=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,hr=/^WEBVTT(.|\n)*?\n{2}/,ee=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,ve=class{options;preambleText=null;preambleEmitted=!1;constructor(e){this.options=e}parse(e){e=e.replaceAll(`\r +function d(i){if(!i)throw new Error("Assertion failed.")}var R=i=>i&&i[i.length-1],K=i=>i>=0&&i<2**32,O=(i,t,e)=>{let r=0;for(let a=t;a>o;r<<=1,r|=c}return r},Ft=(i,t,e,r)=>{for(let a=t;a>e-a-1<i instanceof ArrayBuffer?new Uint8Array(i):new Uint8Array(i.buffer,i.byteOffset,i.byteLength),D=new TextEncoder,et=i=>Object.fromEntries(Object.entries(i).map(([t,e])=>[e,t])),j={bt709:1,bt470bg:5,smpte170m:6},Mt=et(j),q={bt709:1,smpte170m:6,"iec61966-2-1":13},Vt=et(q),X={rgb:0,bt709:1,bt470bg:5,smpte170m:6},Dt=et(X),Ae=i=>!!i&&!!i.primaries&&!!i.transfer&&!!i.matrix&&i.fullRange!==void 0,tt=i=>i instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&i instanceof SharedArrayBuffer||ArrayBuffer.isView(i)&&!(i instanceof DataView),L=class{constructor(){this.currentPromise=Promise.resolve()}async acquire(){let t,e=new Promise(a=>{t=a}),r=this.currentPromise;return this.currentPromise=e,await r,t}},Q=i=>{let t=i*(Math.PI/180),e=Math.cos(t),r=Math.sin(t);return[e,r,0,-r,e,0,0,0,1]},rt=Q(0),Pt=i=>[...i].map(t=>t.toString(16).padStart(2,"0")).join(""),zt=i=>(i=i>>1&1431655765|(i&1431655765)<<1,i=i>>2&858993459|(i&858993459)<<2,i=i>>4&252645135|(i&252645135)<<4,i=i>>8&16711935|(i&16711935)<<8,i=i>>16&65535|(i&65535)<<16,i>>>0),W=(i,t,e)=>{let r=0,a=i.length-1,s=-1;for(;r<=a;){let n=r+a>>1,o=e(i[n]);o===t?(s=n,a=n-1):o{let r=-1,a=0,s=i.length-1;for(;a<=s;){let n=a+(s-a+1)/2|0;e(i[n])<=t?(r=n,a=n+1):s=n-1}return r},E=()=>{let i,t;return{promise:new Promise((r,a)=>{i=r,t=a}),resolve:i,reject:t}},Ut=(i,t)=>{let e=i.indexOf(t);e!==-1&&i.splice(e,1)},Bt=(i,t)=>{for(let e=i.length-1;e>=0;e--)if(t(i[e]))return e;return-1},Wt=async function*(i){Symbol.iterator in i?yield*i[Symbol.iterator]():yield*i[Symbol.asyncIterator]()};var le=/(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g,br=/^WEBVTT(.|\n)*?\n{2}/,ee=/<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g,Re=class{constructor(t){this.preambleText=null;this.preambleEmitted=!1;this.options=t}parse(t){t=t.replaceAll(`\r `,` `).replaceAll("\r",` -`),le.lastIndex=0;let t;if(!this.preambleText){if(!hr.test(e)){let s=new Error("WebVTT preamble incorrect.");throw this.options.error(s),s}t=le.exec(e);let r=e.slice(0,t?.index??e.length).trimEnd();if(!r){let s=new Error("No WebVTT preamble provided.");throw this.options.error(s),s}this.preambleText=r,t&&(e=e.slice(t.index),le.lastIndex=0)}for(;t=le.exec(e);){let r=e.slice(0,t.index),s=t[1],a=t.index+t[0].length,n=e.indexOf(` -`,a)+1,c=e.slice(a,n).trim(),o=e.indexOf(` +`),le.lastIndex=0;let e;if(!this.preambleText){if(!br.test(t)){let a=new Error("WebVTT preamble incorrect.");throw this.options.error(a),a}e=le.exec(t);let r=t.slice(0,e?.index??t.length).trimEnd();if(!r){let a=new Error("No WebVTT preamble provided.");throw this.options.error(a),a}this.preambleText=r,e&&(t=t.slice(e.index),le.lastIndex=0)}for(;e=le.exec(t);){let r=t.slice(0,e.index),a=e[1],s=e.index+e[0].length,n=t.indexOf(` +`,s)+1,o=t.slice(s,n).trim(),c=t.indexOf(` -`,a);o===-1&&(o=e.length);let u=Ie(t[2]),d=Ie(t[3])-u,h=e.slice(n,o).trim();e=e.slice(o).trimStart(),le.lastIndex=0;let g={timestamp:u/1e3,duration:d/1e3,text:h,identifier:s,settings:c,notes:r},b={};this.preambleEmitted||(b.config={description:this.preambleText},this.preambleEmitted=!0),this.options.output(g,b)}}},br=/(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/,Ie=i=>{let e=br.exec(i);if(!e)throw new Error("Expected match.");return 60*60*1e3*Number(e[1]||"0")+60*1e3*Number(e[2])+1e3*Number(e[3])+Number(e[4])},Ae=i=>{let e=Math.floor(i/36e5),t=Math.floor(i%(60*60*1e3)/(60*1e3)),r=Math.floor(i%(60*1e3)/1e3),s=i%1e3;return e.toString().padStart(2,"0")+":"+t.toString().padStart(2,"0")+":"+r.toString().padStart(2,"0")+"."+s.toString().padStart(3,"0")};var de=class{constructor(e){this.writer=e}helper=new Uint8Array(8);helperView=new DataView(this.helper.buffer);offsets=new WeakMap;writeU32(e){this.helperView.setUint32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(e){this.helperView.setUint32(0,Math.floor(e/2**32),!1),this.helperView.setUint32(4,e,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(e){for(let t=0;t[(i%256+256)%256],x=i=>(U.setUint16(0,i,!1),[T[0],T[1]]),gr=i=>(U.setInt16(0,i,!1),[T[0],T[1]]),Nt=i=>(U.setUint32(0,i,!1),[T[1],T[2],T[3]]),p=i=>(U.setUint32(0,i,!1),[T[0],T[1],T[2],T[3]]),Ht=i=>(U.setInt32(0,i,!1),[T[0],T[1],T[2],T[3]]),X=i=>(U.setUint32(0,Math.floor(i/2**32),!1),U.setUint32(4,i,!1),[T[0],T[1],T[2],T[3],T[4],T[5],T[6],T[7]]),it=i=>(U.setInt16(0,2**8*i,!1),[T[0],T[1]]),z=i=>(U.setInt32(0,2**16*i,!1),[T[0],T[1],T[2],T[3]]),tt=i=>(U.setInt32(0,2**30*i,!1),[T[0],T[1],T[2],T[3]]),rt=(i,e)=>{let t=[],r=i;do{let s=r&127;r>>=7,t.length>0&&(s|=128),t.push(s),e!==void 0&&e--}while(r>0||e);return t.reverse()},M=(i,e=!1)=>{let t=Array(i.length).fill(null).map((r,s)=>i.charCodeAt(s));return e&&t.push(0),t},st=i=>{let e=null;for(let t of i)(!e||t.timestamp>e.timestamp)&&(e=t);return e},Lt=i=>[z(i[0]),z(i[1]),tt(i[2]),z(i[3]),z(i[4]),tt(i[5]),z(i[6]),z(i[7]),tt(i[8])],S=(i,e,t)=>({type:i,contents:e&&new Uint8Array(e.flat(10)),children:t}),y=(i,e,t,r,s)=>S(i,[I(e),Nt(t),r??[]],s),Qt=i=>i.fragmented?S("ftyp",[M("iso5"),p(512),M("iso5"),M("iso6"),M("mp41")]):S("ftyp",[M("isom"),p(512),M("isom"),i.holdsAvc?M("avc1"):[],M("mp41")]),Oe=i=>({type:"mdat",largeSize:i}),Kt=i=>({type:"free",size:i}),fe=(i,e,t=!1)=>S("moov",void 0,[kr(e,i),...i.map(r=>Tr(r,e)),t?Zr(i):null]),kr=(i,e)=>{let t=P(Math.max(0,...e.filter(n=>n.samples.length>0).map(n=>{let c=st(n.samples);return c.timestamp+c.duration})),Re),r=Math.max(0,...e.map(n=>n.track.id))+1,s=!Q(i)||!Q(t),a=s?X:p;return y("mvhd",+s,0,[a(i),a(i),p(Re),a(t),z(1),it(1),Array(10).fill(0),Lt(et),Array(24).fill(0),p(r)])},Tr=(i,e)=>S("trak",void 0,[xr(i,e),Cr(i,e)]),xr=(i,e)=>{let t=st(i.samples),r=P(t?t.timestamp+t.duration:0,Re),s=!Q(e)||!Q(r),a=s?X:p,n;if(i.type==="video"){let c=i.track.metadata.rotation;n=c===void 0||typeof c=="number"?L(c??0):c}else n=et;return y("tkhd",+s,3,[a(e),a(e),p(i.track.id),p(0),a(r),Array(8).fill(0),x(0),x(i.track.id),it(i.type==="audio"?1:0),x(0),Lt(n),z(i.type==="video"?i.info.width:0),z(i.type==="video"?i.info.height:0)])},Cr=(i,e)=>S("mdia",void 0,[Sr(i,e),vr(i),Ir(i)]),Sr=(i,e)=>{let t=st(i.samples),r=P(t?t.timestamp+t.duration:0,i.timescale),s=!Q(e)||!Q(r),a=s?X:p;return y("mdhd",+s,0,[a(e),a(e),p(i.timescale),a(r),x(21956),x(0)])},wr={video:"vide",audio:"soun",subtitle:"text"},yr={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},vr=i=>y("hdlr",0,0,[M("mhlr"),M(wr[i.type]),p(0),p(0),p(0),M(yr[i.type],!0)]),Ir=i=>S("minf",void 0,[_r[i.type](),Er(),Vr(i)]),Ar=()=>y("vmhd",0,1,[x(0),x(0),x(0),x(0)]),Rr=()=>y("smhd",0,0,[x(0),x(0)]),Or=()=>y("nmhd",0,0),_r={video:Ar,audio:Rr,subtitle:Or},Er=()=>S("dinf",void 0,[Fr()]),Fr=()=>y("dref",0,0,[p(1)],[Mr()]),Mr=()=>y("url ",0,1),Vr=i=>{let e=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(t=>t.sampleCompositionTimeOffset!==0);return S("stbl",void 0,[Dr(i),$r(i),jr(i),qr(i),Xr(i),Gr(i),e?Yr(i):null])},Dr=i=>{let e;return i.type==="video"?e=Pr(oi[i.track.source._codec],i):i.type==="audio"?e=Nr(ui[i.track.source._codec],i):i.type==="subtitle"&&(e=Qr(li[i.track.source._codec],i)),l(e),y("stsd",0,0,[p(1)],[e])},Pr=(i,e)=>S(i,[Array(6).fill(0),x(1),x(0),x(0),Array(12).fill(0),x(e.info.width),x(e.info.height),p(4718592),p(4718592),p(0),x(1),Array(32).fill(0),x(24),gr(65535)],[ci[e.track.source._codec](e),ye(e.info.decoderConfig.colorSpace)?zr(e):null]),zr=i=>S("colr",[M("nclx"),x($[i.info.decoderConfig.colorSpace.primaries]),x(j[i.info.decoderConfig.colorSpace.transfer]),x(q[i.info.decoderConfig.colorSpace.matrix]),I((i.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),Ur=i=>i.info.decoderConfig&&S("avcC",[...K(i.info.decoderConfig.description)]),Br=i=>i.info.decoderConfig&&S("hvcC",[...K(i.info.decoderConfig.description)]),Wt=i=>{if(!i.info.decoderConfig)return null;let e=i.info.decoderConfig;l(e.colorSpace);let t=e.codec.split("."),r=Number(t[1]),s=Number(t[2]),c=(Number(t[3])<<4)+(0<<1)+Number(e.colorSpace.fullRange);return y("vpcC",1,0,[I(r),I(s),I(c),I(2),I(2),I(2),x(0)])},Wr=()=>S("av1C",[129,0,0,0]),Nr=(i,e)=>S(i,[Array(6).fill(0),x(1),x(0),x(0),p(0),x(e.info.numberOfChannels),x(16),x(0),x(0),z(e.info.sampleRate)],[mi[e.track.source._codec](e)]),Hr=i=>{let t=[...K(i.info.decoderConfig.description??new ArrayBuffer(0))];return t=[...I(64),...I(21),...Nt(0),...p(0),...p(0),...I(5),...rt(t.length),...t],t=[...x(1),...I(0),...I(4),...rt(t.length),...t,...I(6),...I(1),...I(2)],t=[...I(3),...rt(t.length),...t],y("esds",0,0,t)},Lr=i=>{let e=3840,t=0,r=i.info.decoderConfig?.description;if(r){l(r.byteLength>=18);let s=ArrayBuffer.isView(r)?new DataView(r.buffer,r.byteOffset,r.byteLength):new DataView(r);e=s.getUint16(10,!0),t=s.getInt16(14,!0)}return S("dOps",[I(0),I(i.info.numberOfChannels),x(e),p(i.info.sampleRate),it(t),I(0)])},Qr=(i,e)=>S(i,[Array(6).fill(0),x(1)],[di[e.track.source._codec](e)]),Kr=i=>S("vttC",[...D.encode(i.info.config.description)]);var $r=i=>y("stts",0,0,[p(i.timeToSampleTable.length),i.timeToSampleTable.map(e=>[p(e.sampleCount),p(e.sampleDelta)])]),jr=i=>{if(i.samples.every(t=>t.type==="key"))return null;let e=[...i.samples.entries()].filter(([,t])=>t.type==="key");return y("stss",0,0,[p(e.length),e.map(([t])=>p(t+1))])},qr=i=>y("stsc",0,0,[p(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(e=>[p(e.firstChunk),p(e.samplesPerChunk),p(1)])]),Xr=i=>y("stsz",0,0,[p(0),p(i.samples.length),i.samples.map(e=>p(e.size))]),Gr=i=>i.finalizedChunks.length>0&&_(i.finalizedChunks).offset>=2**32?y("co64",0,0,[p(i.finalizedChunks.length),i.finalizedChunks.map(e=>X(e.offset))]):y("stco",0,0,[p(i.finalizedChunks.length),i.finalizedChunks.map(e=>p(e.offset))]),Yr=i=>y("ctts",0,0,[p(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(e=>[p(e.sampleCount),p(e.sampleCompositionTimeOffset)])]),Zr=i=>S("mvex",void 0,i.map(Jr)),Jr=i=>y("trex",0,0,[p(i.track.id),p(1),p(0),p(0),p(0)]),at=(i,e)=>S("moof",void 0,[ei(i),...e.map(ti)]),ei=i=>y("mfhd",0,0,[p(i)]),$t=i=>{let e=0,t=0,r=0,s=0,a=i.type==="delta";return t|=+a,a?e|=1:e|=2,e<<24|t<<16|r<<8|s},ti=i=>S("traf",void 0,[ri(i),ii(i),si(i)]),ri=i=>{l(i.currentChunk);let e=0;e|=8,e|=16,e|=32,e|=131072;let t=i.currentChunk.samples[1]??i.currentChunk.samples[0],r={duration:t.timescaleUnitsToNextSample,size:t.size,flags:$t(t)};return y("tfhd",0,e,[p(i.track.id),p(r.duration),p(r.size),p(r.flags)])},ii=i=>(l(i.currentChunk),y("tfdt",1,0,[X(P(i.currentChunk.startTimestamp,i.timescale))])),si=i=>{l(i.currentChunk);let e=i.currentChunk.samples.map(f=>f.timescaleUnitsToNextSample),t=i.currentChunk.samples.map(f=>f.size),r=i.currentChunk.samples.map($t),s=i.currentChunk.samples.map(f=>P(f.timestamp-f.decodeTimestamp,i.timescale)),a=new Set(e),n=new Set(t),c=new Set(r),o=new Set(s),u=c.size===2&&r[0]!==r[1],m=a.size>1,d=n.size>1,h=!u&&c.size>1,g=o.size>1||[...o].some(f=>f!==0),b=0;return b|=1,b|=4*+u,b|=256*+m,b|=512*+d,b|=1024*+h,b|=2048*+g,y("trun",1,b,[p(i.currentChunk.samples.length),p(i.currentChunk.offset-i.currentChunk.moofOffset||0),u?p(r[0]):[],i.currentChunk.samples.map((f,k)=>[m?p(e[k]):[],d?p(t[k]):[],h?p(r[k]):[],g?Ht(s[k]):[]])])},jt=i=>S("mfra",void 0,[...i.map(ai),ni()]),ai=(i,e)=>y("tfra",1,0,[p(i.track.id),p(63),p(i.finalizedChunks.length),i.finalizedChunks.map(r=>[X(P(r.samples[0].timestamp,i.timescale)),X(r.moofOffset),p(e+1),p(1),p(1)])]),ni=()=>y("mfro",0,0,[p(0)]),qt=()=>S("vtte"),Xt=(i,e,t,r,s)=>S("vttc",void 0,[s!==null?S("vsid",[Ht(s)]):null,t!==null?S("iden",[...D.encode(t)]):null,e!==null?S("ctim",[...D.encode(Ae(e))]):null,r!==null?S("sttg",[...D.encode(r)]):null,S("payl",[...D.encode(i)])]),Gt=i=>S("vtta",[...D.encode(i)]),oi={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},ci={avc:Ur,hevc:Br,vp8:Wt,vp9:Wt,av1:Wr},ui={aac:"mp4a",opus:"Opus"},mi={aac:Hr,opus:Lr},li={webvtt:"wvtt"},di={webvtt:Kr};var te=class{output;mutex=new H;constructor(e){this.output=e}beforeTrackAdd(e){}onTrackClose(e){}trackTimestampInfo=new WeakMap;validateAndNormalizeTimestamp(e,t,r){let s=t/1e6,a=this.trackTimestampInfo.get(e);if(!a){if(!r)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&s>0)throw new Error(`Timestamps must start at zero (got ${s}s).`);a={timestampOffset:s,maxTimestamp:e.source._offsetTimestamps?0:s,lastKeyFrameTimestamp:e.source._offsetTimestamps?0:s},this.trackTimestampInfo.set(e,a)}if(e.source._offsetTimestamps&&(s-=a.timestampOffset),s<0)throw new Error(`Timestamps must be non-negative (got ${s}s).`);if(sr.start-s.start);e.push({start:t[0].start,size:t[0].data.byteLength});for(let r=1;ro.start<=t&&tpi){for(let o=0;o=e.written[a+1].start;)e.written[a].end=Math.max(e.written[a].end,e.written[a+1].end),e.written.splice(a+1,1)}createChunk(e){let r={start:Math.floor(e/this.chunkSize)*this.chunkSize,data:new Uint8Array(this.chunkSize),written:[],shouldFlush:!1};return this.chunks.push(r),this.chunks.sort((s,a)=>s.start-a.start),this.chunks.indexOf(r)}queueChunksForFlush(e=!1){l(this.writer);for(let t=0;t{if(i==="avc"){let a=Math.ceil(e/16)*Math.ceil(t/16),n=Yt.find(d=>a<=d.maxMacroblocks&&r<=d.maxBitrate)??_(Yt),c=n?n.level:0,o="64".padStart(2,"0"),u="00",m=c.toString(16).padStart(2,"0");return`avc1.${o}${u}${m}`}else if(i==="hevc"){let s="",n="6",c=e*t,o=Zt.find(m=>c<=m.maxPictureSize&&r<=m.maxBitrate)??_(Zt);return`hev1.${s}1.${n}.${o.tier}${o.level}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let s="00",a=e*t,n=Jt.find(o=>a<=o.maxPictureSize&&r<=o.maxBitrate)??_(Jt);return`vp09.${s}.${n.level}.08`}else if(i==="av1"){let a=e*t,n=er.find(o=>a<=o.maxPictureSize&&r<=o.maxBitrate)??_(er);return`av01.0.${n.level.toString().padStart(2,"0")}${n.tier}.08`}}throw new TypeError(`Unhandled codec '${i}'.`)},rr=(i,e)=>{if(i==="avc"){if(!e||e.byteLength<4)throw new TypeError("AVC description must be at least 4 bytes long.");return`avc1.${Pt(e.subarray(1,4))}`}else if(i==="hevc"){if(!e)throw new TypeError("HEVC description must be provided.");let t=new DataView(e.buffer,e.byteOffset,e.byteLength),r="hev1.",s=e[1]>>6&3,a=e[1]&31;r+=["","A","B","C"][s]+a,r+=".";let n=zt(t.getUint32(2));r+=n.toString(16),r+=".";let c=e[1]>>5&1,o=e[12];r+=c===0?"L":"H",r+=o,r+=".";let u=[];for(let m=0;m<6;m++){let d=e[m+13];u.push(d)}for(;u[u.length-1]===0;)u.pop();return r+=u.map(m=>m.toString(16)).join("."),r}throw new TypeError(`Unhandled codec '${i}'.`)},ir=(i,e,t)=>{if(i==="aac")return e>=2&&t<=24e3?"mp4a.40.29":t<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},sr=(i,e)=>{if(i==="aac")return`mp4a.40.${ot(e).objectType}`;if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},ot=i=>{if(!i||i.byteLength<2)throw new TypeError("AAC description must be at least 2 bytes long.");let e=0,t=E(i,e,e+5);e+=5,t===31&&(t=32+E(i,e,e+6),e+=6);let r=E(i,e,e+4);e+=4;let s=null;if(r===15)s=E(i,e,e+24),e+=24;else{let c=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];r=1&&a<=7&&(n={1:1,2:2,3:3,4:4,5:5,6:6,7:8}[a]),{objectType:t,frequencyIndex:r,sampleRate:s,channelConfiguration:a,numberOfChannels:n}},ar=i=>i==="avc"?{avc:{format:"avc"}}:i==="hevc"?{hevc:{format:"hevc"}}:{},nr=i=>i==="aac"?{aac:{format:"aac"}}:i==="opus"?{opus:{format:"opus"}}:{},Me=i=>{if(!i)throw new TypeError("Video chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Video chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Video chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Video chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Video chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.codedWidth)||i.decoderConfig.codedWidth<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).");if(!Number.isInteger(i.decoderConfig.codedHeight)||i.decoderConfig.codedHeight<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).");if(i.decoderConfig.description!==void 0&&!Je(i.decoderConfig.description))throw new TypeError("Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.colorSpace!==void 0){let{colorSpace:e}=i.decoderConfig;if(typeof e!="object")throw new TypeError("Video chunk metadata decoder configuration colorSpace, when provided, must be an object.");let t=Object.keys($);if(e.primaries!=null&&!t.includes(e.primaries))throw new TypeError(`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of ${t.join(", ")}.`);let r=Object.keys(j);if(e.transfer!=null&&!r.includes(e.transfer))throw new TypeError(`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of ${r.join(", ")}.`);let s=Object.keys(q);if(e.matrix!=null&&!s.includes(e.matrix))throw new TypeError(`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of ${s.join(", ")}.`);if(e.fullRange!=null&&typeof e.fullRange!="boolean")throw new TypeError("Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.")}if((i.decoderConfig.codec.startsWith("avc1")||i.decoderConfig.codec.startsWith("avc3"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for AVC must include a description, which is expected to be an AVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec.startsWith("hev1")||i.decoderConfig.codec.startsWith("hvc1"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for HEVC must include a description, which is expected to be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec==="vp8"||i.decoderConfig.codec.startsWith("vp09"))&&i.decoderConfig.colorSpace===void 0)throw new TypeError("Video chunk metadata decoder configuration for VP8/VP9 must include a colorSpace.")},Ve=i=>{if(!i)throw new TypeError("Audio chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Audio chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Audio chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Audio chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Audio chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.sampleRate)||i.decoderConfig.sampleRate<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).");if(!Number.isInteger(i.decoderConfig.numberOfChannels)||i.decoderConfig.numberOfChannels<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).");if(i.decoderConfig.description!==void 0&&!Je(i.decoderConfig.description))throw new TypeError("Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.codec.startsWith("mp4a")&&!i.decoderConfig.description)throw new TypeError("Audio chunk metadata decoder configuration for AAC must include a description, which is expected to be an AudioSpecificConfig as specified in ISO 14496-3.");if(i.decoderConfig.codec==="opus"&&i.decoderConfig.description&&i.decoderConfig.description.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.")},De=i=>{if(!i)throw new TypeError("Subtitle metadata must be provided.");if(typeof i!="object")throw new TypeError("Subtitle metadata must be an object.");if(!i.config)throw new TypeError("Subtitle metadata must include a config object.");if(typeof i.config!="object")throw new TypeError("Subtitle metadata config must be an object.");if(typeof i.config.description!="string")throw new TypeError("Subtitle metadata config description must be a string.")};var Re=1e3,hi=2082844800,P=(i,e,t=!0)=>{let r=i*e;return t?Math.round(r):r},Pe=class extends te{timestampsMustStartAtZero=!0;writer;boxWriter;fastStart;auxTarget=new he;auxWriter=this.auxTarget._createWriter();auxBoxWriter=new de(this.auxWriter);ftypSize=null;mdat=null;trackDatas=[];creationTime=Math.floor(Date.now()/1e3)+hi;finalizedChunks=[];nextFragmentNumber=1;constructor(e,t){super(e),this.writer=e._writer,this.boxWriter=new de(this.writer);let r=this.writer instanceof re?"in-memory":!1;this.fastStart=t._options.fastStart??r,(this.fastStart==="in-memory"||this.fastStart==="fragmented")&&(this.writer.ensureMonotonicity=!0)}async start(){let e=await this.mutex.acquire(),t=this.output._tracks.some(r=>r.type==="video"&&r.source._codec==="avc");this.boxWriter.writeBox(Qt({holdsAvc:t,fragmented:this.fastStart==="fragmented"})),this.ftypSize=this.writer.getPos(),this.fastStart==="in-memory"?this.mdat=Oe(!1):this.fastStart==="fragmented"||(this.mdat=Oe(!0),this.boxWriter.writeBox(this.mdat)),await this.writer.flush(),e()}getVideoTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;Me(t),l(t),l(t.decoderConfig),l(t.decoderConfig.codedWidth!==void 0),l(t.decoderConfig.codedHeight!==void 0);let s={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getAudioTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;Ve(t),l(t),l(t.decoderConfig);let s={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},timescale:t.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getSubtitleTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;De(t),l(t),l(t.config);let s={track:e,type:"subtitle",info:{config:t.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),this.validateAndNormalizeTimestamp(e,0,!0),s}async addEncodedVideoChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getVideoTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=this.validateAndNormalizeTimestamp(a.track,t.timestamp,t.type==="key"),o=this.createSampleForTrack(a,n,c,(t.duration??0)/1e6,t.type);await this.registerSample(a,o)}finally{s()}}async addEncodedAudioChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getAudioTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=t.type,o=this.validateAndNormalizeTimestamp(a.track,t.timestamp,c==="key"),u=this.createSampleForTrack(a,n,o,(t.duration??0)/1e6,c);await this.registerSample(a,u)}finally{s()}}async addSubtitleCue(e,t,r){let s=await this.mutex.acquire();try{let a=this.getSubtitleTrackData(e,r);this.validateAndNormalizeTimestamp(a.track,1e6*t.timestamp,!0),e.source._codec==="webvtt"&&(a.cueQueue.push(t),await this.processWebVTTCues(a,t.timestamp))}finally{s()}}async processWebVTTCues(e,t){for(;e.cueQueue.length>0;){let r=new Set([]);for(let u of e.cueQueue)l(u.timestamp<=t),l(e.lastCueEndTimestamp<=u.timestamp+u.duration),r.add(Math.max(u.timestamp,e.lastCueEndTimestamp)),r.add(u.timestamp+u.duration);let s=[...r].sort((u,m)=>u-m),a=s[0],n=s[1]??a;if(t=n)break;ee.lastIndex=0;let d=ee.test(m.text),h=m.timestamp+m.duration,g=e.cueToSourceId.get(m);if(g===void 0&&nr.timestamp).sort((r,s)=>r-s);for(let r=0;r{if(e===n)return t.type==="key";let c=n.sampleQueue[0];return c&&c.type==="key"});s>=1&&a&&(r=!0,await this.finalizeFragment())}else r=s>=.5}r&&(e.currentChunk&&await this.finalizeCurrentChunk(e),e.currentChunk={startTimestamp:t.timestamp,samples:[],offset:null,moofOffset:null}),l(e.currentChunk),e.currentChunk.samples.push(t),e.timestampProcessingQueue.push(t)}async finalizeCurrentChunk(e){if(l(this.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||_(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.writer.getPos();for(let t of e.currentChunk.samples)l(t.data),this.writer.write(t.data),t.data=null;await this.writer.flush()}}async interleaveSamples(){l(this.fastStart==="fragmented");for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let s of this.trackDatas){if(s.sampleQueue.length===0&&!s.track.source._closed)break e;s.sampleQueue.length>0&&s.sampleQueue[0].timestampo.currentChunk),s=this.writer.getPos(),a=at(t,r);this.boxWriter.writeBox(a);{let o=Oe(!1),u=0;for(let d of r)for(let h of d.currentChunk.samples)u+=h.size;let m=this.boxWriter.measureBox(o)+u;m>=2**32&&(o.largeSize=!0,m=this.boxWriter.measureBox(o)+u),o.size=m,this.boxWriter.writeBox(o)}for(let o of r){o.currentChunk.offset=this.writer.getPos(),o.currentChunk.moofOffset=s;for(let u of o.currentChunk.samples)this.writer.write(u.data),u.data=null}let n=this.writer.getPos();this.writer.seek(this.boxWriter.offsets.get(a));let c=at(t,r);this.boxWriter.writeBox(c),this.writer.seek(n);for(let o of r)o.finalizedChunks.push(o.currentChunk),this.finalizedChunks.push(o.currentChunk),o.currentChunk=null;e&&await this.writer.flush()}async onTrackClose(e){let t=await this.mutex.acquire();if(e.type==="subtitle"&&e.source._codec==="webvtt"){let r=this.trackDatas.find(s=>s.track===e);r&&await this.processWebVTTCues(r,1/0)}this.fastStart==="fragmented"&&await this.interleaveSamples(),t()}async finalize(){let e=await this.mutex.acquire();for(let t of this.trackDatas)t.type==="subtitle"&&t.track.source._codec==="webvtt"&&await this.processWebVTTCues(t,1/0);if(this.fastStart==="fragmented"){for(let t of this.trackDatas){for(let r of t.sampleQueue)await this.addSampleToTrack(t,r);this.processTimestamps(t)}await this.finalizeFragment(!1)}else for(let t of this.trackDatas)this.processTimestamps(t),await this.finalizeCurrentChunk(t);if(this.fastStart==="in-memory"){l(this.mdat);let t;for(let s=0;s<2;s++){let a=fe(this.trackDatas,this.creationTime),n=this.boxWriter.measureBox(a);t=this.boxWriter.measureBox(this.mdat);let c=this.writer.getPos()+n+t;for(let o of this.finalizedChunks){o.offset=c;for(let{data:u}of o.samples)l(u),c+=u.byteLength,t+=u.byteLength}if(c<2**32)break;t>=2**32&&(this.mdat.largeSize=!0)}let r=fe(this.trackDatas,this.creationTime);this.boxWriter.writeBox(r),this.mdat.size=t,this.boxWriter.writeBox(this.mdat);for(let s of this.finalizedChunks)for(let a of s.samples)l(a.data),this.writer.write(a.data),a.data=null}else if(this.fastStart==="fragmented"){let t=this.writer.getPos(),r=jt(this.trackDatas);this.boxWriter.writeBox(r);let s=this.writer.getPos()-t;this.writer.seek(this.writer.getPos()-4),this.boxWriter.writeU32(s)}else{l(this.mdat),l(this.ftypSize!==null);let t=this.boxWriter.offsets.get(this.mdat);l(t!==void 0);let r=this.writer.getPos()-t;this.mdat.size=r,this.mdat.largeSize=r>=2**32,this.boxWriter.patchBox(this.mdat);let s=fe(this.trackDatas,this.creationTime);if(typeof this.fastStart=="object"){this.writer.seek(this.ftypSize),this.boxWriter.writeBox(s);let a=t-this.writer.getPos();this.boxWriter.writeBox(Kt(a))}else this.boxWriter.writeBox(s)}e()}};var be=class{value;constructor(e){this.value=e}},ae=class{value;constructor(e){this.value=e}},ge=class{value;constructor(e){this.value=e}};var ct=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,ut=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,or=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var mt=2**15,cr="https://github.com/Vanilagy/webm-muxer",ur=6,mr=5,bi={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},gi={video:1,audio:2,subtitle:17},ze=class extends te{timestampsMustStartAtZero=!1;writer;format;helper=new Uint8Array(8);helperView=new DataView(this.helper.buffer);offsets=new WeakMap;dataOffsets=new WeakMap;trackDatas=[];segment=null;segmentInfo=null;seekHead=null;tracksElement=null;segmentDuration=null;cues=null;currentCluster=null;currentClusterMsTimestamp=null;trackDatasInCurrentCluster=new Set;duration=0;constructor(e,t){super(e),this.writer=e._writer,this.format=t,this.format._options.streamable&&(this.writer.ensureMonotonicity=!0)}writeByte(e){this.helperView.setUint8(0,e),this.writer.write(this.helper.subarray(0,1))}writeFloat32(e){this.helperView.setFloat32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeFloat64(e){this.helperView.setFloat64(0,e,!1),this.writer.write(this.helper)}writeUnsignedInt(e,t=ct(e)){let r=0;switch(t){case 6:this.helperView.setUint8(r++,e/2**40|0);case 5:this.helperView.setUint8(r++,e/2**32|0);case 4:this.helperView.setUint8(r++,e>>24);case 3:this.helperView.setUint8(r++,e>>16);case 2:this.helperView.setUint8(r++,e>>8);case 1:this.helperView.setUint8(r++,e);break;default:throw new Error("Bad UINT size "+t)}this.writer.write(this.helper.subarray(0,r))}writeSignedInt(e,t=ut(e)){e<0&&(e+=2**(t*8)),this.writeUnsignedInt(e,t)}writeEBMLVarInt(e,t=or(e)){let r=0;switch(t){case 1:this.helperView.setUint8(r++,128|e);break;case 2:this.helperView.setUint8(r++,64|e>>8),this.helperView.setUint8(r++,e);break;case 3:this.helperView.setUint8(r++,32|e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;case 4:this.helperView.setUint8(r++,16|e>>24),this.helperView.setUint8(r++,e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;case 5:this.helperView.setUint8(r++,8|e/2**32&7),this.helperView.setUint8(r++,e>>24),this.helperView.setUint8(r++,e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;case 6:this.helperView.setUint8(r++,4|e/2**40&3),this.helperView.setUint8(r++,e/2**32|0),this.helperView.setUint8(r++,e>>24),this.helperView.setUint8(r++,e>>16),this.helperView.setUint8(r++,e>>8),this.helperView.setUint8(r++,e);break;default:throw new Error("Bad EBML VINT size "+t)}this.writer.write(this.helper.subarray(0,r))}writeString(e){this.writer.write(new Uint8Array(e.split("").map(t=>t.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.writer.write(e);else if(Array.isArray(e))for(let t of e)this.writeEBML(t);else if(this.offsets.set(e,this.writer.getPos()),this.writeUnsignedInt(e.id),Array.isArray(e.data)){let t=this.writer.getPos(),r=e.size===-1?1:e.size??4;e.size===-1?this.writeByte(255):this.writer.seek(this.writer.getPos()+r);let s=this.writer.getPos();if(this.dataOffsets.set(e,s),this.writeEBML(e.data),e.size!==-1){let a=this.writer.getPos()-s,n=this.writer.getPos();this.writer.seek(t),this.writeEBMLVarInt(a,r),this.writer.seek(n)}}else if(typeof e.data=="number"){let t=e.size??ct(e.data);this.writeEBMLVarInt(t),this.writeUnsignedInt(e.data,t)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.writeString(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.writer.write(e.data);else if(e.data instanceof be)this.writeEBMLVarInt(4),this.writeFloat32(e.data.value);else if(e.data instanceof ae)this.writeEBMLVarInt(8),this.writeFloat64(e.data.value);else if(e.data instanceof ge){let t=e.size??ut(e.data.value);this.writeEBMLVarInt(t),this.writeSignedInt(e.data.value,t)}}}beforeTrackAdd(e){if(this.format instanceof ne)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source._codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source._codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source._codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}async start(){let e=await this.mutex.acquire();this.writeEBMLHeader(),this.format._options.streamable||this.createSeekHead(),this.createSegmentInfo(),this.createCues(),await this.writer.flush(),e()}writeEBMLHeader(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.format instanceof ne?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}createSeekHead(){let e=new Uint8Array([28,83,187,107]),t=new Uint8Array([21,73,169,102]),r=new Uint8Array([22,84,174,107]),s={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:t},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:r},{id:21420,size:5,data:0}]}]};this.seekHead=s}createSegmentInfo(){let e={id:17545,data:new ae(0)};this.segmentDuration=e;let t={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:cr},{id:22337,data:cr},this.format._options.streamable?null:e]};this.segmentInfo=t}createTracks(){let e={id:374648427,data:[]};this.tracksElement=e;for(let t of this.trackDatas)e.data.push({id:174,data:[{id:215,data:t.track.id},{id:29637,data:t.track.id},{id:131,data:gi[t.type]},{id:134,data:bi[t.track.source._codec]},t.type==="video"?this.videoSpecificTrackInfo(t):null,t.type==="audio"?this.audioSpecificTrackInfo(t):null,t.type==="subtitle"?this.subtitleSpecificTrackInfo(t):null]})}videoSpecificTrackInfo(e){let t=[e.info.decoderConfig.description?{id:25506,data:K(e.info.decoderConfig.description)}:null,e.track.metadata.frameRate?{id:2352003,data:1e9/e.track.metadata.frameRate}:null],r=e.info.decoderConfig.colorSpace,s={id:224,data:[{id:176,data:e.info.width},{id:186,data:e.info.height},ye(r)?{id:21936,data:[{id:21937,data:q[r.matrix]},{id:21946,data:j[r.transfer]},{id:21947,data:$[r.primaries]},{id:21945,data:r.fullRange?2:1}]}:null]};return t.push(s),t}audioSpecificTrackInfo(e){return[e.info.decoderConfig.description?{id:25506,data:K(e.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new be(e.info.sampleRate)},{id:159,data:e.info.numberOfChannels}]}]}subtitleSpecificTrackInfo(e){return[{id:25506,data:D.encode(e.info.config.description)}]}createSegment(){let e={id:408125543,size:this.format._options.streamable?-1:ur,data:[this.format._options.streamable?null:this.seekHead,this.segmentInfo,this.tracksElement]};this.segment=e,this.writeEBML(e)}createCues(){this.cues={id:475249515,data:[]}}get segmentDataOffset(){return l(this.segment),this.dataOffsets.get(this.segment)}getVideoTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;Me(t),l(t),l(t.decoderConfig),l(t.decoderConfig.codedWidth!==void 0),l(t.decoderConfig.codedHeight!==void 0);let s={track:e,type:"video",info:{width:t.decoderConfig.codedWidth,height:t.decoderConfig.codedHeight,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getAudioTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;Ve(t),l(t),l(t.decoderConfig);let s={track:e,type:"audio",info:{numberOfChannels:t.decoderConfig.numberOfChannels,sampleRate:t.decoderConfig.sampleRate,decoderConfig:t.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}getSubtitleTrackData(e,t){let r=this.trackDatas.find(a=>a.track===e);if(r)return r;De(t),l(t),l(t.config);let s={track:e,type:"subtitle",info:{config:t.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((a,n)=>a.track.id-n.track.id),s}async addEncodedVideoChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getVideoTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=t.type==="key",o=this.validateAndNormalizeTimestamp(a.track,t.timestamp,c),u=this.createInternalChunk(n,o,(t.duration??0)/1e6,t.type);e.source._codec==="vp9"&&this.fixVP9ColorSpace(a,u),a.chunkQueue.push(u),await this.interleaveChunks()}finally{s()}}async addEncodedAudioChunk(e,t,r){let s=await this.mutex.acquire();try{let a=this.getAudioTrackData(e,r),n=new Uint8Array(t.byteLength);t.copyTo(n);let c=t.type,o=c==="key",u=this.validateAndNormalizeTimestamp(a.track,t.timestamp,o),m=this.createInternalChunk(n,u,(t.duration??0)/1e6,c);a.chunkQueue.push(m),await this.interleaveChunks()}finally{s()}}async addSubtitleCue(e,t,r){let s=await this.mutex.acquire();try{let a=this.getSubtitleTrackData(e,r),n=this.validateAndNormalizeTimestamp(a.track,1e6*t.timestamp,!0),c=t.text,o=Math.floor(n*1e3);ee.lastIndex=0,c=c.replace(ee,h=>{let b=Ie(h.slice(1,-1))-o;return`<${Ae(b)}>`});let u=D.encode(c),m=`${t.settings??""} -${t.identifier??""} -${t.notes??""}`,d=this.createInternalChunk(u,n,t.duration,"key",m.trim()?D.encode(m):null);a.chunkQueue.push(d),await this.interleaveChunks()}finally{s()}}async interleaveChunks(){for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(t=>t.track===e))return;e:for(;;){let e=null,t=1/0;for(let s of this.trackDatas){if(s.chunkQueue.length===0&&!s.track.source._closed)break e;s.chunkQueue.length>0&&s.chunkQueue[0].timestamp=2&&r++;let o={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];Ft(t.data,r+0,r+3,o)}createInternalChunk(e,t,r,s,a=null){return{data:e,type:s,timestamp:t,duration:r,additions:a}}writeBlock(e,t){this.segment||(this.createTracks(),this.createSegment());let r=Math.floor(1e3*t.timestamp),s=this.trackDatas.every(m=>{if(m.track.source._closed)return!0;if(e===m)return t.type==="key";let d=m.chunkQueue[0];return d&&d.type==="key"});(!this.currentCluster||s&&r-this.currentClusterMsTimestamp>=1e3)&&this.createNewCluster(r);let a=r-this.currentClusterMsTimestamp;if(a<0)return;if(a>=mt)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${mt} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${mt} milliseconds.`);let c=new Uint8Array(4),o=new DataView(c.buffer);o.setUint8(0,128|e.track.id),o.setInt16(1,a,!1);let u=Math.floor(1e3*t.duration);if(u===0&&!t.additions){o.setUint8(3,+(t.type==="key")<<7);let m={id:163,data:[c,t.data]};this.writeEBML(m)}else{let m={id:160,data:[{id:161,data:[c,t.data]},t.type==="delta"?{id:251,data:new ge(e.lastWrittenMsTimestamp-r)}:null,t.additions?{id:30113,data:[{id:166,data:[{id:165,data:t.additions},{id:238,data:1}]}]}:null,u>0?{id:155,data:u}:null]};this.writeEBML(m)}this.duration=Math.max(this.duration,r+u),e.lastWrittenMsTimestamp=r,this.trackDatasInCurrentCluster.add(e)}createNewCluster(e){this.currentCluster&&!this.format._options.streamable&&this.finalizeCurrentCluster(),this.currentCluster={id:524531317,size:this.format._options.streamable?-1:mr,data:[{id:231,data:e}]},this.writeEBML(this.currentCluster),this.currentClusterMsTimestamp=e,this.trackDatasInCurrentCluster.clear()}finalizeCurrentCluster(){l(this.currentCluster);let e=this.writer.getPos()-this.dataOffsets.get(this.currentCluster),t=this.writer.getPos();this.writer.seek(this.offsets.get(this.currentCluster)+4),this.writeEBMLVarInt(e,mr),this.writer.seek(t);let r=this.offsets.get(this.currentCluster)-this.segmentDataOffset;l(this.cues),this.cues.data.push({id:187,data:[{id:179,data:this.currentClusterMsTimestamp},...[...this.trackDatasInCurrentCluster].map(s=>({id:183,data:[{id:247,data:s.track.id},{id:241,data:r}]}))]})}async onTrackClose(){let e=await this.mutex.acquire();await this.interleaveChunks(),e()}async finalize(){let e=await this.mutex.acquire();this.segment||(this.createTracks(),this.createSegment());for(let t of this.trackDatas)for(;t.chunkQueue.length>0;)this.writeBlock(t,t.chunkQueue.shift());if(!this.format._options.streamable&&this.currentCluster&&this.finalizeCurrentCluster(),l(this.cues),this.writeEBML(this.cues),!this.format._options.streamable){let t=this.writer.getPos(),r=this.writer.getPos()-this.segmentDataOffset;this.writer.seek(this.offsets.get(this.segment)+4),this.writeEBMLVarInt(r,ur),this.segmentDuration.data=new ae(this.duration),this.writer.seek(this.offsets.get(this.segmentDuration)),this.writeEBML(this.segmentDuration),this.seekHead.data[0].data[1].data=this.offsets.get(this.cues)-this.segmentDataOffset,this.seekHead.data[1].data[1].data=this.offsets.get(this.segmentInfo)-this.segmentDataOffset,this.seekHead.data[2].data[1].data=this.offsets.get(this.tracksElement)-this.segmentDataOffset,this.writer.seek(this.offsets.get(this.seekHead)),this.writeEBML(this.seekHead),this.writer.seek(t)}e()}};var Y=class{},lt=class extends Y{_options;constructor(e={}){if(!e||typeof e!="object")throw new TypeError("options must be an object.");if(e.fastStart!==void 0&&![!1,"in-memory","fragmented"].includes(e.fastStart))throw new TypeError('options.fastStart, when provided, must be false, "in-memory", or "fragmented".');super(),this._options=e}_createMuxer(e){return new Pe(e,this)}},Ue=class extends Y{_options;constructor(e={}){if(!e||typeof e!="object")throw new TypeError("options must be an object.");if(e.streamable!==void 0&&typeof e.streamable!="boolean")throw new TypeError("options.streamable, when provided, must be a boolean.");super(),this._options=e}_createMuxer(e){return new ze(e,this)}},ne=class extends Ue{};var oe=class{_connectedTrack=null;_closed=!1;_offsetTimestamps=!1;_ensureValidDigest(){if(!this._connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call digest before output has been started.");if(this._connectedTrack.output._finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this._closed)throw new Error("Cannot call digest after source has been closed.")}_start(){}async _flush(){}close(){if(this._closed)throw new Error("Source already closed.");if(!this._connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call close before output has been started.");this._closed=!0,!this._connectedTrack.output._finalizing&&this._connectedTrack.output._muxer.onTrackClose(this._connectedTrack)}},W=class extends oe{_connectedTrack=null;_codec;constructor(e){if(super(),!ie.includes(e))throw new TypeError(`Invalid video codec '${e}'. Must be one of: ${ie.join(", ")}.`);this._codec=e}},dt=class extends W{constructor(e){super(e)}digest(e,t){if(!(e instanceof EncodedVideoChunk))throw new TypeError("chunk must be an EncodedVideoChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedVideoChunk(this._connectedTrack,e,t)}},ki=5,Ti=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!ie.includes(i.codec))throw new TypeError(`Invalid video codec '${i.codec}'. Must be one of: ${ie.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.");if(i.latencyMode!==void 0&&!["quality","realtime"].includes(i.latencyMode))throw new TypeError("config.latencyMode, when provided, must be 'quality' or 'realtime'.")},ke=class{constructor(e,t){this.source=e;this.codecConfig=t;Ti(t)}encoder=null;muxer=null;lastMultipleOfKeyFrameInterval=-1;lastWidth=null;lastHeight=null;async digest(e){if(this.source._ensureValidDigest(),this.lastWidth!==null&&this.lastHeight!==null){if(e.codedWidth!==this.lastWidth||e.codedHeight!==this.lastHeight)throw new Error(`Video frame size must remain constant. Expected ${this.lastWidth}x${this.lastHeight}, got ${e.codedWidth}x${e.codedHeight}.`)}else this.lastWidth=e.codedWidth,this.lastHeight=e.codedHeight;this.ensureEncoder(e),l(this.encoder);let t=Math.floor(e.timestamp/1e6/ki);this.encoder.encode(e,{keyFrame:t!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=t,this.encoder.encodeQueueSize>=4&&await new Promise(r=>this.encoder.addEventListener("dequeue",r,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(e){this.encoder||(this.encoder=new VideoEncoder({output:(t,r)=>void this.muxer.addEncodedVideoChunk(this.source._connectedTrack,t,r),error:t=>console.error("Video encode error:",t)}),this.encoder.configure({codec:tr(this.codecConfig.codec,e.codedWidth,e.codedHeight,this.codecConfig.bitrate),width:e.codedWidth,height:e.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source._connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode,...ar(this.codecConfig.codec)}),l(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},ft=class extends W{_encoder;constructor(e){super(e.codec),this._encoder=new ke(this,e)}digest(e){if(!(e instanceof VideoFrame))throw new TypeError("videoFrame must be a VideoFrame.");return this._encoder.digest(e)}_flush(){return this._encoder.flush()}},pt=class extends W{_encoder;_canvas;constructor(e,t){if(!(e instanceof HTMLCanvasElement))throw new TypeError("canvas must be an HTMLCanvasElement.");super(t.codec),this._encoder=new ke(this,t),this._canvas=e}digest(e,t=0){if(!Number.isFinite(e)||e<0)throw new TypeError("timestamp must be a non-negative number.");if(!Number.isFinite(t)||t<0)throw new TypeError("duration must be a non-negative number.");let r=new VideoFrame(this._canvas,{timestamp:Math.round(1e6*e),duration:Math.round(1e6*t),alpha:"discard"}),s=this._encoder.digest(r);return r.close(),s}_flush(){return this._encoder.flush()}},ht=class extends W{_encoder;_abortController=null;_track;_offsetTimestamps=!0;constructor(e,t){if(!(e instanceof MediaStreamTrack)||e.kind!=="video")throw new TypeError("track must be a video MediaStreamTrack.");t={...t,latencyMode:"realtime"},super(t.codec),this._encoder=new ke(this,t),this._track=e}_start(){this._abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this._track}),t=new WritableStream({write:r=>{this._encoder.digest(r),r.close()}});e.readable.pipeTo(t,{signal:this._abortController.signal}).catch(r=>{r instanceof DOMException&&r.name==="AbortError"||console.error("Pipe error:",r)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},N=class extends oe{_connectedTrack=null;_codec;constructor(e){if(super(),!se.includes(e))throw new TypeError(`Invalid audio codec '${e}'. Must be one of: ${se.join(", ")}.`);this._codec=e}},bt=class extends N{constructor(e){super(e)}digest(e,t){if(!(e instanceof EncodedAudioChunk))throw new TypeError("chunk must be an EncodedAudioChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedAudioChunk(this._connectedTrack,e,t)}},xi=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!se.includes(i.codec))throw new TypeError(`Invalid audio codec '${i.codec}'. Must be one of: ${se.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.")},Te=class{constructor(e,t){this.source=e;this.codecConfig=t;xi(t)}encoder=null;muxer=null;lastNumberOfChannels=null;lastSampleRate=null;async digest(e){if(this.source._ensureValidDigest(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(e.numberOfChannels!==this.lastNumberOfChannels||e.sampleRate!==this.lastSampleRate)throw new Error(`Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${e.numberOfChannels} channels at ${e.sampleRate} Hz.`)}else this.lastNumberOfChannels=e.numberOfChannels,this.lastSampleRate=e.sampleRate;this.ensureEncoder(e),l(this.encoder),this.encoder.encode(e),this.encoder.encodeQueueSize>=4&&await new Promise(t=>this.encoder.addEventListener("dequeue",t,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(e){this.encoder||(this.encoder=new AudioEncoder({output:(t,r)=>void this.muxer.addEncodedAudioChunk(this.source._connectedTrack,t,r),error:t=>console.error("Audio encode error:",t)}),this.encoder.configure({codec:ir(this.codecConfig.codec,e.numberOfChannels,e.sampleRate),numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,bitrate:this.codecConfig.bitrate,...nr(this.codecConfig.codec)}),l(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},gt=class extends N{_encoder;constructor(e){super(e.codec),this._encoder=new Te(this,e)}digest(e){if(!(e instanceof AudioData))throw new TypeError("audioData must be an AudioData.");return this._encoder.digest(e)}_flush(){return this._encoder.flush()}},kt=class extends N{_encoder;_accumulatedFrameCount=0;constructor(e){super(e.codec),this._encoder=new Te(this,e)}digest(e){if(!(e instanceof AudioBuffer))throw new TypeError("audioBuffer must be an AudioBuffer.");let t=e.numberOfChannels,r=e.sampleRate,s=e.length,a=new Float32Array(t*s);for(let o=0;o{this._encoder.digest(r),r.close()}});e.readable.pipeTo(t,{signal:this._abortController.signal}).catch(r=>{r instanceof DOMException&&r.name==="AbortError"||console.error("Pipe error:",r)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},ce=class extends oe{_connectedTrack=null;_codec;constructor(e){if(super(),!Fe.includes(e))throw new TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${Fe.join(", ")}.`);this._codec=e}},xt=class extends ce{_parser;constructor(e){super(e),this._parser=new ve({codec:e,output:(t,r)=>this._connectedTrack?.output._muxer.addSubtitleCue(this._connectedTrack,t,r),error:t=>console.error("Subtitle parse error:",t)})}digest(e){if(typeof e!="string")throw new TypeError("text must be a string.");return this._ensureValidDigest(),this._parser.parse(e),this._connectedTrack.output._muxer.mutex.currentPromise}};var Ct=class{_muxer;_writer;_tracks=[];_started=!1;_finalizing=!1;_mutex=new H;constructor(e){if(!e||typeof e!="object")throw new TypeError("options must be an object.");if(!(e.format instanceof Y))throw new TypeError("options.format must be an OutputFormat.");if(!(e.target instanceof G))throw new TypeError("options.target must be a Target.");if(e.target._output)throw new Error("Target is already used for another output.");e.target._output=this,this._writer=e.target._createWriter(),this._muxer=e.format._createMuxer(this)}addVideoTrack(e,t={}){if(!(e instanceof W))throw new TypeError("source must be a VideoSource.");if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");if(typeof t.rotation=="number"&&![0,90,180,270].includes(t.rotation))throw new TypeError(`Invalid video rotation: ${t.rotation}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(t.rotation)&&(t.rotation.length!==9||t.rotation.some(r=>!Number.isFinite(r))))throw new TypeError(`Invalid video transformation matrix: ${t.rotation.join()}`);if(t.frameRate!==void 0&&(!Number.isInteger(t.frameRate)||t.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${t.frameRate}. Must be a positive integer.`);this._addTrack("video",e,t)}addAudioTrack(e,t={}){if(!(e instanceof N))throw new TypeError("source must be an AudioSource.");if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");this._addTrack("audio",e,t)}addSubtitleTrack(e,t={}){if(!(e instanceof ce))throw new TypeError("source must be a SubtitleSource.");if(!t||typeof t!="object")throw new TypeError("metadata must be an object.");this._addTrack("subtitle",e,t)}_addTrack(e,t,r){if(this._started)throw new Error("Cannot add track after output has started.");if(t._connectedTrack)throw new Error("Source is already used for a track.");let s={id:this._tracks.length+1,output:this,type:e,source:t,metadata:r};this._muxer.beforeTrackAdd(s),this._tracks.push(s),t._connectedTrack=s}async start(){if(this._started)throw new Error("Output already started.");this._started=!0,this._writer.start();let e=await this._mutex.acquire();await this._muxer.start();for(let t of this._tracks)t.source._start();e()}async finalize(){if(!this._started)throw new Error("Cannot finalize before starting.");if(this._finalizing)throw new Error("Cannot call finalize twice.");this._finalizing=!0;let e=await this._mutex.acquire(),t=this._tracks.map(r=>r.source._flush());await Promise.all(t),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),e()}};var xe=class{_sizePromise=null;_getSize(){return this._sizePromise??=this._retrieveSize()}},St=class extends xe{constructor(t){super();this.buffer=t}async _read(t,r){return new Uint8Array(this.buffer,t,r-t)}async _retrieveSize(){return this.buffer.byteLength}},wt=class extends xe{constructor(t){super();this.blob=t}async _read(t,r){let a=await this.blob.slice(t,r).arrayBuffer();return new Uint8Array(a)}async _retrieveSize(){return this.blob.size}};var ue=class{input;constructor(e){this.input=e}};var Be=class{_backing;constructor(e){this._backing=e}isVideoTrack(){return this instanceof Ce}isAudioTrack(){return this instanceof Se}computeDuration(){return this._backing.computeDuration()}},Ce=class extends Be{_backing;constructor(e){super(e),this._backing=e}getCodec(){return this._backing.getCodec()}getWidth(){return this._backing.getWidth()}getHeight(){return this._backing.getHeight()}getRotation(){return this._backing.getRotation()}async getRotatedWidth(){return await this._backing.getRotation()%180===0?this._backing.getWidth():this._backing.getHeight()}async getRotatedHeight(){return await this._backing.getRotation()%180===0?this._backing.getHeight():this._backing.getWidth()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}},Se=class extends Be{_backing;constructor(e){super(e),this._backing=e}getCodec(){return this._backing.getCodec()}getNumberOfChannels(){return this._backing.getNumberOfChannels()}getSampleRate(){return this._backing.getSampleRate()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}};var me=class{constructor(e,t=1/0){this.source=e;this.maxStorableBytes=t}loadedSegments=[];loadingSegments=[];sourceSizePromise=null;nextAge=0;totalStoredBytes=0;async loadRange(e,t){t=Math.min(t,await this.source._getSize());let r=this.loadingSegments.find(o=>o.start<=e&&o.end>=t);if(r){await r.promise;return}if(this.loadedSegments.some(o=>o.start<=e&&o.end>=t))return;let a=this.source._read(e,t),n={start:e,end:t,promise:a};this.loadingSegments.push(n);let c=await a;Ut(this.loadingSegments,n),this.insertIntoLoadedSegments(e,c)}insertIntoLoadedSegments(e,t){let r={start:e,end:e+t.byteLength,bytes:t,view:new DataView(t.buffer),age:this.nextAge++},s=A(this.loadedSegments,e,a=>a.start);(s===-1||this.loadedSegments[s].start=r.end)break;r.start<=n.start&&n.end<=r.end&&(this.loadedSegments.splice(a,1),a--)}for(;this.totalStoredBytes>this.maxStorableBytes&&this.loadedSegments.length>1;){let a=null,n=-1;for(let c=0;ca.start),s=null;if(r!==-1)for(let a=r;ae)break;if(t<=n.end){s=n;break}}if(!s)throw new Error(`No segment loaded for range [${e}, ${t}).`);return s.age=this.nextAge++,{view:s.view,offset:s.bytes.byteOffset+e-s.start}}forgetRange(e,t){if(t<=e)return;let r=A(this.loadedSegments,e,a=>a.start);if(r===-1)return;let s=this.loadedSegments[r];s.start!==e||s.end!==t||(this.loadedSegments.splice(r,1),this.totalStoredBytes-=s.bytes.byteLength)}};var Z=class{constructor(e){this.reader=e}pos=0;readRange(e,t){let{view:r,offset:s}=this.reader.getViewAndOffset(e,t);return new Uint8Array(r.buffer,s,t-e)}readU8(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+1);return this.pos++,e.getUint8(t)}readU16(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+2);return this.pos+=2,e.getUint16(t,!1)}readU24(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+3);this.pos+=3;let r=e.getUint16(t,!1),s=e.getUint8(t+2);return r*256+s}readS32(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,e.getInt32(t,!1)}readU32(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,e.getUint32(t,!1)}readI32(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,e.getInt32(t,!1)}readU64(){let e=this.readU32(),t=this.readU32();return e*4294967296+t}readF64(){let{view:e,offset:t}=this.reader.getViewAndOffset(this.pos,this.pos+8);return this.pos+=8,e.getFloat64(t,!1)}readFixed_16_16(){return this.readS32()/65536}readFixed_2_30(){return this.readS32()/1073741824}readAscii(e){let{view:t,offset:r}=this.reader.getViewAndOffset(this.pos,this.pos+e);this.pos+=e;let s="";for(let a=0;ar.computeDuration()));return Math.max(0,...t)}async getTracks(){return await this.readMetadata(),this.tracks.map(e=>e.inputTrack)}async getMimeType(){await this.readMetadata();let e="video/mp4";if(this.tracks.length>0){let t=await Promise.all(this.tracks.map(s=>s.inputTrack.getCodecMimeType())),r=[...new Set(t)];e+=`; codecs="${r.join(", ")}"`}return e}readMetadata(){return this.metadataPromise??=(async()=>{let e=await this.isobmffReader.reader.source._getSize();for(;this.isobmffReader.pos=0&&rr.presentationTimestamp-s.presentationTimestamp),e.sampleTable}async readFragment(){let e=this.isobmffReader.pos;await this.isobmffReader.reader.loadRange(this.isobmffReader.pos,this.isobmffReader.pos+16);let t=this.isobmffReader.readBoxHeader();l(t.name==="moof"),await this.isobmffReader.reader.loadRange(e,e+t.totalSize),this.isobmffReader.pos=e,this.traverseBox();let r=B(this.fragments,e,a=>a.moofOffset);l(r!==-1);let s=this.fragments[r];l(s.moofOffset===e),this.isobmffReader.reader.forgetRange(e,e+t.totalSize);for(let[a,n]of s.trackData){if(n.startTimestampIsFinal)continue;let c=this.tracks.find(d=>d.id===a);this.isobmffReader.pos=0;let o=null,u=null,m=A(c.fragments,e-1,d=>d.moofOffset);for(m!==-1&&(o=c.fragments[m],u=o,this.isobmffReader.pos=o.moofOffset+o.moofSize);this.isobmffReader.posb.moofOffset);if(g===-1){this.isobmffReader.pos=d;let b=await this.readFragment();o&&(o.nextFragment=b),o=b}else{let b=this.fragments[g];o&&(o.nextFragment=b),o=b}}this.isobmffReader.pos=d+h.totalSize}o&&o.trackData.has(a)&&(u=o)}if(u){let d=u.trackData.get(a);l(d.startTimestampIsFinal),dr(n,d.endTimestamp)}n.startTimestampIsFinal=!0}return s}readContiguousBoxes(e){let t=this.isobmffReader.pos;for(;this.isobmffReader.pos-tm.every((d,h)=>d===o[h]));u===-1?s.rotation=0:s.rotation=90*u}break;case"mdhd":{let s=this.currentTrack;l(s);let a=this.isobmffReader.readU8();this.isobmffReader.pos+=3,a===0?(this.isobmffReader.pos+=8,s.timescale=this.isobmffReader.readU32(),s.durationInTimescale=this.isobmffReader.readU32()):a===1&&(this.isobmffReader.pos+=16,s.timescale=this.isobmffReader.readU32(),s.durationInTimescale=this.isobmffReader.readU64())}break;case"hdlr":{let s=this.currentTrack;l(s),this.isobmffReader.pos+=8;let a=this.isobmffReader.readAscii(4);a==="vide"?s.info={type:"video",width:-1,height:-1,codec:null,codecDescription:null,colorSpace:null}:a==="soun"&&(s.info={type:"audio",numberOfChannels:-1,sampleRate:-1,codec:null,codecDescription:null})}break;case"stbl":{let s=this.currentTrack;l(s),s.sampleTableOffset=e,this.readContiguousBoxes(t.contentSize)}break;case"stsd":{let s=this.currentTrack;if(l(s),s.info===null||s.sampleTable)break;let a=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let n=this.isobmffReader.readU32();for(let c=0;c0){if(u===1)this.isobmffReader.pos+=4*4;else if(u===2){this.isobmffReader.pos+=4,d=this.isobmffReader.readF64(),m=this.isobmffReader.readU32(),this.isobmffReader.pos+=4;let h=this.isobmffReader.readU32(),g=this.isobmffReader.readU32(),b=this.isobmffReader.readU32(),f=this.isobmffReader.readU32()}}s.info.numberOfChannels=m,s.info.sampleRate=d,this.readContiguousBoxes(e+o.totalSize-this.isobmffReader.pos)}}}break;case"avcC":{let s=this.currentTrack;l(s&&s.info),s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+t.contentSize)}break;case"hvcC":{let s=this.currentTrack;l(s&&s.info),s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+t.contentSize)}break;case"colr":{let s=this.currentTrack;if(l(s&&s.info?.type==="video"),this.isobmffReader.readAscii(4)!=="nclx")break;let n=this.isobmffReader.readU16(),c=this.isobmffReader.readU16(),o=this.isobmffReader.readU16(),u=!!(this.isobmffReader.readU8()&128);s.info.colorSpace={primaries:Mt[n],transfer:Vt[c],matrix:Dt[o],fullRange:u}}break;case"wave":t.totalSize>8&&this.readContiguousBoxes(t.contentSize);break;case"esds":{let s=this.currentTrack;l(s&&s.info),this.isobmffReader.pos+=4;let a=this.isobmffReader.readU8();l(a===3),this.isobmffReader.readIsomVariableInteger(),this.isobmffReader.pos+=2;let n=this.isobmffReader.readU8(),c=(n&128)!==0,o=(n&64)!==0,u=(n&32)!==0;if(c&&(this.isobmffReader.pos+=2),o){let b=this.isobmffReader.readU8();this.isobmffReader.pos+=b}u&&(this.isobmffReader.pos+=2);let m=this.isobmffReader.readU8();l(m===4),this.isobmffReader.readIsomVariableInteger();let d=this.isobmffReader.readU8();l(d===64),this.isobmffReader.pos+=12;let h=this.isobmffReader.readU8();l(h===5);let g=this.isobmffReader.readIsomVariableInteger();s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+g)}break;case"stts":{let s=this.currentTrack;if(l(s),!s.sampleTable)break;this.isobmffReader.pos+=4;let a=this.isobmffReader.readU32(),n=0,c=0;for(let o=0;oC.id===a);if(!n)break;n.fragmentLookupTable=[];let c=this.isobmffReader.readU32(),o=(c&48)>>4,u=(c&12)>>2,m=c&3,d=this.isobmffReader,h=[d.readU8.bind(d),d.readU16.bind(d),d.readU24.bind(d),d.readU32.bind(d)],g=h[o],b=h[u],f=h[m],k=this.isobmffReader.readU32();for(let C=0;Ca.moofOffset);this.fragments.splice(s+1,0,this.currentFragment);for(let[,a]of this.currentFragment.trackData){let n=a.samples[0],c=_(a.samples);this.currentFragment.dataStart=Math.min(this.currentFragment.dataStart,n.byteOffset),this.currentFragment.dataEnd=Math.max(this.currentFragment.dataEnd,c.byteOffset+c.byteSize)}this.currentFragment=null}break;case"traf":if(l(this.currentFragment),this.readContiguousBoxes(t.contentSize),this.currentTrack){let s=this.currentFragment.trackData.get(this.currentTrack.id);if(s){let a=A(this.currentTrack.fragments,this.currentFragment.moofOffset,c=>c.moofOffset);this.currentTrack.fragments.splice(a+1,0,this.currentFragment);let{currentFragmentState:n}=this.currentTrack;l(n),n.startTimestamp!==null&&(dr(s,n.startTimestamp),s.startTimestampIsFinal=!0)}this.currentTrack.currentFragmentState=null,this.currentTrack=null}break;case"tfhd":{l(this.currentFragment),this.isobmffReader.pos+=1;let s=this.isobmffReader.readU24(),a=!!(s&1),n=!!(s&2),c=!!(s&8),o=!!(s&16),u=!!(s&32),m=!!(s&65536),d=!!(s&131072),h=this.isobmffReader.readU32(),g=this.tracks.find(f=>f.id===h);if(!g)break;let b=this.fragmentTrackDefaults.find(f=>f.trackId===h);this.currentTrack=g,g.currentFragmentState={baseDataOffset:this.currentFragment.implicitBaseDataOffset,sampleDescriptionIndex:b?.defaultSampleDescriptionIndex??null,defaultSampleDuration:b?.defaultSampleDuration??null,defaultSampleSize:b?.defaultSampleSize??null,defaultSampleFlags:b?.defaultSampleFlags??null,startTimestamp:null},a?g.currentFragmentState.baseDataOffset=this.isobmffReader.readU64():d&&(g.currentFragmentState.baseDataOffset=this.currentFragment.moofOffset),n&&(g.currentFragmentState.sampleDescriptionIndex=this.isobmffReader.readU32()),c&&(g.currentFragmentState.defaultSampleDuration=this.isobmffReader.readU32()),o&&(g.currentFragmentState.defaultSampleSize=this.isobmffReader.readU32()),u&&(g.currentFragmentState.defaultSampleFlags=this.isobmffReader.readU32()),m&&(g.currentFragmentState.defaultSampleDuration=0)}break;case"tfdt":{let s=this.currentTrack;if(!s)break;l(s.currentFragmentState);let a=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let n=a===0?this.isobmffReader.readU32():this.isobmffReader.readU64();s.currentFragmentState.startTimestamp=n}break;case"trun":{let s=this.currentTrack;if(!s)break;if(l(this.currentFragment),l(s.currentFragmentState),this.currentFragment.trackData.has(s.id))throw new Error("Can't have two trun boxes for the same track in one fragment.");let a=this.isobmffReader.readU8(),n=this.isobmffReader.readU24(),c=!!(n&1),o=!!(n&4),u=!!(n&256),m=!!(n&512),d=!!(n&1024),h=!!(n&2048),g=this.isobmffReader.readU32(),b=s.currentFragmentState.baseDataOffset;c&&(b+=this.isobmffReader.readI32());let f=null;o&&(f=this.isobmffReader.readU32());let k=b;if(g===0){this.currentFragment.implicitBaseDataOffset=k;break}let C=0,v={startTimestamp:0,endTimestamp:0,samples:[],presentationTimestamps:[],startTimestampIsFinal:!1};this.currentFragment.trackData.set(s.id,v);for(let R=0;R({presentationTimestamp:R.presentationTimestamp,sampleIndex:V})).sort((R,V)=>R.presentationTimestamp-V.presentationTimestamp);let w=v.samples[v.presentationTimestamps[0].sampleIndex],O=v.samples[_(v.presentationTimestamps).sampleIndex];v.startTimestamp=w.presentationTimestamp,v.endTimestamp=O.presentationTimestamp+O.duration,this.currentFragment.implicitBaseDataOffset=k}break}this.isobmffReader.pos=r}},Ne=class{constructor(e){this.internalTrack=e}chunkToSampleIndex=new WeakMap;chunkToFragmentLocation=new WeakMap;getCodec(){throw new Error("Not implemented on base class.")}async computeDuration(){let t=(await this.getChunk(1/0,{metadataOnly:!0}))?.timestamp;return t?t/1e6:0}async getFirstChunk(e){return this.internalTrack.demuxer.isFragmented?this.performFragmentedLookup(()=>{let t=this.internalTrack.fragments[0];return{fragmentIndex:t?0:-1,sampleIndex:t?0:-1,correctSampleFound:!!t}},0,1/0,e):this.fetchChunkForSampleIndex(0,e)}roundToMicrosecond(e){return(Math.floor(e*1e6)+.99999999)/1e6}async getChunk(e,t){e=this.roundToMicrosecond(e);let r=e*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findSampleInFragmentsForTimestamp(r),r,r,t);{let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=lr(s,r);return this.fetchChunkForSampleIndex(a,t)}}async getNextChunk(e,t){if(this.internalTrack.demuxer.isFragmented){let s=this.chunkToFragmentLocation.get(e);if(s===void 0)throw new Error("Chunk was not created from this track.");let a=s.fragment.trackData.get(this.internalTrack.id),n=a.samples[s.sampleIndex],c=B(this.internalTrack.fragments,s.fragment.moofOffset,o=>o.moofOffset);return l(c!==-1),this.performFragmentedLookup(()=>{if(s.sampleIndex+1d.moofOffset);return l(m!==-1),{fragmentIndex:m,sampleIndex:0,correctSampleFound:!0}}return{fragmentIndex:c,sampleIndex:-1,correctSampleFound:!1}}},n.presentationTimestamp,1/0,t)}let r=this.chunkToSampleIndex.get(e);if(r===void 0)throw new Error("Chunk was not created from this track.");return this.fetchChunkForSampleIndex(r+1,t)}async getKeyChunk(e,t){e=this.roundToMicrosecond(e);let r=e*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findKeySampleInFragmentsForTimestamp(r),r,r,t);let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=lr(s,r),n=a===-1?-1:wi(s,a);return this.fetchChunkForSampleIndex(n,t)}async getNextKeyChunk(e,t){if(this.internalTrack.demuxer.isFragmented){let n=this.chunkToFragmentLocation.get(e);if(n===void 0)throw new Error("Chunk was not created from this track.");let c=n.fragment.trackData.get(this.internalTrack.id),o=c.samples[n.sampleIndex],u=B(this.internalTrack.fragments,n.fragment.moofOffset,m=>m.moofOffset);return l(u!==-1),this.performFragmentedLookup(()=>{let m=c.samples.findIndex((d,h)=>d.isKeyFrame&&h>n.sampleIndex);if(m!==-1)return{fragmentIndex:u,sampleIndex:m,correctSampleFound:!0};{let d=n.fragment;for(;d.nextFragment;){d=d.nextFragment;let h=d.trackData.get(this.internalTrack.id);if(h){let g=B(this.internalTrack.fragments,d.moofOffset,f=>f.moofOffset);l(g!==-1);let b=h.samples.findIndex(f=>f.isKeyFrame);if(b===-1)throw new Error("Not supported: Fragment does not contain key sample.");return{fragmentIndex:g,sampleIndex:b,correctSampleFound:!0}}}return{fragmentIndex:u,sampleIndex:-1,correctSampleFound:!1}}},o.presentationTimestamp,1/0,t)}let r=this.chunkToSampleIndex.get(e);if(r===void 0)throw new Error("Chunk was not created from this track.");let s=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=yi(s,r);return this.fetchChunkForSampleIndex(a,t)}async fetchChunkForSampleIndex(e,t){if(e===-1)return null;let r=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),s=Si(r,e);if(!s)return null;let a;t.metadataOnly?a=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(s.chunkOffset,s.chunkOffset+s.chunkSize),a=this.internalTrack.demuxer.chunkReader.readRange(s.sampleOffset,s.sampleOffset+s.sampleSize));let n=1e6*s.presentationTimestamp/this.internalTrack.timescale,c=1e6*s.duration/this.internalTrack.timescale,o=this.createChunk(a,n,c,s.isKeyFrame);return this.chunkToSampleIndex.set(o,e),o}async fetchChunkInFragment(e,t,r){if(t===-1)return null;let a=e.trackData.get(this.internalTrack.id).samples[t];l(a);let n;r.metadataOnly?n=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(e.dataStart,e.dataEnd),n=this.internalTrack.demuxer.chunkReader.readRange(a.byteOffset,a.byteOffset+a.byteSize));let c=1e6*a.presentationTimestamp/this.internalTrack.timescale,o=1e6*a.duration/this.internalTrack.timescale,u=this.createChunk(n,c,o,a.isKeyFrame);return this.chunkToFragmentLocation.set(u,{fragment:e,sampleIndex:t}),u}findSampleInFragmentsForTimestamp(e){let t=A(this.internalTrack.fragments,e,a=>a.trackData.get(this.internalTrack.id).startTimestamp),r=-1,s=!1;if(t!==-1){let n=this.internalTrack.fragments[t].trackData.get(this.internalTrack.id),c=A(n.presentationTimestamps,e,o=>o.presentationTimestamp);l(c!==-1),r=n.presentationTimestamps[c].sampleIndex,s=ea.trackData.get(this.internalTrack.id).startTimestamp),r=-1,s=!1;if(t!==-1){let n=this.internalTrack.fragments[t].trackData.get(this.internalTrack.id),c=n.presentationTimestamps.findLastIndex(u=>n.samples[u.sampleIndex].isKeyFrame&&u.presentationTimestamp<=e);if(c===-1)throw new Error("Not supported: Fragment does not begin with a key sample.");r=n.presentationTimestamps[c].sampleIndex,s=eC.timestamp);k!==-1&&(f=this.internalTrack.fragmentLookupTable[k])}if(c===-1)m.pos=f?.moofOffset??0;else{let k=this.internalTrack.fragments[c];!f||k.moofOffset>=k.moofOffset?(m.pos=k.moofOffset+k.moofSize,h=k):m.pos=f.moofOffset}for(;m.posr)break;if(h.nextFragment){m.pos=h.nextFragment.moofOffset+h.nextFragment.moofSize,h=h.nextFragment;continue}}await m.reader.loadRange(m.pos,m.pos+16);let k=m.pos,C=m.readBoxHeader();if(C.name==="moof"){let v=B(a.fragments,k,w=>w.moofOffset);if(v===-1){m.pos=k;let w=await a.readFragment();h&&(h.nextFragment=w),h=w;let{fragmentIndex:O,sampleIndex:R,correctSampleFound:V}=e();if(V){let J=this.internalTrack.fragments[O];return this.fetchChunkInFragment(J,R,s)}O!==-1&&(g=O,b=R)}else{let w=a.fragments[v];h&&(h.nextFragment=w),h=w}}m.pos=k+C.totalSize}if(g!==-1){let k=this.internalTrack.fragments[g];return this.fetchChunkInFragment(k,b,s)}return null}finally{n()}}},yt=class extends Ne{internalTrack;constructor(e){super(e),this.internalTrack=e}async getCodec(){return this.internalTrack.info.codec}async getWidth(){return this.internalTrack.info.width}async getHeight(){return this.internalTrack.info.height}async getRotation(){return this.internalTrack.rotation}async getDecoderConfig(){return{codec:rr(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),codedWidth:this.internalTrack.info.width,codedHeight:this.internalTrack.info.height,description:this.internalTrack.info.codecDescription??void 0,colorSpace:this.internalTrack.info.colorSpace??void 0}}createChunk(e,t,r,s){return new EncodedVideoChunk({data:e,timestamp:t,duration:r,type:s?"key":"delta"})}},vt=class extends Ne{internalTrack;constructor(e){super(e),this.internalTrack=e}async getCodec(){return this.internalTrack.info.codec}async getNumberOfChannels(){return this.internalTrack.info.numberOfChannels}async getSampleRate(){return this.internalTrack.info.sampleRate}async getDecoderConfig(){return{codec:sr(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),numberOfChannels:this.internalTrack.info.numberOfChannels,sampleRate:this.internalTrack.info.sampleRate,description:this.internalTrack.info.codecDescription??void 0}}createChunk(e,t,r,s){return new EncodedAudioChunk({data:e,timestamp:t,duration:r,type:s?"key":"delta"})}},lr=(i,e)=>{let t=A(i.presentationTimestamps,e,r=>r.presentationTimestamp);return t===-1?-1:i.presentationTimestamps[t].sampleIndex},Si=(i,e)=>{let t=A(i.sampleTimingEntries,e,f=>f.startIndex),r=i.sampleTimingEntries[t];if(!r||r.startIndex+r.count<=e)return null;let a=r.startDecodeTimestamp+(e-r.startIndex)*r.delta,n=A(i.sampleCompositionTimeOffsets,e,f=>f.startIndex),c=i.sampleCompositionTimeOffsets[n];c&&(a+=c.offset);let o=i.sampleSizes[Math.min(e,i.sampleSizes.length-1)],u=A(i.sampleToChunk,e,f=>f.startSampleIndex),m=i.sampleToChunk[u];l(m);let d=m.startChunkIndex+Math.floor((e-m.startSampleIndex)/m.samplesPerChunk),h=i.chunkOffsets[d],g=0,b=h;if(i.sampleSizes.length===1)b+=o*(e-m.startSampleIndex),g+=o*m.samplesPerChunk;else{let f=m.startSampleIndex+(d-m.startChunkIndex)*m.samplesPerChunk;for(let k=f;kf)!==-1:!0}},wi=(i,e)=>{if(!i.keySampleIndices)return e;let t=A(i.keySampleIndices,e,r=>r);return i.keySampleIndices[t]??-1},yi=(i,e)=>{if(!i.keySampleIndices)return e+1;let t=A(i.keySampleIndices,e,r=>r);return i.keySampleIndices[t+1]??-1},dr=(i,e)=>{i.startTimestamp+=e,i.endTimestamp+=e;for(let t of i.samples)t.presentationTimestamp+=e;for(let t of i.presentationTimestamps)t.presentationTimestamp+=e};var He=class extends ue{};var Le=class{},It=class extends Le{async _canReadInput(e){if(await e._mainReader.source._getSize()<8)return!1;let r=new Z(e._mainReader);return r.pos=4,r.readAscii(4)==="ftyp"}_createDemuxer(e){return new We(e)}},At=class extends Le{async _canReadInput(){return!1}_createDemuxer(e){return new He(e)}},Qe=new It,vi=Qe,Ii=Qe,Rt=new At,fr=Rt,Ai=Rt,Ri=[Qe,fr];var Ot=class{_source;_formats;_mainReader;_demuxerPromise=null;_format=null;constructor(e){this._formats=e.formats,this._source=e.source,this._mainReader=new me(e.source)}_getDemuxer(){return this._demuxerPromise??=(async()=>{await this._mainReader.loadRange(0,4096);for(let e of this._formats)if(await e._canReadInput(this))return this._format=e,e._createDemuxer(this);throw new Error("Input has an unrecognizable format.")})()}async getFormat(){return await this._getDemuxer(),l(this._format),this._format}async computeDuration(){return(await this._getDemuxer()).computeDuration()}async getTracks(){return(await this._getDemuxer()).getTracks()}async getVideoTracks(){return(await this.getTracks()).filter(t=>t.isVideoTrack())}async getPrimaryVideoTrack(){return(await this.getTracks()).find(t=>t.isVideoTrack())??null}async getAudioTracks(){return(await this.getTracks()).filter(t=>t.isAudioTrack())}async getPrimaryAudioTrack(){return(await this.getTracks()).find(t=>t.isAudioTrack())??null}async getMimeType(){return(await this._getDemuxer()).getMimeType()}};var Ke=class{async*chunks(e,t=1/0){let r=[],{promise:s,resolve:a}=F(),{promise:n,resolve:c}=F(),o=!1,u=[],m=()=>Math.max(2,u.length);(async()=>{let d=e??await this.getFirstChunk();for(;d&&!o&&!(d.timestamp/1e6>=t);){if(r.length>m()){({promise:n,resolve:c}=F()),await n;continue}r.push(d),a(),{promise:s,resolve:a}=F(),d=await this.getNextChunk(d)}o=!0,a()})();try{for(;;)if(r.length>0){yield r.shift();let d=performance.now();for(u.push(d);u.length>0&&d-u[0]>=1e3;)u.shift();c()}else if(!o)await s;else break}finally{o=!0,c()}}},$e=class{duplicateFrame(e){return structuredClone(e)}async*mediaFramesAtTimestamps(e){let t=Bt(e),r=[],s=[],{promise:a,resolve:n}=F(),{promise:c,resolve:o}=F(),u=!1,m=!1,d=8,h=null,g=f=>{s.push(f),n(),{promise:a,resolve:n}=F()},b=await this.createDecoder(f=>{if(o(),m){f.close();return}let k=!1;for(;r.length>0&&r[0]===f.timestamp;)g(this.duplicateFrame(f)),r.shift(),k=!0;k?(h?.close(),h=f):f.close()});(async()=>{let f=this.createChunkDrain(),k=null,C=null;for await(let v of t){for(;s.length+b.decodeQueueSize>d;)({promise:c,resolve:o}=F()),await c;if(m)break;let w=await f.getChunk(v);if(!w){g(null);continue}let O=await f.getKeyChunk(v);if(!O){g(null);continue}for(r.push(w.timestamp),k&&O.timestamp===k.timestamp&&w.timestamp>=C.timestamp?(l(C),w.timestamp===C.timestamp&&r.length===1&&(h&&g(this.duplicateFrame(h)),r.shift())):(k=O,C=O,b.decode(O));C.timestamp!==w.timestamp;){let R=await f.getNextChunk(C);l(R),C=R,b.decode(R)}b.decodeQueueSize>=10&&await new Promise(R=>b.addEventListener("dequeue",R,{once:!0}))}await b.flush(),b.close(),u=!0,n()})();try{for(;;)if(s.length>0){let f=s.shift();l(f!==void 0),yield f,o()}else if(!u)await a;else break}finally{m=!0,o();for(let f of s)f?.close();h?.close()}}async*mediaFramesInRange(e=0,t=1/0){let r=[],s=!1,a=null,{promise:n,resolve:c}=F(),{promise:o,resolve:u}=F(),m=!1,d=!1,h=8,g=await this.createDecoder(k=>{u();let C=k.timestamp/1e6;if(C>=t&&(d=!0),d){k.close();return}a&&(C>e?(r.push(a),s=!0):a.close()),C>=e&&(r.push(k),s=!0),a=s?null:k,r.length>0&&(c(),{promise:n,resolve:c}=F())}),b=this.createChunkDrain(),f=await b.getKeyChunk(e)??await b.getFirstChunk();if(f){(async()=>{let k=f,C=1/0;if(t<1/0){let w=await b.getChunk(t),O=w?w.type==="key"&&w.timestamp/1e6===t?w:await b.getNextKeyChunk(w):null;O&&(C=O.timestamp/1e6)}let v=b.chunks(f,C);for(await v.next();k&&!d;){if(r.length+g.decodeQueueSize>h){({promise:o,resolve:u}=F()),await o;continue}g.decode(k);let w=await v.next();if(w.done)break;k=w.value}await v.return(),await g.flush(),g.close(),!s&&a&&r.push(a),m=!0,c()})();try{for(;;)if(r.length>0)yield r.shift(),u();else if(!m)await n;else break}finally{d=!0,u();for(let k of r)k.close()}}}},je=class extends Ke{constructor(t){super();this.videoTrack=t}getFirstChunk(t={}){return this.videoTrack._backing.getFirstChunk(t)}getChunk(t,r={}){return this.videoTrack._backing.getChunk(t,r)}getNextChunk(t,r={}){return this.videoTrack._backing.getNextChunk(t,r)}getKeyChunk(t,r={}){return this.videoTrack._backing.getKeyChunk(t,r)}getNextKeyChunk(t,r={}){return this.videoTrack._backing.getNextKeyChunk(t,r)}},qe=class extends $e{constructor(t){super();this.videoTrack=t}decoderConfig=null;async createDecoder(t){this.decoderConfig??=await this.videoTrack.getDecoderConfig();let r=new VideoDecoder({output:t,error:s=>console.error(s)});return r.configure(this.decoderConfig),r}createChunkDrain(){return new je(this.videoTrack)}async getFrame(t){for await(let r of this.mediaFramesAtTimestamps([t]))return r;throw new Error("Internal error: Iterator returned nothing.")}frames(t=0,r=1/0){return this.mediaFramesInRange(t,r)}framesAtTimestamps(t){return this.mediaFramesAtTimestamps(t)}},_t=class{constructor(e,t){this.videoTrack=e;this.dimensions=t;this.videoFrameDrain=new qe(e)}videoFrameDrain;async videoFrameToWrappedCanvas(e){let t=this.dimensions?.width??await this.videoTrack.getRotatedWidth(),r=this.dimensions?.height??await this.videoTrack.getRotatedHeight(),s=await this.videoTrack.getRotation(),a=document.createElement("canvas");a.width=t,a.height=r;let n=a.getContext("2d",{alpha:!1});l(n),n.translate(t/2,r/2),n.rotate(s*Math.PI/180),n.translate(-t/2,-r/2);let[c,o]=s%180===0?[t,r]:[r,t];n.drawImage(e,(t-c)/2,(r-o)/2,c,o);let u={canvas:a,timestamp:e.timestamp/1e6,duration:(e.duration??0)/1e6};return e.close(),u}async getCanvas(e){let t=await this.videoFrameDrain.getFrame(e);return t&&this.videoFrameToWrappedCanvas(t)}async*canvases(e=0,t=1/0){for await(let r of this.videoFrameDrain.frames(e,t))yield this.videoFrameToWrappedCanvas(r)}async*canvasesAtTimestamps(e){for await(let t of this.videoFrameDrain.framesAtTimestamps(e))yield t&&this.videoFrameToWrappedCanvas(t)}},Xe=class extends Ke{constructor(t){super();this.audioTrack=t}getFirstChunk(t={}){return this.audioTrack._backing.getFirstChunk(t)}getChunk(t,r={}){return this.audioTrack._backing.getChunk(t,r)}getNextChunk(t,r={}){return this.audioTrack._backing.getNextChunk(t,r)}getKeyChunk(t,r={}){return this.audioTrack._backing.getKeyChunk(t,r)}getNextKeyChunk(t,r={}){return this.audioTrack._backing.getNextKeyChunk(t,r)}},Ge=class extends $e{constructor(t){super();this.audioTrack=t}decoderConfig=null;async createDecoder(t){this.decoderConfig??=await this.audioTrack.getDecoderConfig();let r=new AudioDecoder({output:t,error:s=>console.error(s)});return r.configure(this.decoderConfig),r}createChunkDrain(){return new Xe(this.audioTrack)}async getData(t){for await(let r of this.mediaFramesAtTimestamps([t]))return r;throw new Error("Internal error: Iterator returned nothing.")}data(t=0,r=1/0){return this.mediaFramesInRange(t,r)}dataAtTimestamps(t){return this.mediaFramesAtTimestamps(t)}},Et=class{constructor(e){this.audioTrack=e;this.audioDataDrain=new Ge(e)}audioDataDrain;audioDataToWrappedArrayBuffer(e){let t=new AudioBuffer({numberOfChannels:e.numberOfChannels,length:e.numberOfFrames,sampleRate:e.sampleRate}),r=new Float32Array(e.allocationSize({planeIndex:0,format:"f32-planar"})/4);for(let n=0;n{let t=kr.exec(i);if(!t)throw new Error("Expected match.");return 60*60*1e3*Number(t[1]||"0")+60*1e3*Number(t[2])+1e3*Number(t[3])+Number(t[4])},Ee=i=>{let t=Math.floor(i/36e5),e=Math.floor(i%(60*60*1e3)/(60*1e3)),r=Math.floor(i%(60*1e3)/1e3),a=i%1e3;return t.toString().padStart(2,"0")+":"+e.toString().padStart(2,"0")+":"+r.toString().padStart(2,"0")+"."+a.toString().padStart(3,"0")};var fe=class{constructor(t){this.writer=t;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap}writeU32(t){this.helperView.setUint32(0,t,!1),this.writer.write(this.helper.subarray(0,4))}writeU64(t){this.helperView.setUint32(0,Math.floor(t/2**32),!1),this.helperView.setUint32(4,t,!1),this.writer.write(this.helper.subarray(0,8))}writeAscii(t){for(let e=0;e[(i%256+256)%256],C=i=>(B.setUint16(0,i,!1),[x[0],x[1]]),gr=i=>(B.setInt16(0,i,!1),[x[0],x[1]]),Ht=i=>(B.setUint32(0,i,!1),[x[1],x[2],x[3]]),h=i=>(B.setUint32(0,i,!1),[x[0],x[1],x[2],x[3]]),Lt=i=>(B.setInt32(0,i,!1),[x[0],x[1],x[2],x[3]]),G=i=>(B.setUint32(0,Math.floor(i/2**32),!1),B.setUint32(4,i,!1),[x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7]]),at=i=>(B.setInt16(0,2**8*i,!1),[x[0],x[1]]),U=i=>(B.setInt32(0,2**16*i,!1),[x[0],x[1],x[2],x[3]]),it=i=>(B.setInt32(0,2**30*i,!1),[x[0],x[1],x[2],x[3]]),st=(i,t)=>{let e=[],r=i;do{let a=r&127;r>>=7,e.length>0&&(a|=128),e.push(a),t!==void 0&&t--}while(r>0||t);return e.reverse()},M=(i,t=!1)=>{let e=Array(i.length).fill(null).map((r,a)=>i.charCodeAt(a));return t&&e.push(0),e},nt=i=>{let t=null;for(let e of i)(!t||e.timestamp>t.timestamp)&&(t=e);return t},Qt=i=>[U(i[0]),U(i[1]),it(i[2]),U(i[3]),U(i[4]),it(i[5]),U(i[6]),U(i[7]),it(i[8])],S=(i,t,e)=>({type:i,contents:t&&new Uint8Array(t.flat(10)),children:e}),y=(i,t,e,r,a)=>S(i,[_(t),Ht(e),r??[]],a),Kt=i=>i.fragmented?S("ftyp",[M("iso5"),h(512),M("iso5"),M("iso6"),M("mp41")]):S("ftyp",[M("isom"),h(512),M("isom"),i.holdsAvc?M("avc1"):[],M("mp41")]),Me=i=>({type:"mdat",largeSize:i}),$t=i=>({type:"free",size:i}),pe=(i,t,e=!1)=>S("moov",void 0,[Tr(t,i),...i.map(r=>xr(r,t)),e?Jr(i):null]),Tr=(i,t)=>{let e=P(Math.max(0,...t.filter(n=>n.samples.length>0).map(n=>{let o=nt(n.samples);return o.timestamp+o.duration})),Fe),r=Math.max(0,...t.map(n=>n.track.id))+1,a=!K(i)||!K(e),s=a?G:h;return y("mvhd",+a,0,[s(i),s(i),h(Fe),s(e),U(1),at(1),Array(10).fill(0),Qt(rt),Array(24).fill(0),h(r)])},xr=(i,t)=>S("trak",void 0,[Cr(i,t),Sr(i,t)]),Cr=(i,t)=>{let e=nt(i.samples),r=P(e?e.timestamp+e.duration:0,Fe),a=!K(t)||!K(r),s=a?G:h,n;if(i.type==="video"){let o=i.track.metadata.rotation;n=o===void 0||typeof o=="number"?Q(o??0):o}else n=rt;return y("tkhd",+a,3,[s(t),s(t),h(i.track.id),h(0),s(r),Array(8).fill(0),C(0),C(i.track.id),at(i.type==="audio"?1:0),C(0),Qt(n),U(i.type==="video"?i.info.width:0),U(i.type==="video"?i.info.height:0)])},Sr=(i,t)=>S("mdia",void 0,[wr(i,t),_r(i),Ir(i)]),wr=(i,t)=>{let e=nt(i.samples),r=P(e?e.timestamp+e.duration:0,i.timescale),a=!K(t)||!K(r),s=a?G:h;return y("mdhd",+a,0,[s(t),s(t),h(i.timescale),s(r),C(21956),C(0)])},yr={video:"vide",audio:"soun",subtitle:"text"},vr={video:"VideoHandler",audio:"SoundHandler",subtitle:"TextHandler"},_r=i=>y("hdlr",0,0,[M("mhlr"),M(yr[i.type]),h(0),h(0),h(0),M(vr[i.type],!0)]),Ir=i=>S("minf",void 0,[Er[i.type](),Fr(),Dr(i)]),Ar=()=>y("vmhd",0,1,[C(0),C(0),C(0),C(0)]),Rr=()=>y("smhd",0,0,[C(0),C(0)]),Or=()=>y("nmhd",0,0),Er={video:Ar,audio:Rr,subtitle:Or},Fr=()=>S("dinf",void 0,[Mr()]),Mr=()=>y("dref",0,0,[h(1)],[Vr()]),Vr=()=>y("url ",0,1),Dr=i=>{let t=i.compositionTimeOffsetTable.length>1||i.compositionTimeOffsetTable.some(e=>e.sampleCompositionTimeOffset!==0);return S("stbl",void 0,[Pr(i),jr(i),qr(i),Xr(i),Gr(i),Yr(i),t?Zr(i):null])},Pr=i=>{let t;return i.type==="video"?t=zr(ci[i.track.source._codec],i):i.type==="audio"?t=Hr(mi[i.track.source._codec],i):i.type==="subtitle"&&(t=Kr(li[i.track.source._codec],i)),d(t),y("stsd",0,0,[h(1)],[t])},zr=(i,t)=>S(i,[Array(6).fill(0),C(1),C(0),C(0),Array(12).fill(0),C(t.info.width),C(t.info.height),h(4718592),h(4718592),h(0),C(1),Array(32).fill(0),C(24),gr(65535)],[ui[t.track.source._codec](t),Ae(t.info.decoderConfig.colorSpace)?Ur(t):null]),Ur=i=>S("colr",[M("nclx"),C(j[i.info.decoderConfig.colorSpace.primaries]),C(q[i.info.decoderConfig.colorSpace.transfer]),C(X[i.info.decoderConfig.colorSpace.matrix]),_((i.info.decoderConfig.colorSpace.fullRange?1:0)<<7)]),Br=i=>i.info.decoderConfig&&S("avcC",[...$(i.info.decoderConfig.description)]),Wr=i=>i.info.decoderConfig&&S("hvcC",[...$(i.info.decoderConfig.description)]),Nt=i=>{if(!i.info.decoderConfig)return null;let t=i.info.decoderConfig;d(t.colorSpace);let e=t.codec.split("."),r=Number(e[1]),a=Number(e[2]),o=(Number(e[3])<<4)+(0<<1)+Number(t.colorSpace.fullRange);return y("vpcC",1,0,[_(r),_(a),_(o),_(2),_(2),_(2),C(0)])},Nr=()=>S("av1C",[129,0,0,0]),Hr=(i,t)=>S(i,[Array(6).fill(0),C(1),C(0),C(0),h(0),C(t.info.numberOfChannels),C(16),C(0),C(0),U(t.info.sampleRate)],[di[t.track.source._codec](t)]),Lr=i=>{let e=[...$(i.info.decoderConfig.description??new ArrayBuffer(0))];return e=[..._(64),..._(21),...Ht(0),...h(0),...h(0),..._(5),...st(e.length),...e],e=[...C(1),..._(0),..._(4),...st(e.length),...e,..._(6),..._(1),..._(2)],e=[..._(3),...st(e.length),...e],y("esds",0,0,e)},Qr=i=>{let t=3840,e=0,r=i.info.decoderConfig?.description;if(r){d(r.byteLength>=18);let a=ArrayBuffer.isView(r)?new DataView(r.buffer,r.byteOffset,r.byteLength):new DataView(r);t=a.getUint16(10,!0),e=a.getInt16(14,!0)}return S("dOps",[_(0),_(i.info.numberOfChannels),C(t),h(i.info.sampleRate),at(e),_(0)])},Kr=(i,t)=>S(i,[Array(6).fill(0),C(1)],[fi[t.track.source._codec](t)]),$r=i=>S("vttC",[...D.encode(i.info.config.description)]);var jr=i=>y("stts",0,0,[h(i.timeToSampleTable.length),i.timeToSampleTable.map(t=>[h(t.sampleCount),h(t.sampleDelta)])]),qr=i=>{if(i.samples.every(e=>e.type==="key"))return null;let t=[...i.samples.entries()].filter(([,e])=>e.type==="key");return y("stss",0,0,[h(t.length),t.map(([e])=>h(e+1))])},Xr=i=>y("stsc",0,0,[h(i.compactlyCodedChunkTable.length),i.compactlyCodedChunkTable.map(t=>[h(t.firstChunk),h(t.samplesPerChunk),h(1)])]),Gr=i=>y("stsz",0,0,[h(0),h(i.samples.length),i.samples.map(t=>h(t.size))]),Yr=i=>i.finalizedChunks.length>0&&R(i.finalizedChunks).offset>=2**32?y("co64",0,0,[h(i.finalizedChunks.length),i.finalizedChunks.map(t=>G(t.offset))]):y("stco",0,0,[h(i.finalizedChunks.length),i.finalizedChunks.map(t=>h(t.offset))]),Zr=i=>y("ctts",0,0,[h(i.compositionTimeOffsetTable.length),i.compositionTimeOffsetTable.map(t=>[h(t.sampleCount),h(t.sampleCompositionTimeOffset)])]),Jr=i=>S("mvex",void 0,i.map(ei)),ei=i=>y("trex",0,0,[h(i.track.id),h(1),h(0),h(0),h(0)]),ot=(i,t)=>S("moof",void 0,[ti(i),...t.map(ri)]),ti=i=>y("mfhd",0,0,[h(i)]),jt=i=>{let t=0,e=0,r=0,a=0,s=i.type==="delta";return e|=+s,s?t|=1:t|=2,t<<24|e<<16|r<<8|a},ri=i=>S("traf",void 0,[ii(i),si(i),ai(i)]),ii=i=>{d(i.currentChunk);let t=0;t|=8,t|=16,t|=32,t|=131072;let e=i.currentChunk.samples[1]??i.currentChunk.samples[0],r={duration:e.timescaleUnitsToNextSample,size:e.size,flags:jt(e)};return y("tfhd",0,t,[h(i.track.id),h(r.duration),h(r.size),h(r.flags)])},si=i=>(d(i.currentChunk),y("tfdt",1,0,[G(P(i.currentChunk.startTimestamp,i.timescale))])),ai=i=>{d(i.currentChunk);let t=i.currentChunk.samples.map(p=>p.timescaleUnitsToNextSample),e=i.currentChunk.samples.map(p=>p.size),r=i.currentChunk.samples.map(jt),a=i.currentChunk.samples.map(p=>P(p.timestamp-p.decodeTimestamp,i.timescale)),s=new Set(t),n=new Set(e),o=new Set(r),c=new Set(a),u=o.size===2&&r[0]!==r[1],m=s.size>1,l=n.size>1,f=!u&&o.size>1,g=c.size>1||[...c].some(p=>p!==0),b=0;return b|=1,b|=4*+u,b|=256*+m,b|=512*+l,b|=1024*+f,b|=2048*+g,y("trun",1,b,[h(i.currentChunk.samples.length),h(i.currentChunk.offset-i.currentChunk.moofOffset||0),u?h(r[0]):[],i.currentChunk.samples.map((p,k)=>[m?h(t[k]):[],l?h(e[k]):[],f?h(r[k]):[],g?Lt(a[k]):[]])])},qt=i=>S("mfra",void 0,[...i.map(ni),oi()]),ni=(i,t)=>y("tfra",1,0,[h(i.track.id),h(63),h(i.finalizedChunks.length),i.finalizedChunks.map(r=>[G(P(r.samples[0].timestamp,i.timescale)),G(r.moofOffset),h(t+1),h(1),h(1)])]),oi=()=>y("mfro",0,0,[h(0)]),Xt=()=>S("vtte"),Gt=(i,t,e,r,a)=>S("vttc",void 0,[a!==null?S("vsid",[Lt(a)]):null,e!==null?S("iden",[...D.encode(e)]):null,t!==null?S("ctim",[...D.encode(Ee(t))]):null,r!==null?S("sttg",[...D.encode(r)]):null,S("payl",[...D.encode(i)])]),Yt=i=>S("vtta",[...D.encode(i)]),ci={avc:"avc1",hevc:"hvc1",vp8:"vp08",vp9:"vp09",av1:"av01"},ui={avc:Br,hevc:Wr,vp8:Nt,vp9:Nt,av1:Nr},mi={aac:"mp4a",opus:"Opus"},di={aac:Lr,opus:Qr},li={webvtt:"wvtt"},fi={webvtt:$r};var te=class{constructor(t){this.mutex=new L;this.trackTimestampInfo=new WeakMap;this.output=t}beforeTrackAdd(t){}onTrackClose(t){}validateAndNormalizeTimestamp(t,e,r){let a=e/1e6,s=this.trackTimestampInfo.get(t);if(!s){if(!r)throw new Error("First frame must be a key frame.");if(this.timestampsMustStartAtZero&&a>0)throw new Error(`Timestamps must start at zero (got ${a}s).`);s={timestampOffset:a,maxTimestamp:t.source._offsetTimestamps?0:a,lastKeyFrameTimestamp:t.source._offsetTimestamps?0:a},this.trackTimestampInfo.set(t,s)}if(t.source._offsetTimestamps&&(a-=s.timestampOffset),a<0)throw new Error(`Timestamps must be non-negative (got ${a}s).`);if(aa.start-s.start);e.push({start:r[0].start,size:r[0].data.byteLength});for(let a=1;au.start<=r&&rhi){for(let u=0;u=e.written[n+1].start;)e.written[n].end=Math.max(e.written[n].end,e.written[n+1].end),e.written.splice(n+1,1)}createChunk(e){let a={start:Math.floor(e/this.chunkSize)*this.chunkSize,data:new Uint8Array(this.chunkSize),written:[],shouldFlush:!1};return this.chunks.push(a),this.chunks.sort((s,n)=>s.start-n.start),this.chunks.indexOf(a)}queueChunksForFlush(e=!1){d(this.writer);for(let r=0;r{if(i==="avc"){let s=Math.ceil(t/16)*Math.ceil(e/16),n=Zt.find(l=>s<=l.maxMacroblocks&&r<=l.maxBitrate)??R(Zt),o=n?n.level:0,c="64".padStart(2,"0"),u="00",m=o.toString(16).padStart(2,"0");return`avc1.${c}${u}${m}`}else if(i==="hevc"){let a="",n="6",o=t*e,c=Jt.find(m=>o<=m.maxPictureSize&&r<=m.maxBitrate)??R(Jt);return`hev1.${a}1.${n}.${c.tier}${c.level}.B0`}else{if(i==="vp8")return"vp8";if(i==="vp9"){let a="00",s=t*e,n=er.find(c=>s<=c.maxPictureSize&&r<=c.maxBitrate)??R(er);return`vp09.${a}.${n.level}.08`}else if(i==="av1"){let s=t*e,n=tr.find(c=>s<=c.maxPictureSize&&r<=c.maxBitrate)??R(tr);return`av01.0.${n.level.toString().padStart(2,"0")}${n.tier}.08`}}throw new TypeError(`Unhandled codec '${i}'.`)},ir=(i,t)=>{if(i==="avc"){if(!t||t.byteLength<4)throw new TypeError("AVC description must be at least 4 bytes long.");return`avc1.${Pt(t.subarray(1,4))}`}else if(i==="hevc"){if(!t)throw new TypeError("HEVC description must be provided.");let e=new DataView(t.buffer,t.byteOffset,t.byteLength),r="hev1.",a=t[1]>>6&3,s=t[1]&31;r+=["","A","B","C"][a]+s,r+=".";let n=zt(e.getUint32(2));r+=n.toString(16),r+=".";let o=t[1]>>5&1,c=t[12];r+=o===0?"L":"H",r+=c,r+=".";let u=[];for(let m=0;m<6;m++){let l=t[m+13];u.push(l)}for(;u[u.length-1]===0;)u.pop();return r+=u.map(m=>m.toString(16)).join("."),r}throw new TypeError(`Unhandled codec '${i}'.`)},sr=(i,t,e)=>{if(i==="aac")return t>=2&&e<=24e3?"mp4a.40.29":e<=24e3?"mp4a.40.5":"mp4a.40.2";if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},ar=(i,t)=>{if(i==="aac")return`mp4a.40.${ut(t).objectType}`;if(i==="opus")return"opus";if(i==="vorbis")return"vorbis";throw new TypeError(`Unhandled codec '${i}'.`)},ut=i=>{if(!i||i.byteLength<2)throw new TypeError("AAC description must be at least 2 bytes long.");let t=0,e=O(i,t,t+5);t+=5,e===31&&(e=32+O(i,t,t+6),t+=6);let r=O(i,t,t+4);t+=4;let a=null;if(r===15)a=O(i,t,t+24),t+=24;else{let o=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];r=1&&s<=7&&(n={1:1,2:2,3:3,4:4,5:5,6:6,7:8}[s]),{objectType:e,frequencyIndex:r,sampleRate:a,channelConfiguration:s,numberOfChannels:n}},nr=i=>i==="avc"?{avc:{format:"avc"}}:i==="hevc"?{hevc:{format:"hevc"}}:{},or=i=>i==="aac"?{aac:{format:"aac"}}:i==="opus"?{opus:{format:"opus"}}:{},ze=i=>{if(!i)throw new TypeError("Video chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Video chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Video chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Video chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Video chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.codedWidth)||i.decoderConfig.codedWidth<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).");if(!Number.isInteger(i.decoderConfig.codedHeight)||i.decoderConfig.codedHeight<=0)throw new TypeError("Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).");if(i.decoderConfig.description!==void 0&&!tt(i.decoderConfig.description))throw new TypeError("Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.colorSpace!==void 0){let{colorSpace:t}=i.decoderConfig;if(typeof t!="object")throw new TypeError("Video chunk metadata decoder configuration colorSpace, when provided, must be an object.");let e=Object.keys(j);if(t.primaries!=null&&!e.includes(t.primaries))throw new TypeError(`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of ${e.join(", ")}.`);let r=Object.keys(q);if(t.transfer!=null&&!r.includes(t.transfer))throw new TypeError(`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of ${r.join(", ")}.`);let a=Object.keys(X);if(t.matrix!=null&&!a.includes(t.matrix))throw new TypeError(`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of ${a.join(", ")}.`);if(t.fullRange!=null&&typeof t.fullRange!="boolean")throw new TypeError("Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.")}if((i.decoderConfig.codec.startsWith("avc1")||i.decoderConfig.codec.startsWith("avc3"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for AVC must include a description, which is expected to be an AVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec.startsWith("hev1")||i.decoderConfig.codec.startsWith("hvc1"))&&!i.decoderConfig.description)throw new TypeError("Video chunk metadata decoder configuration for HEVC must include a description, which is expected to be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15.");if((i.decoderConfig.codec==="vp8"||i.decoderConfig.codec.startsWith("vp09"))&&i.decoderConfig.colorSpace===void 0)throw new TypeError("Video chunk metadata decoder configuration for VP8/VP9 must include a colorSpace.")},Ue=i=>{if(!i)throw new TypeError("Audio chunk metadata must be provided.");if(typeof i!="object")throw new TypeError("Audio chunk metadata must be an object.");if(!i.decoderConfig)throw new TypeError("Audio chunk metadata must include a decoder configuration.");if(typeof i.decoderConfig!="object")throw new TypeError("Audio chunk metadata decoder configuration must be an object.");if(typeof i.decoderConfig.codec!="string")throw new TypeError("Audio chunk metadata decoder configuration must specify a codec string.");if(!Number.isInteger(i.decoderConfig.sampleRate)||i.decoderConfig.sampleRate<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).");if(!Number.isInteger(i.decoderConfig.numberOfChannels)||i.decoderConfig.numberOfChannels<=0)throw new TypeError("Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).");if(i.decoderConfig.description!==void 0&&!tt(i.decoderConfig.description))throw new TypeError("Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.");if(i.decoderConfig.codec.startsWith("mp4a")&&!i.decoderConfig.description)throw new TypeError("Audio chunk metadata decoder configuration for AAC must include a description, which is expected to be an AudioSpecificConfig as specified in ISO 14496-3.");if(i.decoderConfig.codec==="opus"&&i.decoderConfig.description&&i.decoderConfig.description.byteLength<18)throw new TypeError("Invalid decoder description provided for Opus; must be at least 18 bytes long.")},Be=i=>{if(!i)throw new TypeError("Subtitle metadata must be provided.");if(typeof i!="object")throw new TypeError("Subtitle metadata must be an object.");if(!i.config)throw new TypeError("Subtitle metadata must include a config object.");if(typeof i.config!="object")throw new TypeError("Subtitle metadata config must be an object.");if(typeof i.config.description!="string")throw new TypeError("Subtitle metadata config description must be a string.")};var Fe=1e3,bi=2082844800,P=(i,t,e=!0)=>{let r=i*t;return e?Math.round(r):r},We=class extends te{constructor(e,r){super(e);this.timestampsMustStartAtZero=!0;this.auxTarget=new be;this.auxWriter=this.auxTarget._createWriter();this.auxBoxWriter=new fe(this.auxWriter);this.ftypSize=null;this.mdat=null;this.trackDatas=[];this.creationTime=Math.floor(Date.now()/1e3)+bi;this.finalizedChunks=[];this.nextFragmentNumber=1;this.writer=e._writer,this.boxWriter=new fe(this.writer);let a=this.writer instanceof re?"in-memory":!1;this.fastStart=r._options.fastStart??a,(this.fastStart==="in-memory"||this.fastStart==="fragmented")&&(this.writer.ensureMonotonicity=!0)}async start(){let e=await this.mutex.acquire(),r=this.output._tracks.some(a=>a.type==="video"&&a.source._codec==="avc");this.boxWriter.writeBox(Kt({holdsAvc:r,fragmented:this.fastStart==="fragmented"})),this.ftypSize=this.writer.getPos(),this.fastStart==="in-memory"?this.mdat=Me(!1):this.fastStart==="fragmented"||(this.mdat=Me(!0),this.boxWriter.writeBox(this.mdat)),await this.writer.flush(),e()}getVideoTrackData(e,r){let a=this.trackDatas.find(n=>n.track===e);if(a)return a;ze(r),d(r),d(r.decoderConfig),d(r.decoderConfig.codedWidth!==void 0),d(r.decoderConfig.codedHeight!==void 0);let s={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},timescale:e.metadata.frameRate??57600,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),s}getAudioTrackData(e,r){let a=this.trackDatas.find(n=>n.track===e);if(a)return a;Ue(r),d(r),d(r.decoderConfig);let s={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},timescale:r.decoderConfig.sampleRate,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[]};return this.trackDatas.push(s),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),s}getSubtitleTrackData(e,r){let a=this.trackDatas.find(n=>n.track===e);if(a)return a;Be(r),d(r),d(r.config);let s={track:e,type:"subtitle",info:{config:r.config},timescale:1e3,samples:[],sampleQueue:[],timestampProcessingQueue:[],timeToSampleTable:[],compositionTimeOffsetTable:[],lastTimescaleUnits:null,lastSample:null,finalizedChunks:[],currentChunk:null,compactlyCodedChunkTable:[],lastCueEndTimestamp:0,cueQueue:[],nextSourceId:0,cueToSourceId:new WeakMap};return this.trackDatas.push(s),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),this.validateAndNormalizeTimestamp(e,0,!0),s}async addEncodedVideoChunk(e,r,a){let s=await this.mutex.acquire();try{let n=this.getVideoTrackData(e,a),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=this.validateAndNormalizeTimestamp(n.track,r.timestamp,r.type==="key"),u=this.createSampleForTrack(n,o,c,(r.duration??0)/1e6,r.type);await this.registerSample(n,u)}finally{s()}}async addEncodedAudioChunk(e,r,a){let s=await this.mutex.acquire();try{let n=this.getAudioTrackData(e,a),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=r.type,u=this.validateAndNormalizeTimestamp(n.track,r.timestamp,c==="key"),m=this.createSampleForTrack(n,o,u,(r.duration??0)/1e6,c);await this.registerSample(n,m)}finally{s()}}async addSubtitleCue(e,r,a){let s=await this.mutex.acquire();try{let n=this.getSubtitleTrackData(e,a);this.validateAndNormalizeTimestamp(n.track,1e6*r.timestamp,!0),e.source._codec==="webvtt"&&(n.cueQueue.push(r),await this.processWebVTTCues(n,r.timestamp))}finally{s()}}async processWebVTTCues(e,r){for(;e.cueQueue.length>0;){let a=new Set([]);for(let m of e.cueQueue)d(m.timestamp<=r),d(e.lastCueEndTimestamp<=m.timestamp+m.duration),a.add(Math.max(m.timestamp,e.lastCueEndTimestamp)),a.add(m.timestamp+m.duration);let s=[...a].sort((m,l)=>m-l),n=s[0],o=s[1]??n;if(r=o)break;ee.lastIndex=0;let f=ee.test(l.text),g=l.timestamp+l.duration,b=e.cueToSourceId.get(l);if(b===void 0&&oa.timestamp).sort((a,s)=>a-s);for(let a=0;a{if(e===o)return r.type==="key";let c=o.sampleQueue[0];return c&&c.type==="key"});s>=1&&n&&(a=!0,await this.finalizeFragment())}else a=s>=.5}a&&(e.currentChunk&&await this.finalizeCurrentChunk(e),e.currentChunk={startTimestamp:r.timestamp,samples:[],offset:null,moofOffset:null}),d(e.currentChunk),e.currentChunk.samples.push(r),e.timestampProcessingQueue.push(r)}async finalizeCurrentChunk(e){if(d(this.fastStart!=="fragmented"),!!e.currentChunk){if(e.finalizedChunks.push(e.currentChunk),this.finalizedChunks.push(e.currentChunk),(e.compactlyCodedChunkTable.length===0||R(e.compactlyCodedChunkTable).samplesPerChunk!==e.currentChunk.samples.length)&&e.compactlyCodedChunkTable.push({firstChunk:e.finalizedChunks.length,samplesPerChunk:e.currentChunk.samples.length}),this.fastStart==="in-memory"){e.currentChunk.offset=0;return}e.currentChunk.offset=this.writer.getPos();for(let r of e.currentChunk.samples)d(r.data),this.writer.write(r.data),r.data=null;await this.writer.flush()}}async interleaveSamples(){d(this.fastStart==="fragmented");for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let s of this.trackDatas){if(s.sampleQueue.length===0&&!s.track.source._closed)break e;s.sampleQueue.length>0&&s.sampleQueue[0].timestampu.currentChunk),s=this.writer.getPos(),n=ot(r,a);this.boxWriter.writeBox(n);{let u=Me(!1),m=0;for(let f of a)for(let g of f.currentChunk.samples)m+=g.size;let l=this.boxWriter.measureBox(u)+m;l>=2**32&&(u.largeSize=!0,l=this.boxWriter.measureBox(u)+m),u.size=l,this.boxWriter.writeBox(u)}for(let u of a){u.currentChunk.offset=this.writer.getPos(),u.currentChunk.moofOffset=s;for(let m of u.currentChunk.samples)this.writer.write(m.data),m.data=null}let o=this.writer.getPos();this.writer.seek(this.boxWriter.offsets.get(n));let c=ot(r,a);this.boxWriter.writeBox(c),this.writer.seek(o);for(let u of a)u.finalizedChunks.push(u.currentChunk),this.finalizedChunks.push(u.currentChunk),u.currentChunk=null;e&&await this.writer.flush()}async onTrackClose(e){let r=await this.mutex.acquire();if(e.type==="subtitle"&&e.source._codec==="webvtt"){let a=this.trackDatas.find(s=>s.track===e);a&&await this.processWebVTTCues(a,1/0)}this.fastStart==="fragmented"&&await this.interleaveSamples(),r()}async finalize(){let e=await this.mutex.acquire();for(let r of this.trackDatas)r.type==="subtitle"&&r.track.source._codec==="webvtt"&&await this.processWebVTTCues(r,1/0);if(this.fastStart==="fragmented"){for(let r of this.trackDatas){for(let a of r.sampleQueue)await this.addSampleToTrack(r,a);this.processTimestamps(r)}await this.finalizeFragment(!1)}else for(let r of this.trackDatas)this.processTimestamps(r),await this.finalizeCurrentChunk(r);if(this.fastStart==="in-memory"){d(this.mdat);let r;for(let s=0;s<2;s++){let n=pe(this.trackDatas,this.creationTime),o=this.boxWriter.measureBox(n);r=this.boxWriter.measureBox(this.mdat);let c=this.writer.getPos()+o+r;for(let u of this.finalizedChunks){u.offset=c;for(let{data:m}of u.samples)d(m),c+=m.byteLength,r+=m.byteLength}if(c<2**32)break;r>=2**32&&(this.mdat.largeSize=!0)}let a=pe(this.trackDatas,this.creationTime);this.boxWriter.writeBox(a),this.mdat.size=r,this.boxWriter.writeBox(this.mdat);for(let s of this.finalizedChunks)for(let n of s.samples)d(n.data),this.writer.write(n.data),n.data=null}else if(this.fastStart==="fragmented"){let r=this.writer.getPos(),a=qt(this.trackDatas);this.boxWriter.writeBox(a);let s=this.writer.getPos()-r;this.writer.seek(this.writer.getPos()-4),this.boxWriter.writeU32(s)}else{d(this.mdat),d(this.ftypSize!==null);let r=this.boxWriter.offsets.get(this.mdat);d(r!==void 0);let a=this.writer.getPos()-r;this.mdat.size=a,this.mdat.largeSize=a>=2**32,this.boxWriter.patchBox(this.mdat);let s=pe(this.trackDatas,this.creationTime);if(typeof this.fastStart=="object"){this.writer.seek(this.ftypSize),this.boxWriter.writeBox(s);let n=r-this.writer.getPos();this.boxWriter.writeBox($t(n))}else this.boxWriter.writeBox(s)}e()}};var ke=class{constructor(t){this.value=t}},ae=class{constructor(t){this.value=t}},ge=class{constructor(t){this.value=t}};var mt=i=>i<256?1:i<65536?2:i<1<<24?3:i<2**32?4:i<2**40?5:6,dt=i=>i>=-64&&i<64?1:i>=-8192&&i<8192?2:i>=-(1<<20)&&i<1<<20?3:i>=-(1<<27)&&i<1<<27?4:i>=-(2**34)&&i<2**34?5:6,cr=i=>{if(i<127)return 1;if(i<16383)return 2;if(i<(1<<21)-1)return 3;if(i<(1<<28)-1)return 4;if(i<2**35-1)return 5;if(i<2**42-1)return 6;throw new Error("EBML VINT size not supported "+i)};var lt=2**15,ur="https://github.com/Vanilagy/webm-muxer",mr=6,dr=5,ki={avc:"V_MPEG4/ISO/AVC",hevc:"V_MPEGH/ISO/HEVC",vp8:"V_VP8",vp9:"V_VP9",av1:"V_AV1",aac:"A_AAC",opus:"A_OPUS",webvtt:"S_TEXT/WEBVTT"},gi={video:1,audio:2,subtitle:17},Ne=class extends te{constructor(e,r){super(e);this.timestampsMustStartAtZero=!1;this.helper=new Uint8Array(8);this.helperView=new DataView(this.helper.buffer);this.offsets=new WeakMap;this.dataOffsets=new WeakMap;this.trackDatas=[];this.segment=null;this.segmentInfo=null;this.seekHead=null;this.tracksElement=null;this.segmentDuration=null;this.cues=null;this.currentCluster=null;this.currentClusterMsTimestamp=null;this.trackDatasInCurrentCluster=new Set;this.duration=0;this.writer=e._writer,this.format=r,this.format._options.streamable&&(this.writer.ensureMonotonicity=!0)}writeByte(e){this.helperView.setUint8(0,e),this.writer.write(this.helper.subarray(0,1))}writeFloat32(e){this.helperView.setFloat32(0,e,!1),this.writer.write(this.helper.subarray(0,4))}writeFloat64(e){this.helperView.setFloat64(0,e,!1),this.writer.write(this.helper)}writeUnsignedInt(e,r=mt(e)){let a=0;switch(r){case 6:this.helperView.setUint8(a++,e/2**40|0);case 5:this.helperView.setUint8(a++,e/2**32|0);case 4:this.helperView.setUint8(a++,e>>24);case 3:this.helperView.setUint8(a++,e>>16);case 2:this.helperView.setUint8(a++,e>>8);case 1:this.helperView.setUint8(a++,e);break;default:throw new Error("Bad UINT size "+r)}this.writer.write(this.helper.subarray(0,a))}writeSignedInt(e,r=dt(e)){e<0&&(e+=2**(r*8)),this.writeUnsignedInt(e,r)}writeEBMLVarInt(e,r=cr(e)){let a=0;switch(r){case 1:this.helperView.setUint8(a++,128|e);break;case 2:this.helperView.setUint8(a++,64|e>>8),this.helperView.setUint8(a++,e);break;case 3:this.helperView.setUint8(a++,32|e>>16),this.helperView.setUint8(a++,e>>8),this.helperView.setUint8(a++,e);break;case 4:this.helperView.setUint8(a++,16|e>>24),this.helperView.setUint8(a++,e>>16),this.helperView.setUint8(a++,e>>8),this.helperView.setUint8(a++,e);break;case 5:this.helperView.setUint8(a++,8|e/2**32&7),this.helperView.setUint8(a++,e>>24),this.helperView.setUint8(a++,e>>16),this.helperView.setUint8(a++,e>>8),this.helperView.setUint8(a++,e);break;case 6:this.helperView.setUint8(a++,4|e/2**40&3),this.helperView.setUint8(a++,e/2**32|0),this.helperView.setUint8(a++,e>>24),this.helperView.setUint8(a++,e>>16),this.helperView.setUint8(a++,e>>8),this.helperView.setUint8(a++,e);break;default:throw new Error("Bad EBML VINT size "+r)}this.writer.write(this.helper.subarray(0,a))}writeString(e){this.writer.write(new Uint8Array(e.split("").map(r=>r.charCodeAt(0))))}writeEBML(e){if(e!==null){if(e instanceof Uint8Array)this.writer.write(e);else if(Array.isArray(e))for(let r of e)this.writeEBML(r);else if(this.offsets.set(e,this.writer.getPos()),this.writeUnsignedInt(e.id),Array.isArray(e.data)){let r=this.writer.getPos(),a=e.size===-1?1:e.size??4;e.size===-1?this.writeByte(255):this.writer.seek(this.writer.getPos()+a);let s=this.writer.getPos();if(this.dataOffsets.set(e,s),this.writeEBML(e.data),e.size!==-1){let n=this.writer.getPos()-s,o=this.writer.getPos();this.writer.seek(r),this.writeEBMLVarInt(n,a),this.writer.seek(o)}}else if(typeof e.data=="number"){let r=e.size??mt(e.data);this.writeEBMLVarInt(r),this.writeUnsignedInt(e.data,r)}else if(typeof e.data=="string")this.writeEBMLVarInt(e.data.length),this.writeString(e.data);else if(e.data instanceof Uint8Array)this.writeEBMLVarInt(e.data.byteLength,e.size),this.writer.write(e.data);else if(e.data instanceof ke)this.writeEBMLVarInt(4),this.writeFloat32(e.data.value);else if(e.data instanceof ae)this.writeEBMLVarInt(8),this.writeFloat64(e.data.value);else if(e.data instanceof ge){let r=e.size??dt(e.data.value);this.writeEBMLVarInt(r),this.writeSignedInt(e.data.value,r)}}}beforeTrackAdd(e){if(this.format instanceof ne)if(e.type==="video"){if(!["vp8","vp9","av1"].includes(e.source._codec))throw new Error("WebM only supports VP8, VP9 and AV1 as video codecs. Switching to MKV removes this restriction.")}else if(e.type==="audio"){if(!["opus","vorbis"].includes(e.source._codec))throw new Error("WebM only supports Opus and Vorbis as audio codecs. Switching to MKV removes this restriction.")}else if(e.type==="subtitle"){if(e.source._codec!=="webvtt")throw new Error("WebM only supports WebVTT as subtitle codec. Switching to MKV removes this restriction.")}else throw new Error("WebM only supports video, audio and subtitle tracks. Switching to MKV removes this restriction.")}async start(){let e=await this.mutex.acquire();this.writeEBMLHeader(),this.format._options.streamable||this.createSeekHead(),this.createSegmentInfo(),this.createCues(),await this.writer.flush(),e()}writeEBMLHeader(){let e={id:440786851,data:[{id:17030,data:1},{id:17143,data:1},{id:17138,data:4},{id:17139,data:8},{id:17026,data:this.format instanceof ne?"webm":"matroska"},{id:17031,data:2},{id:17029,data:2}]};this.writeEBML(e)}createSeekHead(){let e=new Uint8Array([28,83,187,107]),r=new Uint8Array([21,73,169,102]),a=new Uint8Array([22,84,174,107]),s={id:290298740,data:[{id:19899,data:[{id:21419,data:e},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:r},{id:21420,size:5,data:0}]},{id:19899,data:[{id:21419,data:a},{id:21420,size:5,data:0}]}]};this.seekHead=s}createSegmentInfo(){let e={id:17545,data:new ae(0)};this.segmentDuration=e;let r={id:357149030,data:[{id:2807729,data:1e6},{id:19840,data:ur},{id:22337,data:ur},this.format._options.streamable?null:e]};this.segmentInfo=r}createTracks(){let e={id:374648427,data:[]};this.tracksElement=e;for(let r of this.trackDatas)e.data.push({id:174,data:[{id:215,data:r.track.id},{id:29637,data:r.track.id},{id:131,data:gi[r.type]},{id:134,data:ki[r.track.source._codec]},r.type==="video"?this.videoSpecificTrackInfo(r):null,r.type==="audio"?this.audioSpecificTrackInfo(r):null,r.type==="subtitle"?this.subtitleSpecificTrackInfo(r):null]})}videoSpecificTrackInfo(e){let r=[e.info.decoderConfig.description?{id:25506,data:$(e.info.decoderConfig.description)}:null,e.track.metadata.frameRate?{id:2352003,data:1e9/e.track.metadata.frameRate}:null],a=e.info.decoderConfig.colorSpace,s={id:224,data:[{id:176,data:e.info.width},{id:186,data:e.info.height},Ae(a)?{id:21936,data:[{id:21937,data:X[a.matrix]},{id:21946,data:q[a.transfer]},{id:21947,data:j[a.primaries]},{id:21945,data:a.fullRange?2:1}]}:null]};return r.push(s),r}audioSpecificTrackInfo(e){return[e.info.decoderConfig.description?{id:25506,data:$(e.info.decoderConfig.description)}:null,{id:225,data:[{id:181,data:new ke(e.info.sampleRate)},{id:159,data:e.info.numberOfChannels}]}]}subtitleSpecificTrackInfo(e){return[{id:25506,data:D.encode(e.info.config.description)}]}createSegment(){let e={id:408125543,size:this.format._options.streamable?-1:mr,data:[this.format._options.streamable?null:this.seekHead,this.segmentInfo,this.tracksElement]};this.segment=e,this.writeEBML(e)}createCues(){this.cues={id:475249515,data:[]}}get segmentDataOffset(){return d(this.segment),this.dataOffsets.get(this.segment)}getVideoTrackData(e,r){let a=this.trackDatas.find(n=>n.track===e);if(a)return a;ze(r),d(r),d(r.decoderConfig),d(r.decoderConfig.codedWidth!==void 0),d(r.decoderConfig.codedHeight!==void 0);let s={track:e,type:"video",info:{width:r.decoderConfig.codedWidth,height:r.decoderConfig.codedHeight,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),s}getAudioTrackData(e,r){let a=this.trackDatas.find(n=>n.track===e);if(a)return a;Ue(r),d(r),d(r.decoderConfig);let s={track:e,type:"audio",info:{numberOfChannels:r.decoderConfig.numberOfChannels,sampleRate:r.decoderConfig.sampleRate,decoderConfig:r.decoderConfig},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),s}getSubtitleTrackData(e,r){let a=this.trackDatas.find(n=>n.track===e);if(a)return a;Be(r),d(r),d(r.config);let s={track:e,type:"subtitle",info:{config:r.config},chunkQueue:[],lastWrittenMsTimestamp:null};return this.trackDatas.push(s),this.trackDatas.sort((n,o)=>n.track.id-o.track.id),s}async addEncodedVideoChunk(e,r,a){let s=await this.mutex.acquire();try{let n=this.getVideoTrackData(e,a),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=r.type==="key",u=this.validateAndNormalizeTimestamp(n.track,r.timestamp,c),m=this.createInternalChunk(o,u,(r.duration??0)/1e6,r.type);e.source._codec==="vp9"&&this.fixVP9ColorSpace(n,m),n.chunkQueue.push(m),await this.interleaveChunks()}finally{s()}}async addEncodedAudioChunk(e,r,a){let s=await this.mutex.acquire();try{let n=this.getAudioTrackData(e,a),o=new Uint8Array(r.byteLength);r.copyTo(o);let c=r.type,u=c==="key",m=this.validateAndNormalizeTimestamp(n.track,r.timestamp,u),l=this.createInternalChunk(o,m,(r.duration??0)/1e6,c);n.chunkQueue.push(l),await this.interleaveChunks()}finally{s()}}async addSubtitleCue(e,r,a){let s=await this.mutex.acquire();try{let n=this.getSubtitleTrackData(e,a),o=this.validateAndNormalizeTimestamp(n.track,1e6*r.timestamp,!0),c=r.text,u=Math.floor(o*1e3);ee.lastIndex=0,c=c.replace(ee,g=>{let p=Oe(g.slice(1,-1))-u;return`<${Ee(p)}>`});let m=D.encode(c),l=`${r.settings??""} +${r.identifier??""} +${r.notes??""}`,f=this.createInternalChunk(m,o,r.duration,"key",l.trim()?D.encode(l):null);n.chunkQueue.push(f),await this.interleaveChunks()}finally{s()}}async interleaveChunks(){for(let e of this.output._tracks)if(!e.source._closed&&!this.trackDatas.some(r=>r.track===e))return;e:for(;;){let e=null,r=1/0;for(let s of this.trackDatas){if(s.chunkQueue.length===0&&!s.track.source._closed)break e;s.chunkQueue.length>0&&s.chunkQueue[0].timestamp=2&&a++;let u={rgb:7,bt709:2,bt470bg:1,smpte170m:3}[e.info.decoderConfig.colorSpace.matrix];Ft(r.data,a+0,a+3,u)}createInternalChunk(e,r,a,s,n=null){return{data:e,type:s,timestamp:r,duration:a,additions:n}}writeBlock(e,r){this.segment||(this.createTracks(),this.createSegment());let a=Math.floor(1e3*r.timestamp),s=this.trackDatas.every(l=>{if(l.track.source._closed)return!0;if(e===l)return r.type==="key";let f=l.chunkQueue[0];return f&&f.type==="key"});(!this.currentCluster||s&&a-this.currentClusterMsTimestamp>=1e3)&&this.createNewCluster(a);let n=a-this.currentClusterMsTimestamp;if(n<0)return;if(n>=lt)throw new Error(`Current Matroska cluster exceeded its maximum allowed length of ${lt} milliseconds. In order to produce a correct WebM file, you must pass in a key frame at least every ${lt} milliseconds.`);let c=new Uint8Array(4),u=new DataView(c.buffer);u.setUint8(0,128|e.track.id),u.setInt16(1,n,!1);let m=Math.floor(1e3*r.duration);if(m===0&&!r.additions){u.setUint8(3,+(r.type==="key")<<7);let l={id:163,data:[c,r.data]};this.writeEBML(l)}else{let l={id:160,data:[{id:161,data:[c,r.data]},r.type==="delta"?{id:251,data:new ge(e.lastWrittenMsTimestamp-a)}:null,r.additions?{id:30113,data:[{id:166,data:[{id:165,data:r.additions},{id:238,data:1}]}]}:null,m>0?{id:155,data:m}:null]};this.writeEBML(l)}this.duration=Math.max(this.duration,a+m),e.lastWrittenMsTimestamp=a,this.trackDatasInCurrentCluster.add(e)}createNewCluster(e){this.currentCluster&&!this.format._options.streamable&&this.finalizeCurrentCluster(),this.currentCluster={id:524531317,size:this.format._options.streamable?-1:dr,data:[{id:231,data:e}]},this.writeEBML(this.currentCluster),this.currentClusterMsTimestamp=e,this.trackDatasInCurrentCluster.clear()}finalizeCurrentCluster(){d(this.currentCluster);let e=this.writer.getPos()-this.dataOffsets.get(this.currentCluster),r=this.writer.getPos();this.writer.seek(this.offsets.get(this.currentCluster)+4),this.writeEBMLVarInt(e,dr),this.writer.seek(r);let a=this.offsets.get(this.currentCluster)-this.segmentDataOffset;d(this.cues),this.cues.data.push({id:187,data:[{id:179,data:this.currentClusterMsTimestamp},...[...this.trackDatasInCurrentCluster].map(s=>({id:183,data:[{id:247,data:s.track.id},{id:241,data:a}]}))]})}async onTrackClose(){let e=await this.mutex.acquire();await this.interleaveChunks(),e()}async finalize(){let e=await this.mutex.acquire();this.segment||(this.createTracks(),this.createSegment());for(let r of this.trackDatas)for(;r.chunkQueue.length>0;)this.writeBlock(r,r.chunkQueue.shift());if(!this.format._options.streamable&&this.currentCluster&&this.finalizeCurrentCluster(),d(this.cues),this.writeEBML(this.cues),!this.format._options.streamable){let r=this.writer.getPos(),a=this.writer.getPos()-this.segmentDataOffset;this.writer.seek(this.offsets.get(this.segment)+4),this.writeEBMLVarInt(a,mr),this.segmentDuration.data=new ae(this.duration),this.writer.seek(this.offsets.get(this.segmentDuration)),this.writeEBML(this.segmentDuration),this.seekHead.data[0].data[1].data=this.offsets.get(this.cues)-this.segmentDataOffset,this.seekHead.data[1].data[1].data=this.offsets.get(this.segmentInfo)-this.segmentDataOffset,this.seekHead.data[2].data[1].data=this.offsets.get(this.tracksElement)-this.segmentDataOffset,this.writer.seek(this.offsets.get(this.seekHead)),this.writeEBML(this.seekHead),this.writer.seek(r)}e()}};var Z=class{},ft=class extends Z{constructor(t={}){if(!t||typeof t!="object")throw new TypeError("options must be an object.");if(t.fastStart!==void 0&&![!1,"in-memory","fragmented"].includes(t.fastStart))throw new TypeError('options.fastStart, when provided, must be false, "in-memory", or "fragmented".');super(),this._options=t}_createMuxer(t){return new We(t,this)}},He=class extends Z{constructor(t={}){if(!t||typeof t!="object")throw new TypeError("options must be an object.");if(t.streamable!==void 0&&typeof t.streamable!="boolean")throw new TypeError("options.streamable, when provided, must be a boolean.");super(),this._options=t}_createMuxer(t){return new Ne(t,this)}},ne=class extends He{};var oe=class{constructor(){this._connectedTrack=null;this._closed=!1;this._offsetTimestamps=!1}_ensureValidDigest(){if(!this._connectedTrack)throw new Error("Cannot call digest without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call digest before output has been started.");if(this._connectedTrack.output._finalizing)throw new Error("Cannot call digest after output has started finalizing.");if(this._closed)throw new Error("Cannot call digest after source has been closed.")}_start(){}async _flush(){}close(){if(this._closed)throw new Error("Source already closed.");if(!this._connectedTrack)throw new Error("Cannot call close without connecting the source to an output track.");if(!this._connectedTrack.output._started)throw new Error("Cannot call close before output has been started.");this._closed=!0,!this._connectedTrack.output._finalizing&&this._connectedTrack.output._muxer.onTrackClose(this._connectedTrack)}},N=class extends oe{constructor(e){super();this._connectedTrack=null;if(!ie.includes(e))throw new TypeError(`Invalid video codec '${e}'. Must be one of: ${ie.join(", ")}.`);this._codec=e}},pt=class extends N{constructor(t){super(t)}digest(t,e){if(!(t instanceof EncodedVideoChunk))throw new TypeError("chunk must be an EncodedVideoChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedVideoChunk(this._connectedTrack,t,e)}},Ti=5,xi=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!ie.includes(i.codec))throw new TypeError(`Invalid video codec '${i.codec}'. Must be one of: ${ie.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.");if(i.latencyMode!==void 0&&!["quality","realtime"].includes(i.latencyMode))throw new TypeError("config.latencyMode, when provided, must be 'quality' or 'realtime'.")},Te=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null;this.muxer=null;this.lastMultipleOfKeyFrameInterval=-1;this.lastWidth=null;this.lastHeight=null;xi(e)}async digest(t){if(this.source._ensureValidDigest(),this.lastWidth!==null&&this.lastHeight!==null){if(t.codedWidth!==this.lastWidth||t.codedHeight!==this.lastHeight)throw new Error(`Video frame size must remain constant. Expected ${this.lastWidth}x${this.lastHeight}, got ${t.codedWidth}x${t.codedHeight}.`)}else this.lastWidth=t.codedWidth,this.lastHeight=t.codedHeight;this.ensureEncoder(t),d(this.encoder);let e=Math.floor(t.timestamp/1e6/Ti);this.encoder.encode(t,{keyFrame:e!==this.lastMultipleOfKeyFrameInterval}),this.lastMultipleOfKeyFrameInterval=e,this.encoder.encodeQueueSize>=4&&await new Promise(r=>this.encoder.addEventListener("dequeue",r,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(t){this.encoder||(this.encoder=new VideoEncoder({output:(e,r)=>void this.muxer.addEncodedVideoChunk(this.source._connectedTrack,e,r),error:e=>console.error("Video encode error:",e)}),this.encoder.configure({codec:rr(this.codecConfig.codec,t.codedWidth,t.codedHeight,this.codecConfig.bitrate),width:t.codedWidth,height:t.codedHeight,bitrate:this.codecConfig.bitrate,framerate:this.source._connectedTrack?.metadata.frameRate,latencyMode:this.codecConfig.latencyMode,...nr(this.codecConfig.codec)}),d(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},ht=class extends N{constructor(t){super(t.codec),this._encoder=new Te(this,t)}digest(t){if(!(t instanceof VideoFrame))throw new TypeError("videoFrame must be a VideoFrame.");return this._encoder.digest(t)}_flush(){return this._encoder.flush()}},bt=class extends N{constructor(t,e){if(!(t instanceof HTMLCanvasElement))throw new TypeError("canvas must be an HTMLCanvasElement.");super(e.codec),this._encoder=new Te(this,e),this._canvas=t}digest(t,e=0){if(!Number.isFinite(t)||t<0)throw new TypeError("timestamp must be a non-negative number.");if(!Number.isFinite(e)||e<0)throw new TypeError("duration must be a non-negative number.");let r=new VideoFrame(this._canvas,{timestamp:Math.round(1e6*t),duration:Math.round(1e6*e),alpha:"discard"}),a=this._encoder.digest(r);return r.close(),a}_flush(){return this._encoder.flush()}},kt=class extends N{constructor(e,r){if(!(e instanceof MediaStreamTrack)||e.kind!=="video")throw new TypeError("track must be a video MediaStreamTrack.");r={...r,latencyMode:"realtime"};super(r.codec);this._abortController=null;this._offsetTimestamps=!0;this._encoder=new Te(this,r),this._track=e}_start(){this._abortController=new AbortController;let e=new MediaStreamTrackProcessor({track:this._track}),r=new WritableStream({write:a=>{this._encoder.digest(a),a.close()}});e.readable.pipeTo(r,{signal:this._abortController.signal}).catch(a=>{a instanceof DOMException&&a.name==="AbortError"||console.error("Pipe error:",a)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},H=class extends oe{constructor(e){super();this._connectedTrack=null;if(!se.includes(e))throw new TypeError(`Invalid audio codec '${e}'. Must be one of: ${se.join(", ")}.`);this._codec=e}},gt=class extends H{constructor(t){super(t)}digest(t,e){if(!(t instanceof EncodedAudioChunk))throw new TypeError("chunk must be an EncodedAudioChunk.");return this._ensureValidDigest(),this._connectedTrack.output._muxer.addEncodedAudioChunk(this._connectedTrack,t,e)}},Ci=i=>{if(!i||typeof i!="object")throw new TypeError("Codec config must be an object.");if(!se.includes(i.codec))throw new TypeError(`Invalid audio codec '${i.codec}'. Must be one of: ${se.join(", ")}.`);if(!Number.isInteger(i.bitrate)||i.bitrate<=0)throw new TypeError("config.bitrate must be a positive integer.")},xe=class{constructor(t,e){this.source=t;this.codecConfig=e;this.encoder=null;this.muxer=null;this.lastNumberOfChannels=null;this.lastSampleRate=null;Ci(e)}async digest(t){if(this.source._ensureValidDigest(),this.lastNumberOfChannels!==null&&this.lastSampleRate!==null){if(t.numberOfChannels!==this.lastNumberOfChannels||t.sampleRate!==this.lastSampleRate)throw new Error(`Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${t.numberOfChannels} channels at ${t.sampleRate} Hz.`)}else this.lastNumberOfChannels=t.numberOfChannels,this.lastSampleRate=t.sampleRate;this.ensureEncoder(t),d(this.encoder),this.encoder.encode(t),this.encoder.encodeQueueSize>=4&&await new Promise(e=>this.encoder.addEventListener("dequeue",e,{once:!0})),await this.muxer.mutex.currentPromise}ensureEncoder(t){this.encoder||(this.encoder=new AudioEncoder({output:(e,r)=>void this.muxer.addEncodedAudioChunk(this.source._connectedTrack,e,r),error:e=>console.error("Audio encode error:",e)}),this.encoder.configure({codec:sr(this.codecConfig.codec,t.numberOfChannels,t.sampleRate),numberOfChannels:t.numberOfChannels,sampleRate:t.sampleRate,bitrate:this.codecConfig.bitrate,...or(this.codecConfig.codec)}),d(this.source._connectedTrack),this.muxer=this.source._connectedTrack.output._muxer)}async flush(){this.encoder&&(await this.encoder.flush(),this.encoder.close())}},Tt=class extends H{constructor(t){super(t.codec),this._encoder=new xe(this,t)}digest(t){if(!(t instanceof AudioData))throw new TypeError("audioData must be an AudioData.");return this._encoder.digest(t)}_flush(){return this._encoder.flush()}},xt=class extends H{constructor(e){super(e.codec);this._accumulatedFrameCount=0;this._encoder=new xe(this,e)}digest(e){if(!(e instanceof AudioBuffer))throw new TypeError("audioBuffer must be an AudioBuffer.");let r=e.numberOfChannels,a=e.sampleRate,s=e.length,n=new Float32Array(r*s);for(let u=0;u{this._encoder.digest(a),a.close()}});e.readable.pipeTo(r,{signal:this._abortController.signal}).catch(a=>{a instanceof DOMException&&a.name==="AbortError"||console.error("Pipe error:",a)})}async _flush(){this._abortController&&(this._abortController.abort(),this._abortController=null),await this._encoder.flush()}},ce=class extends oe{constructor(e){super();this._connectedTrack=null;if(!Pe.includes(e))throw new TypeError(`Invalid subtitle codec '${e}'. Must be one of: ${Pe.join(", ")}.`);this._codec=e}},St=class extends ce{constructor(t){super(t),this._parser=new Re({codec:t,output:(e,r)=>this._connectedTrack?.output._muxer.addSubtitleCue(this._connectedTrack,e,r),error:e=>console.error("Subtitle parse error:",e)})}digest(t){if(typeof t!="string")throw new TypeError("text must be a string.");return this._ensureValidDigest(),this._parser.parse(t),this._connectedTrack.output._muxer.mutex.currentPromise}};var wt=class{constructor(t){this._tracks=[];this._started=!1;this._finalizing=!1;this._mutex=new L;if(!t||typeof t!="object")throw new TypeError("options must be an object.");if(!(t.format instanceof Z))throw new TypeError("options.format must be an OutputFormat.");if(!(t.target instanceof Y))throw new TypeError("options.target must be a Target.");if(t.target._output)throw new Error("Target is already used for another output.");t.target._output=this,this._writer=t.target._createWriter(),this._muxer=t.format._createMuxer(this)}addVideoTrack(t,e={}){if(!(t instanceof N))throw new TypeError("source must be a VideoSource.");if(!e||typeof e!="object")throw new TypeError("metadata must be an object.");if(typeof e.rotation=="number"&&![0,90,180,270].includes(e.rotation))throw new TypeError(`Invalid video rotation: ${e.rotation}. Has to be 0, 90, 180 or 270.`);if(Array.isArray(e.rotation)&&(e.rotation.length!==9||e.rotation.some(r=>!Number.isFinite(r))))throw new TypeError(`Invalid video transformation matrix: ${e.rotation.join()}`);if(e.frameRate!==void 0&&(!Number.isInteger(e.frameRate)||e.frameRate<=0))throw new TypeError(`Invalid video frame rate: ${e.frameRate}. Must be a positive integer.`);this._addTrack("video",t,e)}addAudioTrack(t,e={}){if(!(t instanceof H))throw new TypeError("source must be an AudioSource.");if(!e||typeof e!="object")throw new TypeError("metadata must be an object.");this._addTrack("audio",t,e)}addSubtitleTrack(t,e={}){if(!(t instanceof ce))throw new TypeError("source must be a SubtitleSource.");if(!e||typeof e!="object")throw new TypeError("metadata must be an object.");this._addTrack("subtitle",t,e)}_addTrack(t,e,r){if(this._started)throw new Error("Cannot add track after output has started.");if(e._connectedTrack)throw new Error("Source is already used for a track.");let a={id:this._tracks.length+1,output:this,type:t,source:e,metadata:r};this._muxer.beforeTrackAdd(a),this._tracks.push(a),e._connectedTrack=a}async start(){if(this._started)throw new Error("Output already started.");this._started=!0,this._writer.start();let t=await this._mutex.acquire();await this._muxer.start();for(let e of this._tracks)e.source._start();t()}async finalize(){if(!this._started)throw new Error("Cannot finalize before starting.");if(this._finalizing)throw new Error("Cannot call finalize twice.");this._finalizing=!0;let t=await this._mutex.acquire(),e=this._tracks.map(r=>r.source._flush());await Promise.all(e),await this._muxer.finalize(),await this._writer.flush(),await this._writer.finalize(),t()}};var Ce=class{constructor(){this._sizePromise=null}_getSize(){return this._sizePromise??=this._retrieveSize()}},yt=class extends Ce{constructor(t){super(),this._buffer=t}async _read(t,e){return new Uint8Array(this._buffer,t,e-t)}async _retrieveSize(){return this._buffer.byteLength}},vt=class extends Ce{constructor(t){super(),this._blob=t}async _read(t,e){let a=await this._blob.slice(t,e).arrayBuffer();return new Uint8Array(a)}async _retrieveSize(){return this._blob.size}};var Le=class{constructor(t){this.input=t}};var Se=class{constructor(t){this._backing=t}isVideoTrack(){return this instanceof ue}isAudioTrack(){return this instanceof me}computeDuration(){return this._backing.computeDuration()}},ue=class extends Se{constructor(t){super(t),this._backing=t}getCodec(){return this._backing.getCodec()}getCodedWidth(){return this._backing.getCodedWidth()}getCodedHeight(){return this._backing.getCodedHeight()}getRotation(){return this._backing.getRotation()}async getDisplayWidth(){return await this._backing.getRotation()%180===0?this._backing.getCodedWidth():this._backing.getCodedHeight()}async getDisplayHeight(){return await this._backing.getRotation()%180===0?this._backing.getCodedHeight():this._backing.getCodedWidth()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}},me=class extends Se{constructor(t){super(t),this._backing=t}getCodec(){return this._backing.getCodec()}getNumberOfChannels(){return this._backing.getNumberOfChannels()}getSampleRate(){return this._backing.getSampleRate()}getDecoderConfig(){return this._backing.getDecoderConfig()}async getCodecMimeType(){return(await this.getDecoderConfig()).codec}};var de=class{constructor(t,e=1/0){this.source=t;this.maxStorableBytes=e;this.loadedSegments=[];this.loadingSegments=[];this.sourceSizePromise=null;this.nextAge=0;this.totalStoredBytes=0}async loadRange(t,e){e=Math.min(e,await this.source._getSize());let r=this.loadingSegments.find(c=>c.start<=t&&c.end>=e);if(r){await r.promise;return}if(this.loadedSegments.some(c=>c.start<=t&&c.end>=e))return;let s=this.source._read(t,e),n={start:t,end:e,promise:s};this.loadingSegments.push(n);let o=await s;Ut(this.loadingSegments,n),this.insertIntoLoadedSegments(t,o)}insertIntoLoadedSegments(t,e){let r={start:t,end:t+e.byteLength,bytes:e,view:new DataView(e.buffer),age:this.nextAge++},a=I(this.loadedSegments,t,s=>s.start);(a===-1||this.loadedSegments[a].start=r.end)break;r.start<=n.start&&n.end<=r.end&&(this.loadedSegments.splice(s,1),s--)}for(;this.totalStoredBytes>this.maxStorableBytes&&this.loadedSegments.length>1;){let s=null,n=-1;for(let o=0;os.start),a=null;if(r!==-1)for(let s=r;st)break;if(e<=n.end){a=n;break}}if(!a)throw new Error(`No segment loaded for range [${t}, ${e}).`);return a.age=this.nextAge++,{view:a.view,offset:a.bytes.byteOffset+t-a.start}}forgetRange(t,e){if(e<=t)return;let r=I(this.loadedSegments,t,s=>s.start);if(r===-1)return;let a=this.loadedSegments[r];a.start!==t||a.end!==e||(this.loadedSegments.splice(r,1),this.totalStoredBytes-=a.bytes.byteLength)}};var J=class{constructor(t){this.reader=t;this.pos=0}readRange(t,e){let{view:r,offset:a}=this.reader.getViewAndOffset(t,e);return new Uint8Array(r.buffer,a,e-t)}readU8(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+1);return this.pos++,t.getUint8(e)}readU16(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+2);return this.pos+=2,t.getUint16(e,!1)}readU24(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+3);this.pos+=3;let r=t.getUint16(e,!1),a=t.getUint8(e+2);return r*256+a}readS32(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,t.getInt32(e,!1)}readU32(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,t.getUint32(e,!1)}readI32(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+4);return this.pos+=4,t.getInt32(e,!1)}readU64(){let t=this.readU32(),e=this.readU32();return t*4294967296+e}readF64(){let{view:t,offset:e}=this.reader.getViewAndOffset(this.pos,this.pos+8);return this.pos+=8,t.getFloat64(e,!1)}readFixed_16_16(){return this.readS32()/65536}readFixed_2_30(){return this.readS32()/1073741824}readAscii(t){let{view:e,offset:r}=this.reader.getViewAndOffset(this.pos,this.pos+t);this.pos+=t;let a="";for(let s=0;sa.computeDuration()));return Math.max(0,...r)}async getTracks(){return await this.readMetadata(),this.tracks.map(e=>e.inputTrack)}async getMimeType(){await this.readMetadata();let e="video/mp4";if(this.tracks.length>0){let r=await Promise.all(this.tracks.map(s=>s.inputTrack.getCodecMimeType())),a=[...new Set(r)];e+=`; codecs="${a.join(", ")}"`}return e}readMetadata(){return this.metadataPromise??=(async()=>{let e=await this.isobmffReader.reader.source._getSize();for(;this.isobmffReader.pos=0&&aa.presentationTimestamp-s.presentationTimestamp),e.sampleTable}async readFragment(){let e=this.isobmffReader.pos;await this.isobmffReader.reader.loadRange(this.isobmffReader.pos,this.isobmffReader.pos+16);let r=this.isobmffReader.readBoxHeader();d(r.name==="moof"),await this.isobmffReader.reader.loadRange(e,e+r.totalSize),this.isobmffReader.pos=e,this.traverseBox();let a=W(this.fragments,e,n=>n.moofOffset);d(a!==-1);let s=this.fragments[a];d(s.moofOffset===e),this.isobmffReader.reader.forgetRange(e,e+r.totalSize);for(let[n,o]of s.trackData){if(o.startTimestampIsFinal)continue;let c=this.tracks.find(f=>f.id===n);this.isobmffReader.pos=0;let u=null,m=null,l=I(c.fragments,e-1,f=>f.moofOffset);for(l!==-1&&(u=c.fragments[l],m=u,this.isobmffReader.pos=u.moofOffset+u.moofSize);this.isobmffReader.posp.moofOffset);if(b===-1){this.isobmffReader.pos=f;let p=await this.readFragment();u&&(u.nextFragment=p),u=p}else{let p=this.fragments[b];u&&(u.nextFragment=p),u=p}}this.isobmffReader.pos=f+g.totalSize}u&&u.trackData.has(n)&&(m=u)}if(m){let f=m.trackData.get(n);d(f.startTimestampIsFinal),fr(o,f.endTimestamp)}o.startTimestampIsFinal=!0}return s}readContiguousBoxes(e){let r=this.isobmffReader.pos;for(;this.isobmffReader.pos-rl.every((f,g)=>f===u[g]));m===-1?s.rotation=0:s.rotation=90*m}break;case"mdhd":{let s=this.currentTrack;d(s);let n=this.isobmffReader.readU8();this.isobmffReader.pos+=3,n===0?(this.isobmffReader.pos+=8,s.timescale=this.isobmffReader.readU32(),s.durationInTimescale=this.isobmffReader.readU32()):n===1&&(this.isobmffReader.pos+=16,s.timescale=this.isobmffReader.readU32(),s.durationInTimescale=this.isobmffReader.readU64())}break;case"hdlr":{let s=this.currentTrack;d(s),this.isobmffReader.pos+=8;let n=this.isobmffReader.readAscii(4);n==="vide"?s.info={type:"video",width:-1,height:-1,codec:null,codecDescription:null,colorSpace:null}:n==="soun"&&(s.info={type:"audio",numberOfChannels:-1,sampleRate:-1,codec:null,codecDescription:null})}break;case"stbl":{let s=this.currentTrack;d(s),s.sampleTableOffset=e,this.readContiguousBoxes(r.contentSize)}break;case"stsd":{let s=this.currentTrack;if(d(s),s.info===null||s.sampleTable)break;let n=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let o=this.isobmffReader.readU32();for(let c=0;c0){if(m===1)this.isobmffReader.pos+=4*4;else if(m===2){this.isobmffReader.pos+=4,f=this.isobmffReader.readF64(),l=this.isobmffReader.readU32(),this.isobmffReader.pos+=4;let g=this.isobmffReader.readU32(),b=this.isobmffReader.readU32(),p=this.isobmffReader.readU32(),k=this.isobmffReader.readU32()}}s.info.numberOfChannels=l,s.info.sampleRate=f,this.readContiguousBoxes(e+u.totalSize-this.isobmffReader.pos)}}}break;case"avcC":{let s=this.currentTrack;d(s&&s.info),s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+r.contentSize)}break;case"hvcC":{let s=this.currentTrack;d(s&&s.info),s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+r.contentSize)}break;case"colr":{let s=this.currentTrack;if(d(s&&s.info?.type==="video"),this.isobmffReader.readAscii(4)!=="nclx")break;let o=this.isobmffReader.readU16(),c=this.isobmffReader.readU16(),u=this.isobmffReader.readU16(),m=!!(this.isobmffReader.readU8()&128);s.info.colorSpace={primaries:Mt[o],transfer:Vt[c],matrix:Dt[u],fullRange:m}}break;case"wave":r.totalSize>8&&this.readContiguousBoxes(r.contentSize);break;case"esds":{let s=this.currentTrack;d(s&&s.info),this.isobmffReader.pos+=4;let n=this.isobmffReader.readU8();d(n===3),this.isobmffReader.readIsomVariableInteger(),this.isobmffReader.pos+=2;let o=this.isobmffReader.readU8(),c=(o&128)!==0,u=(o&64)!==0,m=(o&32)!==0;if(c&&(this.isobmffReader.pos+=2),u){let p=this.isobmffReader.readU8();this.isobmffReader.pos+=p}m&&(this.isobmffReader.pos+=2);let l=this.isobmffReader.readU8();d(l===4),this.isobmffReader.readIsomVariableInteger();let f=this.isobmffReader.readU8();d(f===64),this.isobmffReader.pos+=12;let g=this.isobmffReader.readU8();d(g===5);let b=this.isobmffReader.readIsomVariableInteger();s.info.codecDescription=this.isobmffReader.readRange(this.isobmffReader.pos,this.isobmffReader.pos+b)}break;case"stts":{let s=this.currentTrack;if(d(s),!s.sampleTable)break;this.isobmffReader.pos+=4;let n=this.isobmffReader.readU32(),o=0,c=0;for(let u=0;uv.id===n);if(!o)break;o.fragmentLookupTable=[];let c=this.isobmffReader.readU32(),u=(c&48)>>4,m=(c&12)>>2,l=c&3,f=this.isobmffReader,g=[f.readU8.bind(f),f.readU16.bind(f),f.readU24.bind(f),f.readU32.bind(f)],b=g[u],p=g[m],k=g[l],w=this.isobmffReader.readU32();for(let v=0;vn.moofOffset);this.fragments.splice(s+1,0,this.currentFragment);for(let[,n]of this.currentFragment.trackData){let o=n.samples[0],c=R(n.samples);this.currentFragment.dataStart=Math.min(this.currentFragment.dataStart,o.byteOffset),this.currentFragment.dataEnd=Math.max(this.currentFragment.dataEnd,c.byteOffset+c.byteSize)}this.currentFragment=null}break;case"traf":if(d(this.currentFragment),this.readContiguousBoxes(r.contentSize),this.currentTrack){let s=this.currentFragment.trackData.get(this.currentTrack.id);if(s){let n=I(this.currentTrack.fragments,this.currentFragment.moofOffset,c=>c.moofOffset);this.currentTrack.fragments.splice(n+1,0,this.currentFragment);let{currentFragmentState:o}=this.currentTrack;d(o),o.startTimestamp!==null&&(fr(s,o.startTimestamp),s.startTimestampIsFinal=!0)}this.currentTrack.currentFragmentState=null,this.currentTrack=null}break;case"tfhd":{d(this.currentFragment),this.isobmffReader.pos+=1;let s=this.isobmffReader.readU24(),n=!!(s&1),o=!!(s&2),c=!!(s&8),u=!!(s&16),m=!!(s&32),l=!!(s&65536),f=!!(s&131072),g=this.isobmffReader.readU32(),b=this.tracks.find(k=>k.id===g);if(!b)break;let p=this.fragmentTrackDefaults.find(k=>k.trackId===g);this.currentTrack=b,b.currentFragmentState={baseDataOffset:this.currentFragment.implicitBaseDataOffset,sampleDescriptionIndex:p?.defaultSampleDescriptionIndex??null,defaultSampleDuration:p?.defaultSampleDuration??null,defaultSampleSize:p?.defaultSampleSize??null,defaultSampleFlags:p?.defaultSampleFlags??null,startTimestamp:null},n?b.currentFragmentState.baseDataOffset=this.isobmffReader.readU64():f&&(b.currentFragmentState.baseDataOffset=this.currentFragment.moofOffset),o&&(b.currentFragmentState.sampleDescriptionIndex=this.isobmffReader.readU32()),c&&(b.currentFragmentState.defaultSampleDuration=this.isobmffReader.readU32()),u&&(b.currentFragmentState.defaultSampleSize=this.isobmffReader.readU32()),m&&(b.currentFragmentState.defaultSampleFlags=this.isobmffReader.readU32()),l&&(b.currentFragmentState.defaultSampleDuration=0)}break;case"tfdt":{let s=this.currentTrack;if(!s)break;d(s.currentFragmentState);let n=this.isobmffReader.readU8();this.isobmffReader.pos+=3;let o=n===0?this.isobmffReader.readU32():this.isobmffReader.readU64();s.currentFragmentState.startTimestamp=o}break;case"trun":{let s=this.currentTrack;if(!s)break;if(d(this.currentFragment),d(s.currentFragmentState),this.currentFragment.trackData.has(s.id))throw new Error("Can't have two trun boxes for the same track in one fragment.");let n=this.isobmffReader.readU8(),o=this.isobmffReader.readU24(),c=!!(o&1),u=!!(o&4),m=!!(o&256),l=!!(o&512),f=!!(o&1024),g=!!(o&2048),b=this.isobmffReader.readU32(),p=s.currentFragmentState.baseDataOffset;c&&(p+=this.isobmffReader.readI32());let k=null;u&&(k=this.isobmffReader.readU32());let w=p;if(b===0){this.currentFragment.implicitBaseDataOffset=w;break}let v=0,T={startTimestamp:0,endTimestamp:0,samples:[],presentationTimestamps:[],startTimestampIsFinal:!1};this.currentFragment.trackData.set(s.id,T);for(let z=0;z({presentationTimestamp:z.presentationTimestamp,sampleIndex:V})).sort((z,V)=>z.presentationTimestamp-V.presentationTimestamp);let A=T.samples[T.presentationTimestamps[0].sampleIndex],F=T.samples[R(T.presentationTimestamps).sampleIndex];T.startTimestamp=A.presentationTimestamp,T.endTimestamp=F.presentationTimestamp+F.duration,this.currentFragment.implicitBaseDataOffset=w}break}this.isobmffReader.pos=a}},Ke=class{constructor(t){this.internalTrack=t;this.chunkToSampleIndex=new WeakMap;this.chunkToFragmentLocation=new WeakMap}getCodec(){throw new Error("Not implemented on base class.")}async computeDuration(){let e=(await this.getChunk(1/0,{metadataOnly:!0}))?.timestamp;return e?e/1e6:0}async getFirstChunk(t){return this.internalTrack.demuxer.isFragmented?this.performFragmentedLookup(()=>{let e=this.internalTrack.fragments[0];return{fragmentIndex:e?0:-1,sampleIndex:e?0:-1,correctSampleFound:!!e}},0,1/0,t):this.fetchChunkForSampleIndex(0,t)}roundToMicrosecond(t){return(Math.floor(t*1e6)+.99999999)/1e6}async getChunk(t,e){t=this.roundToMicrosecond(t);let r=t*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findSampleInFragmentsForTimestamp(r),r,r,e);{let a=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),s=lr(a,r);return this.fetchChunkForSampleIndex(s,e)}}async getNextChunk(t,e){if(this.internalTrack.demuxer.isFragmented){let a=this.chunkToFragmentLocation.get(t);if(a===void 0)throw new Error("Chunk was not created from this track.");let s=a.fragment.trackData.get(this.internalTrack.id),n=s.samples[a.sampleIndex],o=W(this.internalTrack.fragments,a.fragment.moofOffset,c=>c.moofOffset);return d(o!==-1),this.performFragmentedLookup(()=>{if(a.sampleIndex+1l.moofOffset);return d(m!==-1),{fragmentIndex:m,sampleIndex:0,correctSampleFound:!0}}return{fragmentIndex:o,sampleIndex:-1,correctSampleFound:!1}}},n.presentationTimestamp,1/0,e)}let r=this.chunkToSampleIndex.get(t);if(r===void 0)throw new Error("Chunk was not created from this track.");return this.fetchChunkForSampleIndex(r+1,e)}async getKeyChunk(t,e){t=this.roundToMicrosecond(t);let r=t*this.internalTrack.timescale;if(this.internalTrack.demuxer.isFragmented)return this.performFragmentedLookup(()=>this.findKeySampleInFragmentsForTimestamp(r),r,r,e);let a=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),s=lr(a,r),n=s===-1?-1:yi(a,s);return this.fetchChunkForSampleIndex(n,e)}async getNextKeyChunk(t,e){if(this.internalTrack.demuxer.isFragmented){let n=this.chunkToFragmentLocation.get(t);if(n===void 0)throw new Error("Chunk was not created from this track.");let o=n.fragment.trackData.get(this.internalTrack.id),c=o.samples[n.sampleIndex],u=W(this.internalTrack.fragments,n.fragment.moofOffset,m=>m.moofOffset);return d(u!==-1),this.performFragmentedLookup(()=>{let m=o.samples.findIndex((l,f)=>l.isKeyFrame&&f>n.sampleIndex);if(m!==-1)return{fragmentIndex:u,sampleIndex:m,correctSampleFound:!0};{let l=n.fragment;for(;l.nextFragment;){l=l.nextFragment;let f=l.trackData.get(this.internalTrack.id);if(f){let g=W(this.internalTrack.fragments,l.moofOffset,p=>p.moofOffset);d(g!==-1);let b=f.samples.findIndex(p=>p.isKeyFrame);if(b===-1)throw new Error("Not supported: Fragment does not contain key sample.");return{fragmentIndex:g,sampleIndex:b,correctSampleFound:!0}}}return{fragmentIndex:u,sampleIndex:-1,correctSampleFound:!1}}},c.presentationTimestamp,1/0,e)}let r=this.chunkToSampleIndex.get(t);if(r===void 0)throw new Error("Chunk was not created from this track.");let a=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),s=vi(a,r);return this.fetchChunkForSampleIndex(s,e)}async fetchChunkForSampleIndex(t,e){if(t===-1)return null;let r=this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack),a=wi(r,t);if(!a)return null;let s;e.metadataOnly?s=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(a.chunkOffset,a.chunkOffset+a.chunkSize),s=this.internalTrack.demuxer.chunkReader.readRange(a.sampleOffset,a.sampleOffset+a.sampleSize));let n=1e6*a.presentationTimestamp/this.internalTrack.timescale,o=1e6*a.duration/this.internalTrack.timescale,c=this.createChunk(s,n,o,a.isKeyFrame);return this.chunkToSampleIndex.set(c,t),c}async fetchChunkInFragment(t,e,r){if(e===-1)return null;let s=t.trackData.get(this.internalTrack.id).samples[e];d(s);let n;r.metadataOnly?n=new Uint8Array(0):(await this.internalTrack.demuxer.chunkReader.reader.loadRange(t.dataStart,t.dataEnd),n=this.internalTrack.demuxer.chunkReader.readRange(s.byteOffset,s.byteOffset+s.byteSize));let o=1e6*s.presentationTimestamp/this.internalTrack.timescale,c=1e6*s.duration/this.internalTrack.timescale,u=this.createChunk(n,o,c,s.isKeyFrame);return this.chunkToFragmentLocation.set(u,{fragment:t,sampleIndex:e}),u}findSampleInFragmentsForTimestamp(t){let e=I(this.internalTrack.fragments,t,s=>s.trackData.get(this.internalTrack.id).startTimestamp),r=-1,a=!1;if(e!==-1){let n=this.internalTrack.fragments[e].trackData.get(this.internalTrack.id),o=I(n.presentationTimestamps,t,c=>c.presentationTimestamp);d(o!==-1),r=n.presentationTimestamps[o].sampleIndex,a=ts.trackData.get(this.internalTrack.id).startTimestamp),r=-1,a=!1;if(e!==-1){let n=this.internalTrack.fragments[e].trackData.get(this.internalTrack.id),o=Bt(n.presentationTimestamps,u=>n.samples[u.sampleIndex].isKeyFrame&&u.presentationTimestamp<=t);if(o===-1)throw new Error("Not supported: Fragment does not begin with a key sample.");r=n.presentationTimestamps[o].sampleIndex,a=tw.timestamp);k!==-1&&(p=this.internalTrack.fragmentLookupTable[k])}if(o===-1)m.pos=p?.moofOffset??0;else{let k=this.internalTrack.fragments[o];!p||k.moofOffset>=k.moofOffset?(m.pos=k.moofOffset+k.moofSize,f=k):m.pos=p.moofOffset}for(;m.posr)break;if(f.nextFragment){m.pos=f.nextFragment.moofOffset+f.nextFragment.moofSize,f=f.nextFragment;continue}}await m.reader.loadRange(m.pos,m.pos+16);let k=m.pos,w=m.readBoxHeader();if(w.name==="moof"){let v=W(s.fragments,k,T=>T.moofOffset);if(v===-1){m.pos=k;let T=await s.readFragment();f&&(f.nextFragment=T),f=T;let{fragmentIndex:A,sampleIndex:F,correctSampleFound:z}=t();if(z){let V=this.internalTrack.fragments[A];return this.fetchChunkInFragment(V,F,a)}A!==-1&&(g=A,b=F)}else{let T=s.fragments[v];f&&(f.nextFragment=T),f=T}}m.pos=k+w.totalSize}if(g!==-1){let k=this.internalTrack.fragments[g];return this.fetchChunkInFragment(k,b,a)}return null}finally{n()}}},_t=class extends Ke{constructor(t){super(t),this.internalTrack=t}async getCodec(){return this.internalTrack.info.codec}async getCodedWidth(){return this.internalTrack.info.width}async getCodedHeight(){return this.internalTrack.info.height}async getRotation(){return this.internalTrack.rotation}async getDecoderConfig(){return{codec:ir(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),codedWidth:this.internalTrack.info.width,codedHeight:this.internalTrack.info.height,description:this.internalTrack.info.codecDescription??void 0,colorSpace:this.internalTrack.info.colorSpace??void 0}}createChunk(t,e,r,a){return new EncodedVideoChunk({data:t,timestamp:e,duration:r,type:a?"key":"delta"})}},It=class extends Ke{constructor(t){super(t),this.internalTrack=t}async getCodec(){return this.internalTrack.info.codec}async getNumberOfChannels(){return this.internalTrack.info.numberOfChannels}async getSampleRate(){return this.internalTrack.info.sampleRate}async getDecoderConfig(){return{codec:ar(this.internalTrack.info.codec,this.internalTrack.info.codecDescription),numberOfChannels:this.internalTrack.info.numberOfChannels,sampleRate:this.internalTrack.info.sampleRate,description:this.internalTrack.info.codecDescription??void 0}}createChunk(t,e,r,a){return new EncodedAudioChunk({data:t,timestamp:e,duration:r,type:a?"key":"delta"})}},lr=(i,t)=>{let e=I(i.presentationTimestamps,t,r=>r.presentationTimestamp);return e===-1?-1:i.presentationTimestamps[e].sampleIndex},wi=(i,t)=>{let e=I(i.sampleTimingEntries,t,p=>p.startIndex),r=i.sampleTimingEntries[e];if(!r||r.startIndex+r.count<=t)return null;let s=r.startDecodeTimestamp+(t-r.startIndex)*r.delta,n=I(i.sampleCompositionTimeOffsets,t,p=>p.startIndex),o=i.sampleCompositionTimeOffsets[n];o&&(s+=o.offset);let c=i.sampleSizes[Math.min(t,i.sampleSizes.length-1)],u=I(i.sampleToChunk,t,p=>p.startSampleIndex),m=i.sampleToChunk[u];d(m);let l=m.startChunkIndex+Math.floor((t-m.startSampleIndex)/m.samplesPerChunk),f=i.chunkOffsets[l],g=0,b=f;if(i.sampleSizes.length===1)b+=c*(t-m.startSampleIndex),g+=c*m.samplesPerChunk;else{let p=m.startSampleIndex+(l-m.startChunkIndex)*m.samplesPerChunk;for(let k=p;kp)!==-1:!0}},yi=(i,t)=>{if(!i.keySampleIndices)return t;let e=I(i.keySampleIndices,t,r=>r);return i.keySampleIndices[e]??-1},vi=(i,t)=>{if(!i.keySampleIndices)return t+1;let e=I(i.keySampleIndices,t,r=>r);return i.keySampleIndices[e+1]??-1},fr=(i,t)=>{i.startTimestamp+=t,i.endTimestamp+=t;for(let e of i.samples)e.presentationTimestamp+=t;for(let e of i.presentationTimestamps)e.presentationTimestamp+=t};var we=class{},$e=class extends we{async _canReadInput(t){if(await t._mainReader.source._getSize()<8)return!1;let r=new J(t._mainReader);return r.pos=4,r.readAscii(4)==="ftyp"}_createDemuxer(t){return new Qe(t)}},je=class extends we{async _canReadInput(){return!1}_createDemuxer(){throw new Error("Not implemented")}},qe=new $e,_i=qe,Ii=qe,At=new je,pr=At,Ai=At,Ri=[qe,pr];var Rt=class{constructor(t){this._demuxerPromise=null;this._format=null;this._formats=t.formats,this._source=t.source,this._mainReader=new de(t.source)}_getDemuxer(){return this._demuxerPromise??=(async()=>{await this._mainReader.loadRange(0,4096);for(let t of this._formats)if(await t._canReadInput(this))return this._format=t,t._createDemuxer(this);throw new Error("Input has an unrecognizable format.")})()}async getFormat(){return await this._getDemuxer(),d(this._format),this._format}async computeDuration(){return(await this._getDemuxer()).computeDuration()}async getTracks(){return(await this._getDemuxer()).getTracks()}async getVideoTracks(){return(await this.getTracks()).filter(e=>e.isVideoTrack())}async getPrimaryVideoTrack(){return(await this.getTracks()).find(e=>e.isVideoTrack())??null}async getAudioTracks(){return(await this.getTracks()).filter(e=>e.isAudioTrack())}async getPrimaryAudioTrack(){return(await this.getTracks()).find(e=>e.isAudioTrack())??null}async getMimeType(){return(await this._getDemuxer()).getMimeType()}};var ye=class{async*chunks(t,e=1/0){let r=[],{promise:a,resolve:s}=E(),{promise:n,resolve:o}=E(),c=!1,u=[],m=()=>Math.max(2,u.length);(async()=>{let l=t??await this.getFirstChunk();for(;l&&!c&&!(l.timestamp/1e6>=e);){if(r.length>m()){({promise:n,resolve:o}=E()),await n;continue}r.push(l),s(),{promise:a,resolve:s}=E(),l=await this.getNextChunk(l)}c=!0,s()})();try{for(;;)if(r.length>0){yield r.shift();let l=performance.now();for(u.push(l);u.length>0&&l-u[0]>=1e3;)u.shift();o()}else if(!c)await a;else break}finally{c=!0,o()}}},ve=class{_duplicateFrame(t){return structuredClone(t)}async*mediaFramesAtTimestamps(t){let e=Wt(t),r=[],a=[],{promise:s,resolve:n}=E(),{promise:o,resolve:c}=E(),u=!1,m=!1,l=8,f=null,g=p=>{a.push(p),n(),{promise:s,resolve:n}=E()},b=await this._createDecoder(p=>{if(c(),m){p.close();return}let k=!1;for(;r.length>0&&r[0]===p.timestamp;)g(this._duplicateFrame(p)),r.shift(),k=!0;k?(f?.close(),f=p):p.close()});(async()=>{let p=this._createChunkDrain(),k=null,w=null;for await(let v of e){for(;a.length+b.decodeQueueSize>l;)({promise:o,resolve:c}=E()),await o;if(m)break;let T=await p.getChunk(v);if(!T){g(null);continue}let A=await p.getKeyChunk(v);if(!A){g(null);continue}for(r.push(T.timestamp),k&&A.timestamp===k.timestamp&&T.timestamp>=w.timestamp?(d(w),T.timestamp===w.timestamp&&r.length===1&&(f&&g(this._duplicateFrame(f)),r.shift())):(k=A,w=A,b.decode(A));w.timestamp!==T.timestamp;){let F=await p.getNextChunk(w);d(F),w=F,b.decode(F)}b.decodeQueueSize>=10&&await new Promise(F=>b.addEventListener("dequeue",F,{once:!0}))}await b.flush(),b.close(),u=!0,n()})();try{for(;;)if(a.length>0){let p=a.shift();d(p!==void 0),yield p,c()}else if(!u)await s;else break}finally{m=!0,c();for(let p of a)p?.close();f?.close()}}async*mediaFramesInRange(t=0,e=1/0){let r=[],a=!1,s=null,{promise:n,resolve:o}=E(),{promise:c,resolve:u}=E(),m=!1,l=!1,f=8,g=await this._createDecoder(k=>{u();let w=k.timestamp/1e6;if(w>=e&&(l=!0),l){k.close();return}s&&(w>t?(r.push(s),a=!0):s.close()),w>=t&&(r.push(k),a=!0),s=a?null:k,r.length>0&&(o(),{promise:n,resolve:o}=E())}),b=this._createChunkDrain(),p=await b.getKeyChunk(t)??await b.getFirstChunk();if(p){(async()=>{let k=p,w=1/0;if(e<1/0){let T=await b.getChunk(e),A=T?T.type==="key"&&T.timestamp/1e6===e?T:await b.getNextKeyChunk(T):null;A&&(w=A.timestamp/1e6)}let v=b.chunks(p,w);for(await v.next();k&&!l;){if(r.length+g.decodeQueueSize>f){({promise:c,resolve:u}=E()),await c;continue}g.decode(k);let T=await v.next();if(T.done)break;k=T.value}await v.return(),await g.flush(),g.close(),!a&&s&&r.push(s),m=!0,o()})();try{for(;;)if(r.length>0)yield r.shift(),u();else if(!m)await n;else break}finally{l=!0,u();for(let k of r)k.close()}}}},Xe=class extends ye{constructor(t){super(),this._videoTrack=t}getFirstChunk(t={}){return this._videoTrack._backing.getFirstChunk(t)}getChunk(t,e={}){return this._videoTrack._backing.getChunk(t,e)}getNextChunk(t,e={}){return this._videoTrack._backing.getNextChunk(t,e)}getKeyChunk(t,e={}){return this._videoTrack._backing.getKeyChunk(t,e)}getNextKeyChunk(t,e={}){return this._videoTrack._backing.getNextKeyChunk(t,e)}},Ge=class extends ve{constructor(e){super();this._decoderConfig=null;this._videoTrack=e}async _createDecoder(e){this._decoderConfig??=await this._videoTrack.getDecoderConfig();let r=new VideoDecoder({output:e,error:a=>console.error(a)});return r.configure(this._decoderConfig),r}_createChunkDrain(){return new Xe(this._videoTrack)}async getFrame(e){for await(let r of this.mediaFramesAtTimestamps([e]))return r;throw new Error("Internal error: Iterator returned nothing.")}frames(e=0,r=1/0){return this.mediaFramesInRange(e,r)}framesAtTimestamps(e){return this.mediaFramesAtTimestamps(e)}},Ot=class{constructor(t,e){this._videoTrack=t,this._dimensions=e,this._videoFrameDrain=new Ge(t)}async _videoFrameToWrappedCanvas(t){let e=this._dimensions?.width??await this._videoTrack.getDisplayWidth(),r=this._dimensions?.height??await this._videoTrack.getDisplayHeight(),a=await this._videoTrack.getRotation(),s=document.createElement("canvas");s.width=e,s.height=r;let n=s.getContext("2d",{alpha:!1});d(n),n.translate(e/2,r/2),n.rotate(a*Math.PI/180),n.translate(-e/2,-r/2);let[o,c]=a%180===0?[e,r]:[r,e];n.drawImage(t,(e-o)/2,(r-c)/2,o,c);let u={canvas:s,timestamp:t.timestamp/1e6,duration:(t.duration??0)/1e6};return t.close(),u}async getCanvas(t){let e=await this._videoFrameDrain.getFrame(t);return e&&this._videoFrameToWrappedCanvas(e)}async*canvases(t=0,e=1/0){for await(let r of this._videoFrameDrain.frames(t,e))yield this._videoFrameToWrappedCanvas(r)}async*canvasesAtTimestamps(t){for await(let e of this._videoFrameDrain.framesAtTimestamps(t))yield e&&this._videoFrameToWrappedCanvas(e)}},Ye=class extends ye{constructor(t){super(),this._audioTrack=t}getFirstChunk(t={}){return this._audioTrack._backing.getFirstChunk(t)}getChunk(t,e={}){return this._audioTrack._backing.getChunk(t,e)}getNextChunk(t,e={}){return this._audioTrack._backing.getNextChunk(t,e)}getKeyChunk(t,e={}){return this._audioTrack._backing.getKeyChunk(t,e)}getNextKeyChunk(t,e={}){return this._audioTrack._backing.getNextKeyChunk(t,e)}},Ze=class extends ve{constructor(e){super();this._decoderConfig=null;this._audioTrack=e}async _createDecoder(e){this._decoderConfig??=await this._audioTrack.getDecoderConfig();let r=new AudioDecoder({output:e,error:a=>console.error(a)});return r.configure(this._decoderConfig),r}_createChunkDrain(){return new Ye(this._audioTrack)}async getData(e){for await(let r of this.mediaFramesAtTimestamps([e]))return r;throw new Error("Internal error: Iterator returned nothing.")}data(e=0,r=1/0){return this.mediaFramesInRange(e,r)}dataAtTimestamps(e){return this.mediaFramesAtTimestamps(e)}},Et=class{constructor(t){this._audioDataDrain=new Ze(t)}_audioDataToWrappedArrayBuffer(t){let e=new AudioBuffer({numberOfChannels:t.numberOfChannels,length:t.numberOfFrames,sampleRate:t.sampleRate}),r=new Float32Array(t.allocationSize({planeIndex:0,format:"f32-planar"})/4);for(let n=0;n { return x instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && x instanceof SharedArrayBuffer || ArrayBuffer.isView(x) && !(x instanceof DataView); }; var AsyncMutex = class { - currentPromise = Promise.resolve(); + constructor() { + this.currentPromise = Promise.resolve(); + } async acquire() { let resolver; const nextPromise = new Promise((resolve) => { @@ -168,6 +170,14 @@ var removeItem = (arr, item) => { arr.splice(index, 1); } }; +var findLastIndex = (arr, predicate) => { + for (let i = arr.length - 1; i >= 0; i--) { + if (predicate(arr[i])) { + return i; + } + } + return -1; +}; var toAsyncIterator = async function* (source) { if (Symbol.iterator in source) { yield* source[Symbol.iterator](); @@ -181,10 +191,9 @@ var cueBlockHeaderRegex = /(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+(( var preambleStartRegex = /^WEBVTT(.|\n)*?\n{2}/; var inlineTimestampRegex = /<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g; var SubtitleParser = class { - options; - preambleText = null; - preambleEmitted = false; constructor(options) { + this.preambleText = null; + this.preambleEmitted = false; this.options = options; } parse(text) { @@ -261,14 +270,14 @@ var formatSubtitleTimestamp = (timestamp) => { var IsobmffBoxWriter = class { constructor(writer) { this.writer = writer; + this.helper = new Uint8Array(8); + this.helperView = new DataView(this.helper.buffer); + /** + * Stores the position from the start of the file to where boxes elements have been written. This is used to + * rewrite/edit elements that were already added before, and to measure sizes of things. + */ + this.offsets = /* @__PURE__ */ new WeakMap(); } - helper = new Uint8Array(8); - helperView = new DataView(this.helper.buffer); - /** - * Stores the position from the start of the file to where boxes elements have been written. This is used to - * rewrite/edit elements that were already added before, and to measure sizes of things. - */ - offsets = /* @__PURE__ */ new WeakMap(); writeU32(value) { this.helperView.setUint32(0, value, false); this.writer.write(this.helper.subarray(0, 4)); @@ -1143,9 +1152,9 @@ var SUBTITLE_CODEC_TO_CONFIGURATION_BOX = { // src/muxer.ts var Muxer = class { - output; - mutex = new AsyncMutex(); constructor(output) { + this.mutex = new AsyncMutex(); + this.trackTimestampInfo = /* @__PURE__ */ new WeakMap(); this.output = output; } // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -1154,7 +1163,6 @@ var Muxer = class { // eslint-disable-next-line @typescript-eslint/no-unused-vars onTrackClose(track) { } - trackTimestampInfo = /* @__PURE__ */ new WeakMap(); validateAndNormalizeTimestamp(track, rawTimestampInUs, isKeyFrame) { let timestampInSeconds = rawTimestampInUs / 1e6; let timestampInfo = this.trackTimestampInfo.get(track); @@ -1198,19 +1206,20 @@ var Muxer = class { // src/writer.ts var Writer = class { - /** Setting this to true will cause the writer to ensure data is written in a strictly monotonic, streamable way. */ - ensureMonotonicity = false; + constructor() { + /** Setting this to true will cause the writer to ensure data is written in a strictly monotonic, streamable way. */ + this.ensureMonotonicity = false; + } start() { } }; var ArrayBufferTargetWriter = class extends Writer { - pos = 0; - target; - buffer = new ArrayBuffer(2 ** 16); - bytes = new Uint8Array(this.buffer); - maxPos = 0; constructor(target) { super(); + this.pos = 0; + this.buffer = new ArrayBuffer(2 ** 16); + this.bytes = new Uint8Array(this.buffer); + this.maxPos = 0; this.target = target; } ensureSize(size) { @@ -1246,13 +1255,12 @@ var ArrayBufferTargetWriter = class extends Writer { } }; var StreamTargetWriter = class extends Writer { - pos = 0; - target; - sections = []; - lastFlushEnd = 0; - writer = null; constructor(target) { super(); + this.pos = 0; + this.sections = []; + this.lastFlushEnd = 0; + this.writer = null; this.target = target; } start() { @@ -1322,19 +1330,17 @@ var StreamTargetWriter = class extends Writer { var DEFAULT_CHUNK_SIZE = 2 ** 24; var MAX_CHUNKS_AT_ONCE = 2; var ChunkedStreamTargetWriter = class extends Writer { - pos = 0; - target; - chunkSize; - /** - * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out. - * A chunk is flushed if all of its contents have been written. - */ - chunks = []; - lastFlushEnd = 0; - writer = null; - flushedChunkQueue = []; constructor(target) { super(); + this.pos = 0; + /** + * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out. + * A chunk is flushed if all of its contents have been written. + */ + this.chunks = []; + this.lastFlushEnd = 0; + this.writer = null; + this.flushedChunkQueue = []; this.target = target; this.chunkSize = target._options?.chunkSize ?? DEFAULT_CHUNK_SIZE; if (!Number.isInteger(this.chunkSize) || this.chunkSize < 2 ** 10) { @@ -1452,21 +1458,22 @@ var ChunkedStreamTargetWriter = class extends Writer { // src/target.ts var Target = class { - /** @internal */ - _output = null; + constructor() { + /** @internal */ + this._output = null; + } }; var ArrayBufferTarget = class extends Target { - buffer = null; + constructor() { + super(...arguments); + this.buffer = null; + } /** @internal */ _createWriter() { return new ArrayBufferTargetWriter(this); } }; var StreamTarget = class extends Target { - /** @internal */ - _writable; - /** @internal */ - _options; constructor(writable, options = {}) { super(); if (!(writable instanceof WritableStream)) { @@ -2006,21 +2013,18 @@ var intoTimescale = (timeInSeconds, timescale, round = true) => { return round ? Math.round(value) : value; }; var IsobmffMuxer = class extends Muxer { - timestampsMustStartAtZero = true; - writer; - boxWriter; - fastStart; - auxTarget = new ArrayBufferTarget(); - auxWriter = this.auxTarget._createWriter(); - auxBoxWriter = new IsobmffBoxWriter(this.auxWriter); - ftypSize = null; - mdat = null; - trackDatas = []; - creationTime = Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET; - finalizedChunks = []; - nextFragmentNumber = 1; constructor(output, format) { super(output); + this.timestampsMustStartAtZero = true; + this.auxTarget = new ArrayBufferTarget(); + this.auxWriter = this.auxTarget._createWriter(); + this.auxBoxWriter = new IsobmffBoxWriter(this.auxWriter); + this.ftypSize = null; + this.mdat = null; + this.trackDatas = []; + this.creationTime = Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET; + this.finalizedChunks = []; + this.nextFragmentNumber = 1; this.writer = output._writer; this.boxWriter = new IsobmffBoxWriter(this.writer); const fastStartDefault = this.writer instanceof ArrayBufferTargetWriter ? "in-memory" : false; @@ -2609,19 +2613,16 @@ var IsobmffMuxer = class extends Muxer { // src/matroska/ebml.ts var EBMLFloat32 = class { - value; constructor(value) { this.value = value; } }; var EBMLFloat64 = class { - value; constructor(value) { this.value = value; } }; var EBMLSignedInt = class { - value; constructor(value) { this.value = value; } @@ -2695,31 +2696,29 @@ var TRACK_TYPE_MAP = { subtitle: 17 }; var MatroskaMuxer = class extends Muxer { - timestampsMustStartAtZero = false; - writer; - format; - helper = new Uint8Array(8); - helperView = new DataView(this.helper.buffer); - /** - * Stores the position from the start of the file to where EBML elements have been written. This is used to - * rewrite/edit elements that were already added before, and to measure sizes of things. - */ - offsets = /* @__PURE__ */ new WeakMap(); - /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */ - dataOffsets = /* @__PURE__ */ new WeakMap(); - trackDatas = []; - segment = null; - segmentInfo = null; - seekHead = null; - tracksElement = null; - segmentDuration = null; - cues = null; - currentCluster = null; - currentClusterMsTimestamp = null; - trackDatasInCurrentCluster = /* @__PURE__ */ new Set(); - duration = 0; constructor(output, format) { super(output); + this.timestampsMustStartAtZero = false; + this.helper = new Uint8Array(8); + this.helperView = new DataView(this.helper.buffer); + /** + * Stores the position from the start of the file to where EBML elements have been written. This is used to + * rewrite/edit elements that were already added before, and to measure sizes of things. + */ + this.offsets = /* @__PURE__ */ new WeakMap(); + /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */ + this.dataOffsets = /* @__PURE__ */ new WeakMap(); + this.trackDatas = []; + this.segment = null; + this.segmentInfo = null; + this.seekHead = null; + this.tracksElement = null; + this.segmentDuration = null; + this.cues = null; + this.currentCluster = null; + this.currentClusterMsTimestamp = null; + this.trackDatasInCurrentCluster = /* @__PURE__ */ new Set(); + this.duration = 0; this.writer = output._writer; this.format = format; if (this.format._options.streamable) { @@ -3394,8 +3393,6 @@ ${cue.notes ?? ""}`; var OutputFormat = class { }; var Mp4OutputFormat = class extends OutputFormat { - /** @internal */ - _options; constructor(options = {}) { if (!options || typeof options !== "object") { throw new TypeError("options must be an object."); @@ -3412,8 +3409,6 @@ var Mp4OutputFormat = class extends OutputFormat { } }; var MkvOutputFormat2 = class extends OutputFormat { - /** @internal */ - _options; constructor(options = {}) { if (!options || typeof options !== "object") { throw new TypeError("options must be an object."); @@ -3434,12 +3429,14 @@ var WebMOutputFormat = class extends MkvOutputFormat2 { // src/media-source.ts var MediaSource = class { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _closed = false; - /** @internal */ - _offsetTimestamps = false; + constructor() { + /** @internal */ + this._connectedTrack = null; + /** @internal */ + this._closed = false; + /** @internal */ + this._offsetTimestamps = false; + } /** @internal */ _ensureValidDigest() { if (!this._connectedTrack) { @@ -3479,12 +3476,10 @@ var MediaSource = class { } }; var VideoSource = class extends MediaSource { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _codec; constructor(codec) { super(); + /** @internal */ + this._connectedTrack = null; if (!VIDEO_CODECS.includes(codec)) { throw new TypeError(`Invalid video codec '${codec}'. Must be one of: ${VIDEO_CODECS.join(", ")}.`); } @@ -3522,13 +3517,13 @@ var VideoEncoderWrapper = class { constructor(source, codecConfig) { this.source = source; this.codecConfig = codecConfig; + this.encoder = null; + this.muxer = null; + this.lastMultipleOfKeyFrameInterval = -1; + this.lastWidth = null; + this.lastHeight = null; validateVideoCodecConfig(codecConfig); } - encoder = null; - muxer = null; - lastMultipleOfKeyFrameInterval = -1; - lastWidth = null; - lastHeight = null; async digest(videoFrame) { this.source._ensureValidDigest(); if (this.lastWidth !== null && this.lastHeight !== null) { @@ -3586,8 +3581,6 @@ var VideoEncoderWrapper = class { } }; var VideoFrameSource = class extends VideoSource { - /** @internal */ - _encoder; constructor(codecConfig) { super(codecConfig.codec); this._encoder = new VideoEncoderWrapper(this, codecConfig); @@ -3604,10 +3597,6 @@ var VideoFrameSource = class extends VideoSource { } }; var CanvasSource = class extends VideoSource { - /** @internal */ - _encoder; - /** @internal */ - _canvas; constructor(canvas, codecConfig) { if (!(canvas instanceof HTMLCanvasElement)) { throw new TypeError("canvas must be an HTMLCanvasElement."); @@ -3638,14 +3627,6 @@ var CanvasSource = class extends VideoSource { } }; var MediaStreamVideoTrackSource = class extends VideoSource { - /** @internal */ - _encoder; - /** @internal */ - _abortController = null; - /** @internal */ - _track; - /** @internal */ - _offsetTimestamps = true; constructor(track, codecConfig) { if (!(track instanceof MediaStreamTrack) || track.kind !== "video") { throw new TypeError("track must be a video MediaStreamTrack."); @@ -3655,6 +3636,10 @@ var MediaStreamVideoTrackSource = class extends VideoSource { latencyMode: "realtime" }; super(codecConfig.codec); + /** @internal */ + this._abortController = null; + /** @internal */ + this._offsetTimestamps = true; this._encoder = new VideoEncoderWrapper(this, codecConfig); this._track = track; } @@ -3685,12 +3670,10 @@ var MediaStreamVideoTrackSource = class extends VideoSource { } }; var AudioSource = class extends MediaSource { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _codec; constructor(codec) { super(); + /** @internal */ + this._connectedTrack = null; if (!AUDIO_CODECS.includes(codec)) { throw new TypeError(`Invalid audio codec '${codec}'. Must be one of: ${AUDIO_CODECS.join(", ")}.`); } @@ -3724,12 +3707,12 @@ var AudioEncoderWrapper = class { constructor(source, codecConfig) { this.source = source; this.codecConfig = codecConfig; + this.encoder = null; + this.muxer = null; + this.lastNumberOfChannels = null; + this.lastSampleRate = null; validateAudioCodecConfig(codecConfig); } - encoder = null; - muxer = null; - lastNumberOfChannels = null; - lastSampleRate = null; async digest(audioData) { this.source._ensureValidDigest(); if (this.lastNumberOfChannels !== null && this.lastSampleRate !== null) { @@ -3776,8 +3759,6 @@ var AudioEncoderWrapper = class { } }; var AudioDataSource = class extends AudioSource { - /** @internal */ - _encoder; constructor(codecConfig) { super(codecConfig.codec); this._encoder = new AudioEncoderWrapper(this, codecConfig); @@ -3794,12 +3775,10 @@ var AudioDataSource = class extends AudioSource { } }; var AudioBufferSource = class extends AudioSource { - /** @internal */ - _encoder; - /** @internal */ - _accumulatedFrameCount = 0; constructor(codecConfig) { super(codecConfig.codec); + /** @internal */ + this._accumulatedFrameCount = 0; this._encoder = new AudioEncoderWrapper(this, codecConfig); } digest(audioBuffer) { @@ -3833,19 +3812,15 @@ var AudioBufferSource = class extends AudioSource { } }; var MediaStreamAudioTrackSource = class extends AudioSource { - /** @internal */ - _encoder; - /** @internal */ - _abortController = null; - /** @internal */ - _track; - /** @internal */ - _offsetTimestamps = true; constructor(track, codecConfig) { if (!(track instanceof MediaStreamTrack) || track.kind !== "audio") { throw new TypeError("track must be an audio MediaStreamTrack."); } super(codecConfig.codec); + /** @internal */ + this._abortController = null; + /** @internal */ + this._offsetTimestamps = true; this._encoder = new AudioEncoderWrapper(this, codecConfig); this._track = track; } @@ -3876,12 +3851,10 @@ var MediaStreamAudioTrackSource = class extends AudioSource { } }; var SubtitleSource = class extends MediaSource { - /** @internal */ - _connectedTrack = null; - /** @internal */ - _codec; constructor(codec) { super(); + /** @internal */ + this._connectedTrack = null; if (!SUBTITLE_CODECS.includes(codec)) { throw new TypeError(`Invalid subtitle codec '${codec}'. Must be one of: ${SUBTITLE_CODECS.join(", ")}.`); } @@ -3889,8 +3862,6 @@ var SubtitleSource = class extends MediaSource { } }; var TextSubtitleSource = class extends SubtitleSource { - /** @internal */ - _parser; constructor(codec) { super(codec); this._parser = new SubtitleParser({ @@ -3911,19 +3882,15 @@ var TextSubtitleSource = class extends SubtitleSource { // src/output.ts var Output = class { - /** @internal */ - _muxer; - /** @internal */ - _writer; - /** @internal */ - _tracks = []; - /** @internal */ - _started = false; - /** @internal */ - _finalizing = false; - /** @internal */ - _mutex = new AsyncMutex(); constructor(options) { + /** @internal */ + this._tracks = []; + /** @internal */ + this._started = false; + /** @internal */ + this._finalizing = false; + /** @internal */ + this._mutex = new AsyncMutex(); if (!options || typeof options !== "object") { throw new TypeError("options must be an object."); } @@ -4029,8 +3996,10 @@ var Output = class { // src/source.ts var Source = class { - /** @internal */ - _sizePromise = null; + constructor() { + /** @internal */ + this._sizePromise = null; + } /** @internal */ _getSize() { return this._sizePromise ??= this._retrieveSize(); @@ -4039,37 +4008,36 @@ var Source = class { var ArrayBufferSource = class extends Source { constructor(buffer) { super(); - this.buffer = buffer; + this._buffer = buffer; } /** @internal */ async _read(start, end) { - return new Uint8Array(this.buffer, start, end - start); + return new Uint8Array(this._buffer, start, end - start); } /** @internal */ async _retrieveSize() { - return this.buffer.byteLength; + return this._buffer.byteLength; } }; var BlobSource = class extends Source { constructor(blob) { super(); - this.blob = blob; + this._blob = blob; } /** @internal */ async _read(start, end) { - const slice = this.blob.slice(start, end); + const slice = this._blob.slice(start, end); const buffer = await slice.arrayBuffer(); return new Uint8Array(buffer); } /** @internal */ async _retrieveSize() { - return this.blob.size; + return this._blob.size; } }; // src/demuxer.ts var Demuxer = class { - input; constructor(input) { this.input = input; } @@ -4077,8 +4045,6 @@ var Demuxer = class { // src/input-track.ts var InputTrack = class { - /** @internal */ - _backing; /** @internal */ constructor(backing) { this._backing = backing; @@ -4094,8 +4060,6 @@ var InputTrack = class { } }; var InputVideoTrack = class extends InputTrack { - /** @internal */ - _backing; /** @internal */ constructor(backing) { super(backing); @@ -4104,22 +4068,22 @@ var InputVideoTrack = class extends InputTrack { getCodec() { return this._backing.getCodec(); } - getWidth() { - return this._backing.getWidth(); + getCodedWidth() { + return this._backing.getCodedWidth(); } - getHeight() { - return this._backing.getHeight(); + getCodedHeight() { + return this._backing.getCodedHeight(); } getRotation() { return this._backing.getRotation(); } - async getRotatedWidth() { + async getDisplayWidth() { const rotation = await this._backing.getRotation(); - return rotation % 180 === 0 ? this._backing.getWidth() : this._backing.getHeight(); + return rotation % 180 === 0 ? this._backing.getCodedWidth() : this._backing.getCodedHeight(); } - async getRotatedHeight() { + async getDisplayHeight() { const rotation = await this._backing.getRotation(); - return rotation % 180 === 0 ? this._backing.getHeight() : this._backing.getWidth(); + return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth(); } getDecoderConfig() { return this._backing.getDecoderConfig(); @@ -4130,8 +4094,6 @@ var InputVideoTrack = class extends InputTrack { } }; var InputAudioTrack = class extends InputTrack { - /** @internal */ - _backing; /** @internal */ constructor(backing) { super(backing); @@ -4160,12 +4122,12 @@ var Reader = class { constructor(source, maxStorableBytes = Infinity) { this.source = source; this.maxStorableBytes = maxStorableBytes; + this.loadedSegments = []; + this.loadingSegments = []; + this.sourceSizePromise = null; + this.nextAge = 0; + this.totalStoredBytes = 0; } - loadedSegments = []; - loadingSegments = []; - sourceSizePromise = null; - nextAge = 0; - totalStoredBytes = 0; async loadRange(start, end) { end = Math.min(end, await this.source._getSize()); const matchingLoadingSegment = this.loadingSegments.find((x) => x.start <= start && x.end >= end); @@ -4268,8 +4230,8 @@ var Reader = class { var IsobmffReader = class { constructor(reader) { this.reader = reader; + this.pos = 0; } - pos = 0; readRange(start, end) { const { view: view2, offset } = this.reader.getViewAndOffset(start, end); return new Uint8Array(view2.buffer, offset, end - start); @@ -4359,20 +4321,18 @@ var IsobmffReader = class { // src/isobmff/isobmff-demuxer.ts var knownMatrixes = [rotationMatrix(0), rotationMatrix(90), rotationMatrix(180), rotationMatrix(270)]; var IsobmffDemuxer = class extends Demuxer { - isobmffReader; - currentTrack = null; - tracks = []; - metadataPromise = null; - movieTimescale = -1; - movieDurationInTimescale = -1; - isFragmented = false; - fragmentTrackDefaults = []; - fragments = []; - currentFragment = null; - fragmentLookupMutex = new AsyncMutex(); - chunkReader; constructor(input) { super(input); + this.currentTrack = null; + this.tracks = []; + this.metadataPromise = null; + this.movieTimescale = -1; + this.movieDurationInTimescale = -1; + this.isFragmented = false; + this.fragmentTrackDefaults = []; + this.fragments = []; + this.currentFragment = null; + this.fragmentLookupMutex = new AsyncMutex(); this.isobmffReader = new IsobmffReader(input._mainReader); this.chunkReader = new IsobmffReader(new Reader(input._source, 64 * 2 ** 20)); } @@ -5304,9 +5264,9 @@ var IsobmffDemuxer = class extends Demuxer { var IsobmffTrackBacking = class { constructor(internalTrack) { this.internalTrack = internalTrack; + this.chunkToSampleIndex = /* @__PURE__ */ new WeakMap(); + this.chunkToFragmentLocation = /* @__PURE__ */ new WeakMap(); } - chunkToSampleIndex = /* @__PURE__ */ new WeakMap(); - chunkToFragmentLocation = /* @__PURE__ */ new WeakMap(); getCodec() { throw new Error("Not implemented on base class."); } @@ -5579,7 +5539,7 @@ var IsobmffTrackBacking = class { if (fragmentIndex !== -1) { const fragment = this.internalTrack.fragments[fragmentIndex]; const trackData = fragment.trackData.get(this.internalTrack.id); - const index = trackData.presentationTimestamps.findLastIndex((x) => { + const index = findLastIndex(trackData.presentationTimestamps, (x) => { const sample = trackData.samples[x.sampleIndex]; return sample.isKeyFrame && x.presentationTimestamp <= timestampInTimescale; }); @@ -5679,7 +5639,6 @@ var IsobmffTrackBacking = class { } }; var IsobmffVideoTrackBacking = class extends IsobmffTrackBacking { - internalTrack; constructor(internalTrack) { super(internalTrack); this.internalTrack = internalTrack; @@ -5687,10 +5646,10 @@ var IsobmffVideoTrackBacking = class extends IsobmffTrackBacking { async getCodec() { return this.internalTrack.info.codec; } - async getWidth() { + async getCodedWidth() { return this.internalTrack.info.width; } - async getHeight() { + async getCodedHeight() { return this.internalTrack.info.height; } async getRotation() { @@ -5715,7 +5674,6 @@ var IsobmffVideoTrackBacking = class extends IsobmffTrackBacking { } }; var IsobmffAudioTrackBacking = class extends IsobmffTrackBacking { - internalTrack; constructor(internalTrack) { super(internalTrack); this.internalTrack = internalTrack; @@ -5830,10 +5788,6 @@ var offsetFragmentTrackDataByTimestamp = (trackData, timestamp) => { } }; -// src/matroska/matroska-demuxer.ts -var MatroskaDemuxer = class extends Demuxer { -}; - // src/input-format.ts var InputFormat = class { }; @@ -5849,6 +5803,7 @@ var IsobmffInputFormat = class extends InputFormat { const fourCc = isobmffReader.readAscii(4); return fourCc === "ftyp"; } + /** @internal */ _createDemuxer(input) { return new IsobmffDemuxer(input); } @@ -5858,8 +5813,9 @@ var MatroskaInputFormat = class extends InputFormat { async _canReadInput() { return false; } - _createDemuxer(input) { - return new MatroskaDemuxer(input); + /** @internal */ + _createDemuxer() { + throw new Error("Not implemented"); } }; var ISOBMFF = new IsobmffInputFormat(); @@ -5872,17 +5828,11 @@ var ALL_FORMATS = [ISOBMFF, MKV]; // src/input.ts var Input = class { - /** @internal */ - _source; - /** @internal */ - _formats; - /** @internal */ - _mainReader; - /** @internal */ - _demuxerPromise = null; - /** @internal */ - _format = null; constructor(options) { + /** @internal */ + this._demuxerPromise = null; + /** @internal */ + this._format = null; this._formats = options.formats; this._source = options.source; this._mainReader = new Reader(options.source); @@ -5987,7 +5937,8 @@ var BaseChunkDrain = class { } }; var BaseMediaFrameDrain = class { - duplicateFrame(frame) { + /** @internal */ + _duplicateFrame(frame) { return structuredClone(frame); } async *mediaFramesAtTimestamps(timestamps) { @@ -6005,7 +5956,7 @@ var BaseMediaFrameDrain = class { onQueueNotEmpty(); ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers()); }; - const decoder = await this.createDecoder((frame) => { + const decoder = await this._createDecoder((frame) => { onQueueDequeue(); if (ended) { frame.close(); @@ -6013,7 +5964,7 @@ var BaseMediaFrameDrain = class { } let frameUsed = false; while (timestampsOfInterest.length > 0 && timestampsOfInterest[0] === frame.timestamp) { - pushToQueue(this.duplicateFrame(frame)); + pushToQueue(this._duplicateFrame(frame)); timestampsOfInterest.shift(); frameUsed = true; } @@ -6025,7 +5976,7 @@ var BaseMediaFrameDrain = class { } }); void (async () => { - const chunkDrain = this.createChunkDrain(); + const chunkDrain = this._createChunkDrain(); let lastKeyChunk = null; let lastChunk = null; for await (const timestamp of timestampIterator) { @@ -6051,7 +6002,7 @@ var BaseMediaFrameDrain = class { assert(lastChunk); if (targetChunk.timestamp === lastChunk.timestamp && timestampsOfInterest.length === 1) { if (lastUsedFrame) { - pushToQueue(this.duplicateFrame(lastUsedFrame)); + pushToQueue(this._duplicateFrame(lastUsedFrame)); } timestampsOfInterest.shift(); } @@ -6106,7 +6057,7 @@ var BaseMediaFrameDrain = class { let decoderIsFlushed = false; let ended = false; const MAX_QUEUE_SIZE = 8; - const decoder = await this.createDecoder((frame) => { + const decoder = await this._createDecoder((frame) => { onQueueDequeue(); const frameTimestamp = frame.timestamp / 1e6; if (frameTimestamp >= endTimestamp) { @@ -6134,7 +6085,7 @@ var BaseMediaFrameDrain = class { ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers()); } }); - const chunkDrain = this.createChunkDrain(); + const chunkDrain = this._createChunkDrain(); const keyChunk = await chunkDrain.getKeyChunk(startTimestamp) ?? await chunkDrain.getFirstChunk(); if (!keyChunk) { return; @@ -6196,41 +6147,44 @@ var BaseMediaFrameDrain = class { var EncodedVideoChunkDrain = class extends BaseChunkDrain { constructor(videoTrack) { super(); - this.videoTrack = videoTrack; + this._videoTrack = videoTrack; } getFirstChunk(options = {}) { - return this.videoTrack._backing.getFirstChunk(options); + return this._videoTrack._backing.getFirstChunk(options); } getChunk(timestamp, options = {}) { - return this.videoTrack._backing.getChunk(timestamp, options); + return this._videoTrack._backing.getChunk(timestamp, options); } getNextChunk(chunk, options = {}) { - return this.videoTrack._backing.getNextChunk(chunk, options); + return this._videoTrack._backing.getNextChunk(chunk, options); } getKeyChunk(timestamp, options = {}) { - return this.videoTrack._backing.getKeyChunk(timestamp, options); + return this._videoTrack._backing.getKeyChunk(timestamp, options); } getNextKeyChunk(chunk, options = {}) { - return this.videoTrack._backing.getNextKeyChunk(chunk, options); + return this._videoTrack._backing.getNextKeyChunk(chunk, options); } }; var VideoFrameDrain = class extends BaseMediaFrameDrain { constructor(videoTrack) { super(); - this.videoTrack = videoTrack; + /** @internal */ + this._decoderConfig = null; + this._videoTrack = videoTrack; } - decoderConfig = null; - async createDecoder(onFrame) { - this.decoderConfig ??= await this.videoTrack.getDecoderConfig(); + /** @internal */ + async _createDecoder(onFrame) { + this._decoderConfig ??= await this._videoTrack.getDecoderConfig(); const decoder = new VideoDecoder({ output: onFrame, error: (error) => console.error(error) }); - decoder.configure(this.decoderConfig); + decoder.configure(this._decoderConfig); return decoder; } - createChunkDrain() { - return new EncodedVideoChunkDrain(this.videoTrack); + /** @internal */ + _createChunkDrain() { + return new EncodedVideoChunkDrain(this._videoTrack); } async getFrame(timestamp) { for await (const frame of this.mediaFramesAtTimestamps([timestamp])) { @@ -6247,15 +6201,15 @@ var VideoFrameDrain = class extends BaseMediaFrameDrain { }; var CanvasDrain = class { constructor(videoTrack, dimensions) { - this.videoTrack = videoTrack; - this.dimensions = dimensions; - this.videoFrameDrain = new VideoFrameDrain(videoTrack); + this._videoTrack = videoTrack; + this._dimensions = dimensions; + this._videoFrameDrain = new VideoFrameDrain(videoTrack); } - videoFrameDrain; - async videoFrameToWrappedCanvas(frame) { - const width = this.dimensions?.width ?? await this.videoTrack.getRotatedWidth(); - const height = this.dimensions?.height ?? await this.videoTrack.getRotatedHeight(); - const rotation = await this.videoTrack.getRotation(); + /** @internal */ + async _videoFrameToWrappedCanvas(frame) { + const width = this._dimensions?.width ?? await this._videoTrack.getDisplayWidth(); + const height = this._dimensions?.height ?? await this._videoTrack.getDisplayHeight(); + const rotation = await this._videoTrack.getRotation(); const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; @@ -6275,58 +6229,61 @@ var CanvasDrain = class { return result; } async getCanvas(timestamp) { - const frame = await this.videoFrameDrain.getFrame(timestamp); - return frame && this.videoFrameToWrappedCanvas(frame); + const frame = await this._videoFrameDrain.getFrame(timestamp); + return frame && this._videoFrameToWrappedCanvas(frame); } async *canvases(startTimestamp = 0, endTimestamp = Infinity) { - for await (const frame of this.videoFrameDrain.frames(startTimestamp, endTimestamp)) { - yield this.videoFrameToWrappedCanvas(frame); + for await (const frame of this._videoFrameDrain.frames(startTimestamp, endTimestamp)) { + yield this._videoFrameToWrappedCanvas(frame); } } async *canvasesAtTimestamps(timestamps) { - for await (const frame of this.videoFrameDrain.framesAtTimestamps(timestamps)) { - yield frame && this.videoFrameToWrappedCanvas(frame); + for await (const frame of this._videoFrameDrain.framesAtTimestamps(timestamps)) { + yield frame && this._videoFrameToWrappedCanvas(frame); } } }; var EncodedAudioChunkDrain = class extends BaseChunkDrain { constructor(audioTrack) { super(); - this.audioTrack = audioTrack; + this._audioTrack = audioTrack; } getFirstChunk(options = {}) { - return this.audioTrack._backing.getFirstChunk(options); + return this._audioTrack._backing.getFirstChunk(options); } getChunk(timestamp, options = {}) { - return this.audioTrack._backing.getChunk(timestamp, options); + return this._audioTrack._backing.getChunk(timestamp, options); } getNextChunk(chunk, options = {}) { - return this.audioTrack._backing.getNextChunk(chunk, options); + return this._audioTrack._backing.getNextChunk(chunk, options); } getKeyChunk(timestamp, options = {}) { - return this.audioTrack._backing.getKeyChunk(timestamp, options); + return this._audioTrack._backing.getKeyChunk(timestamp, options); } getNextKeyChunk(chunk, options = {}) { - return this.audioTrack._backing.getNextKeyChunk(chunk, options); + return this._audioTrack._backing.getNextKeyChunk(chunk, options); } }; var AudioDataDrain = class extends BaseMediaFrameDrain { constructor(audioTrack) { super(); - this.audioTrack = audioTrack; + /** @internal */ + this._decoderConfig = null; + this._audioTrack = audioTrack; } - decoderConfig = null; - async createDecoder(onData) { - this.decoderConfig ??= await this.audioTrack.getDecoderConfig(); + /** @internal */ + async _createDecoder(onData) { + this._decoderConfig ??= await this._audioTrack.getDecoderConfig(); const decoder = new AudioDecoder({ output: onData, error: (error) => console.error(error) }); - decoder.configure(this.decoderConfig); + decoder.configure(this._decoderConfig); return decoder; } - createChunkDrain() { - return new EncodedAudioChunkDrain(this.audioTrack); + /** @internal */ + _createChunkDrain() { + return new EncodedAudioChunkDrain(this._audioTrack); } async getData(timestamp) { for await (const data of this.mediaFramesAtTimestamps([timestamp])) { @@ -6343,11 +6300,10 @@ var AudioDataDrain = class extends BaseMediaFrameDrain { }; var AudioBufferDrain = class { constructor(audioTrack) { - this.audioTrack = audioTrack; - this.audioDataDrain = new AudioDataDrain(audioTrack); + this._audioDataDrain = new AudioDataDrain(audioTrack); } - audioDataDrain; - audioDataToWrappedArrayBuffer(data) { + /** @internal */ + _audioDataToWrappedArrayBuffer(data) { const audioBuffer = new AudioBuffer({ numberOfChannels: data.numberOfChannels, length: data.numberOfFrames, @@ -6368,17 +6324,17 @@ var AudioBufferDrain = class { return result; } async getBuffer(timestamp) { - const data = await this.audioDataDrain.getData(timestamp); - return data && this.audioDataToWrappedArrayBuffer(data); + const data = await this._audioDataDrain.getData(timestamp); + return data && this._audioDataToWrappedArrayBuffer(data); } async *buffers(startTimestamp = 0, endTimestamp = Infinity) { - for await (const data of this.audioDataDrain.data(startTimestamp, endTimestamp)) { - yield this.audioDataToWrappedArrayBuffer(data); + for await (const data of this._audioDataDrain.data(startTimestamp, endTimestamp)) { + yield this._audioDataToWrappedArrayBuffer(data); } } async *buffersAtTimestamps(timestamps) { - for await (const data of this.audioDataDrain.dataAtTimestamps(timestamps)) { - yield data && this.audioDataToWrappedArrayBuffer(data); + for await (const data of this._audioDataDrain.dataAtTimestamps(timestamps)) { + yield data && this._audioDataToWrappedArrayBuffer(data); } } }; @@ -6392,6 +6348,8 @@ export { AudioDataDrain, AudioDataSource, AudioSource, + BaseChunkDrain, + BaseMediaFrameDrain, BlobSource, CanvasDrain, CanvasSource, @@ -6401,10 +6359,16 @@ export { EncodedVideoChunkSource, ISOBMFF, Input, + InputAudioTrack, + InputFormat, + InputTrack, + InputVideoTrack, + IsobmffInputFormat, MATROSKA, MKV, MOV, MP4, + MatroskaInputFormat, MediaSource, MediaStreamAudioTrackSource, MediaStreamVideoTrackSource, diff --git a/src/index.ts b/src/index.ts index 38f6b41..e7758ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,19 +32,37 @@ export { AudioCodec, SUBTITLE_CODECS, SubtitleCodec, + MediaCodec, } from './codec'; export { Target, ArrayBufferTarget, StreamTarget, StreamTargetChunk, StreamTargetOptions } from './target'; -export { TransformationMatrix } from './misc'; +export { Rotation, TransformationMatrix, AnyIterable } from './misc'; export { Source, ArrayBufferSource, BlobSource } from './source'; -export { ALL_FORMATS, ISOBMFF, MP4, MOV, MATROSKA, MKV, WEBM } from './input-format'; -export { Input, InputOptions } from './input'; export { + InputFormat, + IsobmffInputFormat, + MatroskaInputFormat, + ALL_FORMATS, + ISOBMFF, + MP4, + MOV, + MATROSKA, + MKV, + WEBM, +} from './input-format'; +export { Input, InputOptions } from './input'; +export { InputTrack, InputVideoTrack, InputAudioTrack } from './input-track'; +export { + ChunkRetrievalOptions, + BaseChunkDrain, + BaseMediaFrameDrain, EncodedVideoChunkDrain, VideoFrameDrain, EncodedAudioChunkDrain, CanvasDrain, + WrappedCanvas, AudioDataDrain, AudioBufferDrain, + WrappedAudioBuffer, } from './media-drain'; // 🐡🦔 diff --git a/src/input-format.ts b/src/input-format.ts index cd7f15f..8cc9bce 100644 --- a/src/input-format.ts +++ b/src/input-format.ts @@ -2,8 +2,8 @@ import { Demuxer } from './demuxer'; import { Input } from './input'; import { IsobmffDemuxer } from './isobmff/isobmff-demuxer'; import { IsobmffReader } from './isobmff/isobmff-reader'; -import { MatroskaDemuxer } from './matroska/matroska-demuxer'; +/** @public */ export abstract class InputFormat { /** @internal */ abstract _canReadInput(input: Input): Promise; @@ -12,7 +12,8 @@ export abstract class InputFormat { abstract _createDemuxer(input: Input): Demuxer; } -class IsobmffInputFormat extends InputFormat { +/** @public */ +export class IsobmffInputFormat extends InputFormat { /** @internal */ override async _canReadInput(input: Input) { const sourceSize = await input._mainReader.source._getSize(); @@ -27,27 +28,37 @@ class IsobmffInputFormat extends InputFormat { return fourCc === 'ftyp'; } + /** @internal */ override _createDemuxer(input: Input) { return new IsobmffDemuxer(input); } } -class MatroskaInputFormat extends InputFormat { +/** @public */ +export class MatroskaInputFormat extends InputFormat { /** @internal */ override async _canReadInput() { return false; // TODO } - override _createDemuxer(input: Input) { - return new MatroskaDemuxer(input); + /** @internal */ + override _createDemuxer(): never { + throw new Error('Not implemented'); } } +/** @public */ export const ISOBMFF = new IsobmffInputFormat(); +/** @public */ export const MP4 = ISOBMFF; +/** @public */ export const MOV = ISOBMFF; +/** @public */ export const MATROSKA = new MatroskaInputFormat(); +/** @public */ export const MKV = MATROSKA; +/** @public */ export const WEBM = MATROSKA; +/** @public */ export const ALL_FORMATS: InputFormat[] = [ISOBMFF, MKV]; diff --git a/src/input-track.ts b/src/input-track.ts index 06c6361..f4621fd 100644 --- a/src/input-track.ts +++ b/src/input-track.ts @@ -1,4 +1,5 @@ import { AudioCodec, MediaCodec, VideoCodec } from './codec'; +import { ChunkRetrievalOptions } from './media-drain'; import { Rotation } from './misc'; export interface InputTrackBacking { @@ -6,6 +7,7 @@ export interface InputTrackBacking { computeDuration(): Promise; } +/** @public */ export abstract class InputTrack { /** @internal */ _backing: InputTrackBacking; @@ -31,14 +33,10 @@ export abstract class InputTrack { } } -export type ChunkRetrievalOptions = { - metadataOnly?: boolean; -}; - export interface InputVideoTrackBacking extends InputTrackBacking { getCodec(): Promise; - getWidth(): Promise; - getHeight(): Promise; + getCodedWidth(): Promise; + getCodedHeight(): Promise; getRotation(): Promise; getDecoderConfig(): Promise; getFirstChunk(options: ChunkRetrievalOptions): Promise; @@ -48,6 +46,7 @@ export interface InputVideoTrackBacking extends InputTrackBacking { getNextKeyChunk(chunk: EncodedVideoChunk, options: ChunkRetrievalOptions): Promise; } +/** @public */ export class InputVideoTrack extends InputTrack { /** @internal */ override _backing: InputVideoTrackBacking; @@ -63,26 +62,26 @@ export class InputVideoTrack extends InputTrack { return this._backing.getCodec(); } - getWidth() { - return this._backing.getWidth(); + getCodedWidth() { + return this._backing.getCodedWidth(); } - getHeight() { - return this._backing.getHeight(); + getCodedHeight() { + return this._backing.getCodedHeight(); } getRotation() { return this._backing.getRotation(); } - async getRotatedWidth() { + async getDisplayWidth() { const rotation = await this._backing.getRotation(); - return rotation % 180 === 0 ? this._backing.getWidth() : this._backing.getHeight(); + return rotation % 180 === 0 ? this._backing.getCodedWidth() : this._backing.getCodedHeight(); } - async getRotatedHeight() { + async getDisplayHeight() { const rotation = await this._backing.getRotation(); - return rotation % 180 === 0 ? this._backing.getHeight() : this._backing.getWidth(); + return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth(); } getDecoderConfig() { @@ -107,6 +106,7 @@ export interface InputAudioTrackBacking extends InputTrackBacking { getNextKeyChunk(chunk: EncodedAudioChunk, options: ChunkRetrievalOptions): Promise; } +/** @public */ export class InputAudioTrack extends InputTrack { /** @internal */ override _backing: InputAudioTrackBacking; diff --git a/src/input.ts b/src/input.ts index 837ac04..26efeba 100644 --- a/src/input.ts +++ b/src/input.ts @@ -4,11 +4,13 @@ import { assert } from './misc'; import { Reader } from './reader'; import { Source } from './source'; +/** @public */ export type InputOptions = { formats: InputFormat[]; source: Source; }; +/** @public */ export class Input { /** @internal */ _source: Source; diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts index e03f415..32f59bb 100644 --- a/src/isobmff/isobmff-demuxer.ts +++ b/src/isobmff/isobmff-demuxer.ts @@ -9,7 +9,6 @@ import { import { Demuxer } from '../demuxer'; import { Input } from '../input'; import { - ChunkRetrievalOptions, InputAudioTrack, InputAudioTrackBacking, InputTrack, @@ -17,6 +16,7 @@ import { InputVideoTrack, InputVideoTrackBacking, } from '../input-track'; +import { ChunkRetrievalOptions } from '../media-drain'; import { assert, COLOR_PRIMARIES_MAP_INVERSE, @@ -28,6 +28,7 @@ import { Rotation, last, AsyncMutex, + findLastIndex, } from '../misc'; import { Reader } from '../reader'; import { IsobmffReader } from './isobmff-reader'; @@ -1654,7 +1655,7 @@ abstract class IsobmffTrackBacking { + const index = findLastIndex(trackData.presentationTimestamps, (x) => { const sample = trackData.samples[x.sampleIndex]!; return sample.isKeyFrame && x.presentationTimestamp <= timestampInTimescale; }); @@ -1805,11 +1806,11 @@ class IsobmffVideoTrackBacking extends IsobmffTrackBacking im return this.internalTrack.info.codec!; } - async getWidth() { + async getCodedWidth() { return this.internalTrack.info.width; } - async getHeight() { + async getCodedHeight() { return this.internalTrack.info.height; } diff --git a/src/matroska/matroska-demuxer.ts b/src/matroska/matroska-demuxer.ts deleted file mode 100644 index 7dab093..0000000 --- a/src/matroska/matroska-demuxer.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Demuxer } from '../demuxer'; -import { Input } from '../input'; - -export class MatroskaDemuxer extends Demuxer { - -} diff --git a/src/media-drain.ts b/src/media-drain.ts index 313af6e..8ef5332 100644 --- a/src/media-drain.ts +++ b/src/media-drain.ts @@ -1,7 +1,13 @@ -import { ChunkRetrievalOptions, InputAudioTrack, InputVideoTrack } from './input-track'; +import { InputAudioTrack, InputVideoTrack } from './input-track'; import { AnyIterable, assert, promiseWithResolvers, toAsyncIterator } from './misc'; -abstract class BaseChunkDrain { +/** @public */ +export type ChunkRetrievalOptions = { + metadataOnly?: boolean; +}; + +/** @public */ +export abstract class BaseChunkDrain { abstract getFirstChunk(options?: ChunkRetrievalOptions): Promise; abstract getChunk(timestamp: number, options?: ChunkRetrievalOptions): Promise; abstract getNextChunk(chunk: Chunk, options?: ChunkRetrievalOptions): Promise; @@ -71,14 +77,18 @@ abstract class BaseChunkDrain { - abstract createDecoder(onMedia: (media: MediaFrame) => unknown): Promise; - abstract createChunkDrain(): BaseChunkDrain; + /** @internal */ + abstract _createDecoder(onMedia: (media: MediaFrame) => unknown): Promise; + /** @internal */ + abstract _createChunkDrain(): BaseChunkDrain; - private duplicateFrame(frame: MediaFrame) { + /** @internal */ + private _duplicateFrame(frame: MediaFrame) { return structuredClone(frame); } @@ -101,7 +111,7 @@ abstract class BaseMediaFrameDrain< ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers()); }; - const decoder = await this.createDecoder((frame) => { + const decoder = await this._createDecoder((frame) => { onQueueDequeue(); if (ended) { @@ -111,7 +121,7 @@ abstract class BaseMediaFrameDrain< let frameUsed = false; while (timestampsOfInterest.length > 0 && timestampsOfInterest[0] === frame.timestamp) { - pushToQueue(this.duplicateFrame(frame)); + pushToQueue(this._duplicateFrame(frame)); timestampsOfInterest.shift(); frameUsed = true; } @@ -126,7 +136,7 @@ abstract class BaseMediaFrameDrain< // The following is the "pump" process that keeps pumping chunks into the decoder void (async () => { - const chunkDrain = this.createChunkDrain(); + const chunkDrain = this._createChunkDrain(); let lastKeyChunk: Chunk | null = null; let lastChunk: Chunk | null = null; @@ -165,7 +175,7 @@ abstract class BaseMediaFrameDrain< // Special case: We have a repeat chunk, but the frame for that chunk has already been decoded. // Therefore, we need to push the frame here instead of in the decoder callback. if (lastUsedFrame) { - pushToQueue(this.duplicateFrame(lastUsedFrame)); + pushToQueue(this._duplicateFrame(lastUsedFrame)); } timestampsOfInterest.shift(); } @@ -230,7 +240,7 @@ abstract class BaseMediaFrameDrain< const MAX_QUEUE_SIZE = 8; - const decoder = await this.createDecoder((frame) => { + const decoder = await this._createDecoder((frame) => { onQueueDequeue(); const frameTimestamp = frame.timestamp / 1e6; @@ -269,7 +279,7 @@ abstract class BaseMediaFrameDrain< } }); - const chunkDrain = this.createChunkDrain(); + const chunkDrain = this._createChunkDrain(); const keyChunk = await chunkDrain.getKeyChunk(startTimestamp) ?? await chunkDrain.getFirstChunk(); if (!keyChunk) { return; @@ -352,53 +362,67 @@ abstract class BaseMediaFrameDrain< } } +/** @public */ export class EncodedVideoChunkDrain extends BaseChunkDrain { - constructor(public videoTrack: InputVideoTrack) { + /** @internal */ + _videoTrack: InputVideoTrack; + + constructor(videoTrack: InputVideoTrack) { super(); + + this._videoTrack = videoTrack; } getFirstChunk(options: ChunkRetrievalOptions = {}) { - return this.videoTrack._backing.getFirstChunk(options); + return this._videoTrack._backing.getFirstChunk(options); } getChunk(timestamp: number, options: ChunkRetrievalOptions = {}) { - return this.videoTrack._backing.getChunk(timestamp, options); + return this._videoTrack._backing.getChunk(timestamp, options); } getNextChunk(chunk: EncodedVideoChunk, options: ChunkRetrievalOptions = {}) { - return this.videoTrack._backing.getNextChunk(chunk, options); + return this._videoTrack._backing.getNextChunk(chunk, options); } getKeyChunk(timestamp: number, options: ChunkRetrievalOptions = {}) { - return this.videoTrack._backing.getKeyChunk(timestamp, options); + return this._videoTrack._backing.getKeyChunk(timestamp, options); } getNextKeyChunk(chunk: EncodedVideoChunk, options: ChunkRetrievalOptions = {}) { - return this.videoTrack._backing.getNextKeyChunk(chunk, options); + return this._videoTrack._backing.getNextKeyChunk(chunk, options); } } +/** @public */ export class VideoFrameDrain extends BaseMediaFrameDrain { - decoderConfig: VideoDecoderConfig | null = null; + /** @internal */ + _videoTrack: InputVideoTrack; + /** @internal */ + _decoderConfig: VideoDecoderConfig | null = null; - constructor(public videoTrack: InputVideoTrack) { + constructor(videoTrack: InputVideoTrack) { super(); + + this._videoTrack = videoTrack; } - async createDecoder(onFrame: (frame: VideoFrame) => unknown) { - this.decoderConfig ??= await this.videoTrack.getDecoderConfig(); + /** @internal */ + async _createDecoder(onFrame: (frame: VideoFrame) => unknown) { + this._decoderConfig ??= await this._videoTrack.getDecoderConfig(); const decoder = new VideoDecoder({ output: onFrame, error: error => console.error(error), }); - decoder.configure(this.decoderConfig); + decoder.configure(this._decoderConfig); return decoder; } - createChunkDrain() { - return new EncodedVideoChunkDrain(this.videoTrack); + /** @internal */ + _createChunkDrain() { + return new EncodedVideoChunkDrain(this._videoTrack); } async getFrame(timestamp: number) { @@ -417,23 +441,33 @@ export class VideoFrameDrain extends BaseMediaFrameDrain { - const width = this.dimensions?.width ?? await this.videoTrack.getRotatedWidth(); - const height = this.dimensions?.height ?? await this.videoTrack.getRotatedHeight(); - const rotation = await this.videoTrack.getRotation(); + /** @internal */ + async _videoFrameToWrappedCanvas(frame: VideoFrame): Promise { + const width = this._dimensions?.width ?? await this._videoTrack.getDisplayWidth(); + const height = this._dimensions?.height ?? await this._videoTrack.getDisplayHeight(); + const rotation = await this._videoTrack.getRotation(); const canvas = document.createElement('canvas'); canvas.width = width; @@ -461,70 +495,84 @@ export class CanvasDrain { } async getCanvas(timestamp: number) { - const frame = await this.videoFrameDrain.getFrame(timestamp); - return frame && this.videoFrameToWrappedCanvas(frame); + const frame = await this._videoFrameDrain.getFrame(timestamp); + return frame && this._videoFrameToWrappedCanvas(frame); } async* canvases(startTimestamp = 0, endTimestamp = Infinity) { - for await (const frame of this.videoFrameDrain.frames(startTimestamp, endTimestamp)) { - yield this.videoFrameToWrappedCanvas(frame); + for await (const frame of this._videoFrameDrain.frames(startTimestamp, endTimestamp)) { + yield this._videoFrameToWrappedCanvas(frame); } } async* canvasesAtTimestamps(timestamps: AnyIterable) { - for await (const frame of this.videoFrameDrain.framesAtTimestamps(timestamps)) { - yield frame && this.videoFrameToWrappedCanvas(frame); + for await (const frame of this._videoFrameDrain.framesAtTimestamps(timestamps)) { + yield frame && this._videoFrameToWrappedCanvas(frame); } } } +/** @public */ export class EncodedAudioChunkDrain extends BaseChunkDrain { - constructor(public audioTrack: InputAudioTrack) { + /** @internal */ + _audioTrack: InputAudioTrack; + + constructor(audioTrack: InputAudioTrack) { super(); + + this._audioTrack = audioTrack; } getFirstChunk(options: ChunkRetrievalOptions = {}) { - return this.audioTrack._backing.getFirstChunk(options); + return this._audioTrack._backing.getFirstChunk(options); } getChunk(timestamp: number, options: ChunkRetrievalOptions = {}) { - return this.audioTrack._backing.getChunk(timestamp, options); + return this._audioTrack._backing.getChunk(timestamp, options); } getNextChunk(chunk: EncodedAudioChunk, options: ChunkRetrievalOptions = {}) { - return this.audioTrack._backing.getNextChunk(chunk, options); + return this._audioTrack._backing.getNextChunk(chunk, options); } getKeyChunk(timestamp: number, options: ChunkRetrievalOptions = {}) { - return this.audioTrack._backing.getKeyChunk(timestamp, options); + return this._audioTrack._backing.getKeyChunk(timestamp, options); } getNextKeyChunk(chunk: EncodedAudioChunk, options: ChunkRetrievalOptions = {}) { - return this.audioTrack._backing.getNextKeyChunk(chunk, options); + return this._audioTrack._backing.getNextKeyChunk(chunk, options); } } +/** @public */ export class AudioDataDrain extends BaseMediaFrameDrain { - decoderConfig: AudioDecoderConfig | null = null; + /** @internal */ + _audioTrack: InputAudioTrack; + /** @internal */ + _decoderConfig: AudioDecoderConfig | null = null; - constructor(public audioTrack: InputAudioTrack) { + constructor(audioTrack: InputAudioTrack) { super(); + + this._audioTrack = audioTrack; } - async createDecoder(onData: (data: AudioData) => unknown) { - this.decoderConfig ??= await this.audioTrack.getDecoderConfig(); + /** @internal */ + async _createDecoder(onData: (data: AudioData) => unknown) { + this._decoderConfig ??= await this._audioTrack.getDecoderConfig(); const decoder = new AudioDecoder({ output: onData, error: error => console.error(error), }); - decoder.configure(this.decoderConfig); + decoder.configure(this._decoderConfig); return decoder; } - createChunkDrain() { - return new EncodedAudioChunkDrain(this.audioTrack); + /** @internal */ + _createChunkDrain() { + return new EncodedAudioChunkDrain(this._audioTrack); } async getData(timestamp: number) { @@ -543,19 +591,23 @@ export class AudioDataDrain extends BaseMediaFrameDrain) { - for await (const data of this.audioDataDrain.dataAtTimestamps(timestamps)) { - yield data && this.audioDataToWrappedArrayBuffer(data); + for await (const data of this._audioDataDrain.dataAtTimestamps(timestamps)) { + yield data && this._audioDataToWrappedArrayBuffer(data); } } } diff --git a/src/misc.ts b/src/misc.ts index d771a72..8a47b3f 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -4,6 +4,7 @@ export function assert(x: unknown): asserts x { } } +/** @public */ export type Rotation = 0 | 90 | 180 | 270; /** @public */ @@ -214,6 +215,17 @@ export const removeItem = (arr: T[], item: T) => { } }; +export const findLastIndex = (arr: T[], predicate: (x: T) => boolean) => { + for (let i = arr.length - 1; i >= 0; i--) { + if (predicate(arr[i]!)) { + return i; + } + } + + return -1; +}; + +/** @public */ export type AnyIterable = | Iterable | AsyncIterable; diff --git a/src/source.ts b/src/source.ts index ebad958..6aa3bf6 100644 --- a/src/source.ts +++ b/src/source.ts @@ -1,3 +1,4 @@ +/** @public */ export abstract class Source { /** @internal */ abstract _read(start: number, end: number): Promise; @@ -13,36 +14,48 @@ export abstract class Source { } } +/** @public */ export class ArrayBufferSource extends Source { - constructor(private buffer: ArrayBuffer) { + /** @internal */ + _buffer: ArrayBuffer; + + constructor(buffer: ArrayBuffer) { super(); + + this._buffer = buffer; } /** @internal */ override async _read(start: number, end: number) { - return new Uint8Array(this.buffer, start, end - start); + return new Uint8Array(this._buffer, start, end - start); } /** @internal */ override async _retrieveSize() { - return this.buffer.byteLength; + return this._buffer.byteLength; } } +/** @public */ export class BlobSource extends Source { - constructor(private blob: Blob) { + /** @internal */ + _blob: Blob; + + constructor(blob: Blob) { super(); + + this._blob = blob; } /** @internal */ override async _read(start: number, end: number) { - const slice = this.blob.slice(start, end); + const slice = this._blob.slice(start, end); const buffer = await slice.arrayBuffer(); return new Uint8Array(buffer); } /** @internal */ override async _retrieveSize() { - return this.blob.size; + return this._blob.size; } } diff --git a/tsconfig.json b/tsconfig.json index 4157a38..40dbf0f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2023", + "target": "ES2021", "strict": true, "noImplicitAny": true, "noImplicitOverride": true,