avbridge 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +125 -1
- package/NOTICE.md +2 -2
- package/README.md +100 -74
- package/THIRD_PARTY_LICENSES.md +2 -2
- package/dist/avi-2JPBSHGA.js +183 -0
- package/dist/avi-2JPBSHGA.js.map +1 -0
- package/dist/avi-F6WZJK5T.cjs +185 -0
- package/dist/avi-F6WZJK5T.cjs.map +1 -0
- package/dist/{avi-GCGM7OJI.js → avi-NJXAXUXK.js} +9 -3
- package/dist/avi-NJXAXUXK.js.map +1 -0
- package/dist/{avi-6SJLWIWW.cjs → avi-W6L3BTWU.cjs} +10 -4
- package/dist/avi-W6L3BTWU.cjs.map +1 -0
- package/dist/{chunk-ILKDNBSE.js → chunk-2PGRFCWB.js} +59 -10
- package/dist/chunk-2PGRFCWB.js.map +1 -0
- package/dist/chunk-5YAWWKA3.js +18 -0
- package/dist/chunk-5YAWWKA3.js.map +1 -0
- package/dist/chunk-6UUT4BEA.cjs +219 -0
- package/dist/chunk-6UUT4BEA.cjs.map +1 -0
- package/dist/{chunk-OE66B34H.cjs → chunk-7RGG6ME7.cjs} +562 -94
- package/dist/chunk-7RGG6ME7.cjs.map +1 -0
- package/dist/{chunk-WD2ZNQA7.js → chunk-DCSOQH2N.js} +7 -4
- package/dist/chunk-DCSOQH2N.js.map +1 -0
- package/dist/chunk-F3LQJKXK.cjs +20 -0
- package/dist/chunk-F3LQJKXK.cjs.map +1 -0
- package/dist/chunk-IAYKFGFG.js +200 -0
- package/dist/chunk-IAYKFGFG.js.map +1 -0
- package/dist/chunk-NNVOHKXJ.cjs +204 -0
- package/dist/chunk-NNVOHKXJ.cjs.map +1 -0
- package/dist/{chunk-C5VA5U5O.js → chunk-NV7ILLWH.js} +556 -92
- package/dist/chunk-NV7ILLWH.js.map +1 -0
- package/dist/{chunk-HZLQNKFN.cjs → chunk-QQXBPW72.js} +54 -15
- package/dist/chunk-QQXBPW72.js.map +1 -0
- package/dist/chunk-XKPSTC34.cjs +210 -0
- package/dist/chunk-XKPSTC34.cjs.map +1 -0
- package/dist/{chunk-L4NPOJ36.cjs → chunk-Z33SBWL5.cjs} +7 -4
- package/dist/chunk-Z33SBWL5.cjs.map +1 -0
- package/dist/element-browser.js +631 -103
- package/dist/element-browser.js.map +1 -1
- package/dist/element.cjs +4 -4
- package/dist/element.d.cts +1 -1
- package/dist/element.d.ts +1 -1
- package/dist/element.js +3 -3
- package/dist/index.cjs +174 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -4
- package/dist/index.d.ts +48 -4
- package/dist/index.js +93 -12
- package/dist/index.js.map +1 -1
- package/dist/libav-http-reader-AZLE7YFS.cjs +16 -0
- package/dist/{libav-http-reader-FPYDBMYK.cjs.map → libav-http-reader-AZLE7YFS.cjs.map} +1 -1
- package/dist/libav-http-reader-WXG3Z7AI.js +3 -0
- package/dist/{libav-http-reader-NQJVY273.js.map → libav-http-reader-WXG3Z7AI.js.map} +1 -1
- package/dist/{player-DUyvltvy.d.cts → player-B6WB74RD.d.cts} +63 -3
- package/dist/{player-DUyvltvy.d.ts → player-B6WB74RD.d.ts} +63 -3
- package/dist/player.cjs +5500 -0
- package/dist/player.cjs.map +1 -0
- package/dist/player.d.cts +649 -0
- package/dist/player.d.ts +649 -0
- package/dist/player.js +5498 -0
- package/dist/player.js.map +1 -0
- package/dist/source-73CAH6HW.cjs +28 -0
- package/dist/{source-CN43EI7Z.cjs.map → source-73CAH6HW.cjs.map} +1 -1
- package/dist/source-F656KYYV.js +3 -0
- package/dist/{source-FFZ7TW2B.js.map → source-F656KYYV.js.map} +1 -1
- package/dist/source-QJR3OHTW.js +3 -0
- package/dist/source-QJR3OHTW.js.map +1 -0
- package/dist/source-VB74JQ7Z.cjs +28 -0
- package/dist/source-VB74JQ7Z.cjs.map +1 -0
- package/dist/variant-routing-434STYAB.js +3 -0
- package/dist/{variant-routing-JOBWXYKD.js.map → variant-routing-434STYAB.js.map} +1 -1
- package/dist/variant-routing-HONNAA6R.cjs +12 -0
- package/dist/{variant-routing-GOHB2RZN.cjs.map → variant-routing-HONNAA6R.cjs.map} +1 -1
- package/package.json +9 -1
- package/src/classify/rules.ts +27 -5
- package/src/convert/remux.ts +8 -0
- package/src/convert/transcode.ts +41 -8
- package/src/element/avbridge-player.ts +845 -0
- package/src/element/player-icons.ts +25 -0
- package/src/element/player-styles.ts +472 -0
- package/src/errors.ts +47 -0
- package/src/index.ts +23 -0
- package/src/player-element.ts +18 -0
- package/src/player.ts +127 -27
- package/src/plugins/builtin.ts +2 -2
- package/src/probe/avi.ts +4 -0
- package/src/probe/index.ts +40 -10
- package/src/strategies/fallback/audio-output.ts +31 -0
- package/src/strategies/fallback/decoder.ts +83 -2
- package/src/strategies/fallback/index.ts +34 -1
- package/src/strategies/fallback/variant-routing.ts +7 -13
- package/src/strategies/fallback/video-renderer.ts +129 -33
- package/src/strategies/hybrid/decoder.ts +131 -20
- package/src/strategies/hybrid/index.ts +36 -2
- package/src/strategies/remux/index.ts +13 -1
- package/src/strategies/remux/mse.ts +12 -2
- package/src/strategies/remux/pipeline.ts +6 -0
- package/src/subtitles/index.ts +7 -3
- package/src/types.ts +53 -1
- package/src/util/libav-http-reader.ts +5 -1
- package/src/util/source.ts +28 -8
- package/src/util/transport.ts +26 -0
- package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.mjs +1 -1
- package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.wasm +0 -0
- package/dist/avi-6SJLWIWW.cjs.map +0 -1
- package/dist/avi-GCGM7OJI.js.map +0 -1
- package/dist/chunk-C5VA5U5O.js.map +0 -1
- package/dist/chunk-HZLQNKFN.cjs.map +0 -1
- package/dist/chunk-ILKDNBSE.js.map +0 -1
- package/dist/chunk-J5MCMN3S.js +0 -27
- package/dist/chunk-J5MCMN3S.js.map +0 -1
- package/dist/chunk-L4NPOJ36.cjs.map +0 -1
- package/dist/chunk-NZU7W256.cjs +0 -29
- package/dist/chunk-NZU7W256.cjs.map +0 -1
- package/dist/chunk-OE66B34H.cjs.map +0 -1
- package/dist/chunk-WD2ZNQA7.js.map +0 -1
- package/dist/libav-http-reader-FPYDBMYK.cjs +0 -16
- package/dist/libav-http-reader-NQJVY273.js +0 -3
- package/dist/source-CN43EI7Z.cjs +0 -28
- package/dist/source-FFZ7TW2B.js +0 -3
- package/dist/variant-routing-GOHB2RZN.cjs +0 -12
- package/dist/variant-routing-JOBWXYKD.js +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/events.ts","../src/probe/mediabunny.ts","../src/probe/index.ts","../src/util/codec-strings.ts","../src/classify/rules.ts","../src/diagnostics.ts","../src/plugins/registry.ts","../src/strategies/native.ts","../src/strategies/remux/mse.ts","../src/strategies/remux/pipeline.ts","../src/strategies/remux/index.ts","../src/strategies/fallback/video-renderer.ts","../src/strategies/fallback/audio-output.ts","../src/strategies/fallback/variant-routing.ts","../src/strategies/hybrid/decoder.ts","../src/strategies/hybrid/index.ts","../src/strategies/fallback/decoder.ts","../src/strategies/fallback/index.ts","../src/plugins/builtin.ts","../src/subtitles/srt.ts","../src/subtitles/vtt.ts","../src/subtitles/index.ts","../src/player.ts","../src/element/avbridge-video.ts","../src/element/player-styles.ts","../src/element/player-icons.ts","../src/element/avbridge-player.ts","../src/player-element.ts"],"names":["normalizeSource","sniffNormalizedSource","AvbridgeError","ERR_PROBE_FAILED","ERR_PROBE_UNKNOWN_CONTAINER","ERR_LIBAV_NOT_REACHABLE","ERR_MSE_NOT_SUPPORTED","ERR_MSE_CODEC_NOT_SUPPORTED","wallNow","frame","drain","loadLibav","dbg","frames","samples","us","loadBridge","sanitizeFrameTimestamp","libavFrameToInterleavedFloat32","AV_SAMPLE_FMT_U8","AV_SAMPLE_FMT_S16","AV_SAMPLE_FMT_S32","AV_SAMPLE_FMT_FLT","AV_SAMPLE_FMT_U8P","AV_SAMPLE_FMT_S16P","AV_SAMPLE_FMT_S32P","AV_SAMPLE_FMT_FLTP","ensurePlanes","asFloat32","asInt16","asInt32","asUint8","READY_AUDIO_BUFFER_SECONDS","READY_TIMEOUT_SECONDS","fetchWith","ERR_ALL_STRATEGIES_EXHAUSTED","ERR_PLAYER_NOT_READY"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;;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","file":"player.cjs","sourcesContent":["/**\n * Tiny strongly-typed event emitter. We avoid pulling in eventemitter3 / mitt\n * because we only need a handful of methods and want zero deps.\n *\n * Supports \"sticky\" events via {@link TypedEmitter.emitSticky}: the last value\n * for that event is remembered, and any future `on()` subscriber receives it\n * immediately. This is the right pattern for one-shot state-snapshot events\n * like \"strategy chosen\" or \"player ready\" — callers that subscribe after the\n * event has already fired still need to react to it.\n */\n\nexport type Listener<T> = (payload: T) => void;\n\nexport class TypedEmitter<EventMap> {\n private listeners: { [K in keyof EventMap]?: Set<Listener<EventMap[K]>> } = {};\n private sticky: { [K in keyof EventMap]?: EventMap[K] } = {};\n\n on<K extends keyof EventMap>(event: K, fn: Listener<EventMap[K]>): () => void {\n let set = this.listeners[event];\n if (!set) {\n set = new Set();\n this.listeners[event] = set;\n }\n set.add(fn);\n\n // Replay any sticky value that's already been emitted for this event.\n if (Object.prototype.hasOwnProperty.call(this.sticky, event)) {\n try {\n fn(this.sticky[event] as EventMap[K]);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.error(\"[avbridge] listener threw replaying sticky value:\", err);\n }\n }\n\n return () => this.off(event, fn);\n }\n\n off<K extends keyof EventMap>(event: K, fn: Listener<EventMap[K]>): void {\n this.listeners[event]?.delete(fn);\n }\n\n emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void {\n const set = this.listeners[event];\n if (!set) return;\n // Snapshot so listeners can unsubscribe themselves.\n for (const fn of [...set]) {\n try {\n fn(payload);\n } catch (err) {\n // Don't let one bad listener break the others.\n // eslint-disable-next-line no-console\n console.error(\"[avbridge] listener threw:\", err);\n }\n }\n }\n\n /**\n * Like {@link emit} but also remembers the value so future subscribers\n * receive it on `on()`. Use for one-shot state-snapshot events.\n */\n emitSticky<K extends keyof EventMap>(event: K, payload: EventMap[K]): void {\n this.sticky[event] = payload;\n this.emit(event, payload);\n }\n\n removeAll(): void {\n this.listeners = {};\n this.sticky = {};\n }\n}\n","import type {\n AudioCodec,\n AudioTrackInfo,\n ContainerKind,\n MediaContext,\n VideoCodec,\n VideoTrackInfo,\n} from \"../types.js\";\nimport type { NormalizedSource } from \"../util/source.js\";\n\n/**\n * Probe via mediabunny. Built against the real (typed) API exported by\n * `mediabunny.d.ts`:\n *\n * - `Input.getTracks()` returns `InputTrack[]`; each track has `isVideoTrack()`\n * / `isAudioTrack()` type guards plus a `codec` getter that returns one of\n * the enum strings (`\"avc\"|\"hevc\"|\"vp9\"|\"vp8\"|\"av1\"` for video,\n * `\"aac\"|\"opus\"|...` for audio).\n * - For decoder metadata + codec parameter strings we call\n * `getDecoderConfig()` and `getCodecParameterString()` on the typed track.\n *\n * The bridging back to avbridge's own codec naming (`h264` instead of mediabunny's\n * `avc`) happens here so the rest of the codebase keeps a single vocabulary.\n */\nexport async function probeWithMediabunny(\n source: NormalizedSource,\n sniffedContainer: ContainerKind,\n): Promise<MediaContext> {\n const mb = await import(\"mediabunny\");\n const input = new mb.Input({\n source: await buildMediabunnySource(mb, source),\n formats: mb.ALL_FORMATS,\n });\n\n const allTracks = await input.getTracks();\n const duration = await safeNumber(() => input.computeDuration());\n\n const videoTracks: VideoTrackInfo[] = [];\n const audioTracks: AudioTrackInfo[] = [];\n\n for (const track of allTracks) {\n if (track.isVideoTrack()) {\n const codecParam = await safe(() => track.getCodecParameterString());\n videoTracks.push({\n id: track.id,\n codec: mediabunnyVideoToAvbridge(track.codec),\n width: track.displayWidth ?? track.codedWidth ?? 0,\n height: track.displayHeight ?? track.codedHeight ?? 0,\n codecString: codecParam ?? undefined,\n });\n } else if (track.isAudioTrack()) {\n const codecParam = await safe(() => track.getCodecParameterString());\n audioTracks.push({\n id: track.id,\n codec: mediabunnyAudioToAvbridge(track.codec),\n channels: track.numberOfChannels ?? 0,\n sampleRate: track.sampleRate ?? 0,\n language: track.languageCode,\n codecString: codecParam ?? undefined,\n });\n }\n }\n\n const format = await safe(() => input.getFormat());\n const container = resolveContainer(format?.name, sniffedContainer);\n\n return {\n source: source.original,\n name: source.name,\n byteLength: source.byteLength,\n container,\n videoTracks,\n audioTracks,\n subtitleTracks: [],\n probedBy: \"mediabunny\",\n duration,\n };\n}\n\n/**\n * Build the right mediabunny `Source` for a normalized input. URL sources\n * use `UrlSource` (Range requests, prefetch, parallelism) so we don't\n * buffer the whole file into memory. Blob/File sources use `BlobSource`.\n *\n * Exported so the remux strategy can use the same routing logic.\n */\nexport async function buildMediabunnySource(\n mb: typeof import(\"mediabunny\"),\n source: NormalizedSource,\n): Promise<InstanceType<typeof mb.BlobSource> | InstanceType<typeof mb.UrlSource>> {\n if (source.kind === \"url\") {\n return new mb.UrlSource(source.url);\n }\n return new mb.BlobSource(source.blob);\n}\n\n/**\n * Build a mediabunny `Source` directly from a raw `MediaInput`, bypassing\n * `normalizeSource`. Used by strategies that already have the original\n * input on hand (via `MediaContext.source`) and don't need a sniff window.\n *\n * This is the routing point that decides \"stream from URL via Range\n * requests\" vs \"wrap in-memory bytes as BlobSource\". Always prefer\n * `UrlSource` for URL inputs so we don't accidentally buffer the file.\n */\nexport async function buildMediabunnySourceFromInput(\n mb: typeof import(\"mediabunny\"),\n source: import(\"../types.js\").MediaInput,\n): Promise<InstanceType<typeof mb.BlobSource> | InstanceType<typeof mb.UrlSource>> {\n if (typeof source === \"string\") return new mb.UrlSource(source);\n if (source instanceof URL) return new mb.UrlSource(source.toString());\n if (source instanceof Blob) return new mb.BlobSource(source);\n if (source instanceof ArrayBuffer) return new mb.BlobSource(new Blob([source]));\n if (source instanceof Uint8Array) return new mb.BlobSource(new Blob([source as BlobPart]));\n throw new TypeError(\"unsupported source type for mediabunny\");\n}\n\nfunction resolveContainer(formatName: string | undefined, sniffed: ContainerKind): ContainerKind {\n const name = (formatName ?? \"\").toLowerCase();\n if (name.includes(\"matroska\") || name.includes(\"mkv\")) return \"mkv\";\n if (name.includes(\"webm\")) return \"webm\";\n if (name.includes(\"mp4\") || name.includes(\"isom\")) return \"mp4\";\n if (name.includes(\"mov\") || name.includes(\"quicktime\")) return \"mov\";\n if (name.includes(\"ogg\")) return \"ogg\";\n if (name.includes(\"wav\")) return \"wav\";\n if (name.includes(\"flac\")) return \"flac\";\n if (name.includes(\"mp3\")) return \"mp3\";\n if (name.includes(\"adts\") || name.includes(\"aac\")) return \"adts\";\n if (name.includes(\"mpegts\") || name.includes(\"mpeg-ts\") || name.includes(\"transport\")) return \"mpegts\";\n return sniffed;\n}\n\n/** Mediabunny video codec → avbridge video codec. */\nexport function mediabunnyVideoToAvbridge(c: string | null | undefined): VideoCodec {\n switch (c) {\n case \"avc\": return \"h264\";\n case \"hevc\": return \"h265\";\n case \"vp8\": return \"vp8\";\n case \"vp9\": return \"vp9\";\n case \"av1\": return \"av1\";\n default:\n // Preserve the original codec string when mediabunny gave us something\n // we don't recognize. The classifier checks `NATIVE_VIDEO_CODECS.has()`\n // and routes anything outside that set through the fallback chain — so\n // returning the unknown name (instead of silently relabeling it as\n // \"h264\") gets correct routing AND honest diagnostics.\n return c ? (c as VideoCodec) : \"unknown\";\n }\n}\n\n/** avbridge video codec → mediabunny video codec (for output sources). */\nexport function avbridgeVideoToMediabunny(c: VideoCodec): \"avc\" | \"hevc\" | \"vp9\" | \"vp8\" | \"av1\" | null {\n switch (c) {\n case \"h264\": return \"avc\";\n case \"h265\": return \"hevc\";\n case \"vp8\": return \"vp8\";\n case \"vp9\": return \"vp9\";\n case \"av1\": return \"av1\";\n default: return null;\n }\n}\n\nexport function mediabunnyAudioToAvbridge(c: string | null | undefined): AudioCodec {\n switch (c) {\n case \"aac\": return \"aac\";\n case \"mp3\": return \"mp3\";\n case \"opus\": return \"opus\";\n case \"vorbis\": return \"vorbis\";\n case \"flac\": return \"flac\";\n case \"ac3\": return \"ac3\";\n case \"eac3\": return \"eac3\";\n default: return c ? (c as AudioCodec) : \"unknown\";\n }\n}\n\nexport function avbridgeAudioToMediabunny(c: AudioCodec): string | null {\n switch (c) {\n case \"aac\": return \"aac\";\n case \"mp3\": return \"mp3\";\n case \"opus\": return \"opus\";\n case \"vorbis\": return \"vorbis\";\n case \"flac\": return \"flac\";\n case \"ac3\": return \"ac3\";\n case \"eac3\": return \"eac3\";\n default: return null;\n }\n}\n\nasync function safeNumber(fn: () => Promise<number> | number): Promise<number | undefined> {\n try {\n const v = await fn();\n return typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function safe<T>(fn: () => Promise<T> | T): Promise<T | undefined> {\n try { return await fn(); } catch { return undefined; }\n}\n","import type { ContainerKind, MediaContext, MediaInput, TransportConfig } from \"../types.js\";\nimport { normalizeSource, sniffNormalizedSource } from \"../util/source.js\";\nimport { probeWithMediabunny } from \"./mediabunny.js\";\nimport { AvbridgeError, ERR_PROBE_FAILED, ERR_PROBE_UNKNOWN_CONTAINER, ERR_LIBAV_NOT_REACHABLE } from \"../errors.js\";\n\n/** Containers mediabunny can demux. Sniff results outside this set go straight to libav. */\nconst MEDIABUNNY_CONTAINERS = new Set<ContainerKind>([\n \"mp4\",\n \"mov\",\n \"mkv\",\n \"webm\",\n \"ogg\",\n \"wav\",\n \"mp3\",\n \"flac\",\n \"adts\",\n \"mpegts\",\n]);\n\n/**\n * Probe a source and produce a {@link MediaContext}.\n *\n * Routing:\n * 1. Sniff the magic header. Cheap, deterministic, ignores file extensions.\n * 2. If the container is one mediabunny supports → try mediabunny first\n * (fast path — it's a single pass of WASM-free JS parsing). If mediabunny\n * throws (e.g. an assertion on an unsupported sample entry like `mp4v`\n * for MPEG-4 Part 2 in ISOBMFF, or an exotic MKV codec), fall through to\n * libav.js which handles the long tail of codecs mediabunny doesn't.\n * The combined-error case surfaces *both* failures so the user sees\n * which path each step took.\n * 3. If sniffing identifies AVI/ASF/FLV (or `unknown`) → libav.js directly.\n * mediabunny can't read those containers at all, so there's no fast path\n * to try.\n */\nexport async function probe(\n source: MediaInput,\n transport?: TransportConfig,\n): Promise<MediaContext> {\n const normalized = await normalizeSource(source, transport);\n const sniffed = await sniffNormalizedSource(normalized);\n\n if (MEDIABUNNY_CONTAINERS.has(sniffed)) {\n try {\n const result = await probeWithMediabunny(normalized, sniffed);\n // If mediabunny returned unknown codecs, try libav which recognizes\n // a wider range (DTS, TrueHD, etc.). Only escalate if there ARE\n // tracks with unknown codecs — otherwise mediabunny's result is fine.\n const hasUnknownCodec =\n result.videoTracks.some((t) => t.codec === \"unknown\") ||\n result.audioTracks.some((t) => t.codec === \"unknown\");\n if (hasUnknownCodec) {\n try {\n const { probeWithLibav } = await import(\"./avi.js\");\n return await probeWithLibav(normalized, sniffed);\n } catch {\n // libav also failed — return mediabunny's result (unknown codecs\n // are better than no result at all)\n return result;\n }\n }\n return result;\n } catch (mediabunnyErr) {\n // mediabunny rejected the file. Before giving up, try libav — it can\n // demux a much wider range of codec combinations in ISOBMFF/MKV/etc.\n // than mediabunny's pure-JS parser (e.g. mp4v, wmv3-in-asf, flac in\n // an MP4 container). This is \"escalation\", not \"masking\": if libav\n // also fails we surface both errors below.\n // eslint-disable-next-line no-console\n console.warn(\n `[avbridge] mediabunny rejected ${sniffed} file, falling back to libav:`,\n (mediabunnyErr as Error).message,\n );\n try {\n const { probeWithLibav } = await import(\"./avi.js\");\n return await probeWithLibav(normalized, sniffed);\n } catch (libavErr) {\n const mbMsg = (mediabunnyErr as Error).message || String(mediabunnyErr);\n const lvMsg = libavErr instanceof Error ? libavErr.message : String(libavErr);\n throw new AvbridgeError(\n ERR_PROBE_FAILED,\n `Failed to probe ${sniffed.toUpperCase()} file. mediabunny: ${mbMsg}. libav: ${lvMsg}.`,\n \"The file may be corrupt, truncated, or in an unsupported format. Enable AVBRIDGE_DEBUG for detailed logs.\",\n );\n }\n }\n }\n\n // sniffed === avi | asf | flv | unknown — try libav.\n try {\n const { probeWithLibav } = await import(\"./avi.js\");\n return await probeWithLibav(normalized, sniffed);\n } catch (err) {\n const inner = err instanceof Error ? err.message : String(err);\n // eslint-disable-next-line no-console\n console.error(\"[avbridge] libav probe failed for\", sniffed, \"file:\", err);\n if (sniffed === \"unknown\") {\n throw new AvbridgeError(\n ERR_PROBE_UNKNOWN_CONTAINER,\n `Unable to probe source: container format could not be identified. libav fallback: ${inner || \"(no details)\"}`,\n \"The file may be corrupt or in a format avbridge doesn't recognize. Check the file plays in VLC or ffprobe.\",\n );\n }\n throw new AvbridgeError(\n ERR_LIBAV_NOT_REACHABLE,\n `${sniffed.toUpperCase()} files require libav.js, which failed to load: ${inner || \"(no details)\"}`,\n \"Install @libav.js/variant-webcodecs, or check that AVBRIDGE_LIBAV_BASE points to the correct path.\",\n );\n }\n}\n","import type { AudioTrackInfo, VideoTrackInfo } from \"../types.js\";\n\n/**\n * Build an RFC 6381 codec string for use with `MediaSource.isTypeSupported`\n * and `<source type=...>`. Returns null when we don't have enough info to\n * compose one — callers should treat that as \"ask the browser at runtime via\n * a different channel\" rather than guessing.\n */\nexport function videoCodecString(track: VideoTrackInfo): string | null {\n if (track.codecString) return track.codecString;\n switch (track.codec) {\n case \"h264\": {\n // avc1.PPCCLL — profile (1B), constraint (1B), level (1B). Default to\n // High Profile @ 4.0 if we don't know — common on real-world content.\n const profileHex = profileToHex(track.profile) ?? \"64\"; // 0x64 = High\n const constraint = \"00\";\n const level = ((track.level ?? 40) & 0xff).toString(16).padStart(2, \"0\");\n return `avc1.${profileHex}${constraint}${level}`;\n }\n case \"h265\":\n // Default Main Profile @ Level 4.1 (0x5d = 93) — `hvc1.1.6.L93.B0`.\n return \"hvc1.1.6.L93.B0\";\n case \"vp8\":\n return \"vp8\";\n case \"vp9\":\n return \"vp09.00.10.08\";\n case \"av1\":\n return \"av01.0.04M.08\";\n default:\n return null;\n }\n}\n\nfunction profileToHex(profile?: string): string | null {\n if (!profile) return null;\n const p = profile.toLowerCase();\n if (p.includes(\"baseline\")) return \"42\";\n if (p.includes(\"main\")) return \"4d\";\n if (p.includes(\"high 10\")) return \"6e\";\n if (p.includes(\"high 4:2:2\")) return \"7a\";\n if (p.includes(\"high 4:4:4\")) return \"f4\";\n if (p.includes(\"high\")) return \"64\";\n return null;\n}\n\nexport function audioCodecString(track: AudioTrackInfo): string | null {\n if (track.codecString) return track.codecString;\n switch (track.codec) {\n case \"aac\":\n return \"mp4a.40.2\"; // AAC-LC\n case \"mp3\":\n return \"mp4a.40.34\";\n case \"opus\":\n return \"opus\";\n case \"vorbis\":\n return \"vorbis\";\n case \"flac\":\n return \"flac\";\n default:\n return null;\n }\n}\n\n/**\n * Compose a `video/mp4; codecs=\"...\"` MIME for MSE. Returns null if either\n * codec string can't be produced — caller should fall back to remux refusal.\n */\nexport function mp4MimeFor(video: VideoTrackInfo, audio?: AudioTrackInfo): string | null {\n const v = videoCodecString(video);\n if (!v) return null;\n const codecs = audio ? `${v},${audioCodecString(audio) ?? \"\"}`.replace(/,$/, \"\") : v;\n return `video/mp4; codecs=\"${codecs}\"`;\n}\n\n/**\n * Wrap `MediaSource.isTypeSupported` so it returns false (instead of throwing)\n * in environments without MSE — e.g. jsdom under vitest.\n */\nexport function mseSupports(mime: string): boolean {\n if (typeof MediaSource === \"undefined\") return false;\n try {\n return MediaSource.isTypeSupported(mime);\n } catch {\n return false;\n }\n}\n","import type {\n AudioCodec,\n AudioTrackInfo,\n Classification,\n ContainerKind,\n MediaContext,\n VideoCodec,\n VideoTrackInfo,\n} from \"../types.js\";\nimport { mp4MimeFor, mseSupports } from \"../util/codec-strings.js\";\n\n/**\n * Codecs we know `<video>` and MSE support across modern desktop + Android.\n * The decision to remux instead of decode hinges on this list.\n */\n/** Codecs the browser can decode natively (also the set WebCodecs can transcode). */\nexport const NATIVE_VIDEO_CODECS = new Set<VideoCodec>([\"h264\", \"h265\", \"vp8\", \"vp9\", \"av1\"]);\nexport const NATIVE_AUDIO_CODECS = new Set<AudioCodec>([\n \"aac\",\n \"mp3\",\n \"opus\",\n \"vorbis\",\n \"flac\",\n]);\n\n/**\n * Codecs no major browser plays, period. These force the WASM fallback.\n */\nexport const FALLBACK_VIDEO_CODECS = new Set<VideoCodec>([\n \"wmv3\", \"vc1\", \"mpeg4\",\n \"rv10\", \"rv20\", \"rv30\", \"rv40\",\n \"mpeg2\", \"mpeg1\", \"theora\",\n]);\nexport const FALLBACK_AUDIO_CODECS = new Set<AudioCodec>([\n \"wmav2\", \"wmapro\", \"ac3\", \"eac3\",\n \"cook\", \"ra_144\", \"ra_288\", \"sipr\", \"atrac3\",\n \"dts\", \"truehd\",\n]);\n\n/**\n * Containers `<video>` plays directly. Anything else with otherwise-supported\n * codecs is a remux candidate — IF mediabunny can read the container.\n */\nconst NATIVE_CONTAINERS = new Set<ContainerKind>([\n \"mp4\",\n \"mov\",\n \"webm\",\n \"ogg\",\n \"wav\",\n \"mp3\",\n \"flac\",\n \"adts\",\n]);\n\n/**\n * Containers mediabunny can demux. The remux strategy feeds the source through\n * mediabunny → fMP4 → MSE, so the source container must be one mediabunny\n * understands. AVI, ASF, FLV are NOT in this set — mediabunny rejects them\n * with \"unsupported or unrecognizable format\". Files in those containers with\n * otherwise-native codecs (e.g. AVI + H.264 + MP3) must go to the fallback\n * strategy even though the *codecs* are browser-supported.\n *\n * MPEG-TS is in this set: mediabunny demuxes it natively, but browsers\n * cannot play `<video src=\"*.ts\">` directly (MPEG-TS is HLS-only), so even\n * a TS file with H.264 + AAC has to go through the remux path.\n */\nconst REMUXABLE_CONTAINERS = new Set<ContainerKind>([\n \"mp4\",\n \"mov\",\n \"mkv\",\n \"webm\",\n \"ogg\",\n \"wav\",\n \"mp3\",\n \"flac\",\n \"adts\",\n \"mpegts\",\n]);\n\n/**\n * Pure classification — no I/O, no async. Test-friendly.\n */\nexport function classifyContext(ctx: MediaContext): Classification {\n const video = ctx.videoTracks[0];\n const audio = ctx.audioTracks[0];\n\n // Audio-only files: mediabunny handles all the common ones natively.\n if (!video) {\n if (NATIVE_CONTAINERS.has(ctx.container) && (!audio || NATIVE_AUDIO_CODECS.has(audio.codec))) {\n return {\n class: \"NATIVE\",\n strategy: \"native\",\n reason: `audio-only ${ctx.container} with native codec`,\n };\n }\n if (audio && FALLBACK_AUDIO_CODECS.has(audio.codec)) {\n return {\n class: \"FALLBACK_REQUIRED\",\n strategy: \"fallback\",\n reason: `audio codec \"${audio.codec}\" requires WASM decode`,\n };\n }\n if (REMUXABLE_CONTAINERS.has(ctx.container)) {\n return {\n class: \"REMUX_CANDIDATE\",\n strategy: \"remux\",\n reason: `audio-only file in non-native container \"${ctx.container}\"`,\n };\n }\n return {\n class: \"FALLBACK_REQUIRED\",\n strategy: \"fallback\",\n reason: `audio-only file in \"${ctx.container}\" (not remuxable by mediabunny)`,\n };\n }\n\n // Video paths.\n if (FALLBACK_VIDEO_CODECS.has(video.codec)) {\n return {\n class: \"FALLBACK_REQUIRED\",\n strategy: \"fallback\",\n reason: `video codec \"${video.codec}\" has no browser decoder; WASM fallback required`,\n };\n }\n // Audio codec needs WASM decode — either it's in the known fallback set\n // or it's unrecognized (\"unknown\" / not in native set). Unknown codecs\n // definitely can't play natively, so they get the same treatment.\n const audioNeedsFallback = audio && (\n FALLBACK_AUDIO_CODECS.has(audio.codec) ||\n !NATIVE_AUDIO_CODECS.has(audio.codec)\n );\n if (audioNeedsFallback) {\n // If the VIDEO codec is native, prefer hybrid (WebCodecs hardware video\n // decode + libav software audio decode) over full WASM fallback. This is\n // critical for Blu-ray MKVs: H.264 1080p in WASM is unwatchably slow,\n // but WebCodecs decodes it at full speed while libav handles the DTS/AC3\n // audio in software.\n if (NATIVE_VIDEO_CODECS.has(video.codec) && webCodecsAvailable()) {\n return {\n class: \"HYBRID_CANDIDATE\",\n strategy: \"hybrid\",\n reason: `video \"${video.codec}\" is hardware-decodable via WebCodecs; audio \"${audio.codec}\" decoded in software by libav`,\n fallbackChain: [\"fallback\"],\n };\n }\n return {\n class: \"FALLBACK_REQUIRED\",\n strategy: \"fallback\",\n reason: `audio codec \"${audio.codec}\" has no browser decoder; WASM fallback required`,\n };\n }\n\n if (!NATIVE_VIDEO_CODECS.has(video.codec)) {\n return {\n class: \"FALLBACK_REQUIRED\",\n strategy: \"fallback\",\n reason: `unknown video codec \"${video.codec}\", routing to fallback`,\n };\n }\n\n // Codecs are native. Now decide between NATIVE and REMUX based on the\n // container and codec quirks.\n const isNativeContainer = NATIVE_CONTAINERS.has(ctx.container);\n\n if (isNativeContainer && isSafeNativeCombo(video, audio)) {\n // Confirm with the browser when we have access to MediaSource.\n const mime = mp4MimeFor(video, audio);\n if (mime && mseSupports(mime)) {\n return {\n class: \"NATIVE\",\n strategy: \"native\",\n reason: `${ctx.container} + ${video.codec}${audio ? \"/\" + audio.codec : \"\"} plays natively`,\n };\n }\n if (mime == null || typeof MediaSource === \"undefined\") {\n // No MSE in this environment (e.g. tests) — trust the heuristic.\n return {\n class: \"NATIVE\",\n strategy: \"native\",\n reason: `${ctx.container} + ${video.codec}${audio ? \"/\" + audio.codec : \"\"} (heuristic native)`,\n };\n }\n }\n\n if (isNativeContainer && isRiskyNative(video)) {\n return {\n class: \"RISKY_NATIVE\",\n strategy: \"native\",\n reason: `${video.codec} ${video.profile ?? \"\"} ${video.bitDepth ?? 8}-bit may stutter on mobile; will escalate to remux on stall`,\n fallbackChain: [\"remux\", \"hybrid\", \"fallback\"],\n };\n }\n\n // Codecs are native but the container isn't. Can we remux?\n // Remuxing goes through mediabunny, which only supports certain containers.\n // AVI/ASF/FLV are NOT in that set — mediabunny rejects them at Input().\n if (REMUXABLE_CONTAINERS.has(ctx.container)) {\n return {\n class: \"REMUX_CANDIDATE\",\n strategy: \"remux\",\n reason: `${ctx.container} container with native-supported codecs — remux to fragmented MP4 for reliable playback`,\n };\n }\n\n // Container is unreadable by mediabunny (AVI, ASF, FLV, etc.) but codecs\n // are browser-supported. Use the hybrid strategy (libav demux + WebCodecs\n // hardware decode) when WebCodecs is available; otherwise full WASM decode.\n if (webCodecsAvailable()) {\n return {\n class: \"HYBRID_CANDIDATE\",\n strategy: \"hybrid\",\n reason: `${ctx.container} container requires libav demux; codecs (${video.codec}${audio ? \"/\" + audio.codec : \"\"}) are hardware-decodable via WebCodecs`,\n fallbackChain: [\"fallback\"],\n };\n }\n return {\n class: \"FALLBACK_REQUIRED\",\n strategy: \"fallback\",\n reason: `${ctx.container} container cannot be remuxed by mediabunny; falling back to WASM decode (${video.codec}${audio ? \"/\" + audio.codec : \"\"})`,\n };\n}\n\nfunction webCodecsAvailable(): boolean {\n return typeof globalThis.VideoDecoder !== \"undefined\";\n}\n\nfunction isSafeNativeCombo(video: VideoTrackInfo, audio?: AudioTrackInfo): boolean {\n if (video.codec === \"h264\") {\n // 8-bit yuv420p H.264 is the safe combo. Hi10P / 4:2:2 / 4:4:4 are not.\n if (video.bitDepth && video.bitDepth > 8) return false;\n if (video.pixelFormat && !/yuv420p$/.test(video.pixelFormat)) return false;\n }\n if (audio && !NATIVE_AUDIO_CODECS.has(audio.codec)) return false;\n return true;\n}\n\nfunction isRiskyNative(video: VideoTrackInfo): boolean {\n if (video.bitDepth && video.bitDepth > 8) return true;\n if (video.pixelFormat && /yuv4(2[24]|44)/.test(video.pixelFormat)) return true;\n if (video.width > 3840 || video.height > 2160) return true;\n if (video.fps && video.fps > 60) return true;\n return false;\n}\n","import type {\n Classification,\n DiagnosticsSnapshot,\n MediaContext,\n StrategyName,\n} from \"./types.js\";\n\n/**\n * Accumulates diagnostic info as the player walks probe → classify → play.\n * `snapshot()` produces an immutable view shaped exactly like the example in\n * design doc §12.\n */\nexport class Diagnostics {\n private container: DiagnosticsSnapshot[\"container\"] = \"unknown\";\n private videoCodec?: DiagnosticsSnapshot[\"videoCodec\"];\n private audioCodec?: DiagnosticsSnapshot[\"audioCodec\"];\n private width?: number;\n private height?: number;\n private fps?: number;\n private duration?: number;\n private strategy: DiagnosticsSnapshot[\"strategy\"] = \"pending\";\n private strategyClass: DiagnosticsSnapshot[\"strategyClass\"] = \"pending\";\n private reason = \"\";\n private probedBy?: DiagnosticsSnapshot[\"probedBy\"];\n private sourceType?: DiagnosticsSnapshot[\"sourceType\"];\n private transport?: DiagnosticsSnapshot[\"transport\"];\n private rangeSupported?: DiagnosticsSnapshot[\"rangeSupported\"];\n private runtime: Record<string, unknown> = {};\n private lastError?: Error;\n private strategyHistory: Array<{ strategy: StrategyName; reason: string; at: number }> = [];\n\n recordProbe(ctx: MediaContext): void {\n this.container = ctx.container;\n this.probedBy = ctx.probedBy;\n this.duration = ctx.duration;\n const v = ctx.videoTracks[0];\n if (v) {\n this.videoCodec = v.codec;\n this.width = v.width;\n this.height = v.height;\n this.fps = v.fps;\n }\n const a = ctx.audioTracks[0];\n if (a) this.audioCodec = a.codec;\n // Source-type detection. For blob inputs we know the transport with\n // certainty. For URL inputs we know the *intended* transport but not\n // whether the server actually honors Range — that's confirmed later by\n // the strategy that fetches the bytes (via {@link recordTransport}).\n const src = ctx.source;\n if (typeof src === \"string\" || src instanceof URL) {\n this.sourceType = \"url\";\n this.transport = \"http-range\";\n // Intentionally NOT setting rangeSupported here. Inferring \"true\" from\n // input type was misleading: native/remux URL paths rely on the\n // browser's or mediabunny's own Range handling and don't fail-fast on\n // a non-supporting server. Strategies that prove Range support call\n // recordTransport() once they have a confirmed answer.\n this.rangeSupported = undefined;\n } else {\n this.sourceType = \"blob\";\n this.transport = \"memory\";\n this.rangeSupported = false;\n }\n }\n\n /**\n * Called by a strategy once it has a confirmed answer about how the\n * source bytes are actually flowing (e.g. after the libav HTTP block\n * reader's initial Range probe succeeded). Lets diagnostics report the\n * truth instead of an input-type heuristic.\n */\n recordTransport(\n transport: NonNullable<DiagnosticsSnapshot[\"transport\"]>,\n rangeSupported: boolean,\n ): void {\n this.transport = transport;\n this.rangeSupported = rangeSupported;\n }\n\n recordClassification(c: Classification): void {\n this.strategy = c.strategy;\n this.strategyClass = c.class;\n this.reason = c.reason;\n }\n\n recordRuntime(stats: Record<string, unknown>): void {\n // Strategies can surface confirmed transport info in their runtime\n // stats under the well-known `_transport` / `_rangeSupported` keys.\n // When present, they're hoisted to the typed fields via\n // recordTransport() and stripped from the generic runtime bag so they\n // don't duplicate.\n const {\n _transport,\n _rangeSupported,\n ...rest\n } = stats as Record<string, unknown> & {\n _transport?: NonNullable<DiagnosticsSnapshot[\"transport\"]>;\n _rangeSupported?: boolean;\n };\n if (_transport != null && typeof _rangeSupported === \"boolean\") {\n this.recordTransport(_transport, _rangeSupported);\n }\n this.runtime = { ...this.runtime, ...rest };\n }\n\n recordStrategySwitch(strategy: StrategyName, reason: string): void {\n this.strategy = strategy;\n this.reason = reason;\n this.strategyHistory.push({ strategy, reason, at: Date.now() });\n }\n\n recordError(err: Error): void {\n this.lastError = err;\n }\n\n snapshot(): DiagnosticsSnapshot {\n const snap: DiagnosticsSnapshot = {\n container: this.container,\n videoCodec: this.videoCodec,\n audioCodec: this.audioCodec,\n width: this.width,\n height: this.height,\n fps: this.fps,\n duration: this.duration,\n strategy: this.strategy,\n strategyClass: this.strategyClass,\n reason: this.reason,\n probedBy: this.probedBy,\n sourceType: this.sourceType,\n transport: this.transport,\n rangeSupported: this.rangeSupported,\n runtime: { ...this.runtime, ...(this.lastError ? { error: this.lastError.message } : {}) },\n strategyHistory: this.strategyHistory.length > 0 ? [...this.strategyHistory] : undefined,\n };\n return Object.freeze(snap);\n }\n}\n","import type { MediaContext, Plugin, StrategyName } from \"../types.js\";\n\n/**\n * Plugin registry. Built-in strategies are registered as plugins so that\n * user-supplied plugins can preempt them. The registry is consulted twice:\n * once by the player layer to find a plugin matching the picked strategy, and\n * (optionally) by classification to ask plugins what they support.\n */\nexport class PluginRegistry {\n private plugins: Plugin[] = [];\n\n register(plugin: Plugin, prepend = false): void {\n if (prepend) this.plugins.unshift(plugin);\n else this.plugins.push(plugin);\n }\n\n all(): readonly Plugin[] {\n return this.plugins;\n }\n\n /**\n * Find the first plugin that claims this context AND its name matches the\n * strategy. Built-in strategy plugins are named exactly `\"native\"`,\n * `\"remux\"`, `\"fallback\"`.\n */\n findFor(context: MediaContext, strategy: StrategyName): Plugin | null {\n for (const p of this.plugins) {\n if (p.name === strategy && p.canHandle(context)) return p;\n }\n return null;\n }\n}\n","import type { MediaContext, PlaybackSession } from \"../types.js\";\n\n/**\n * Simplest strategy: hand the source to the browser. Works for any\n * MP4/WebM/MP3/etc. that the user agent already plays.\n *\n * The only complexity is that the source might be a `File`/`Blob` (use\n * `URL.createObjectURL`), an `ArrayBuffer`/`Uint8Array` (wrap in a Blob first),\n * or a string URL (assign directly).\n */\nexport async function createNativeSession(\n context: MediaContext,\n video: HTMLVideoElement,\n): Promise<PlaybackSession> {\n const { url, revoke } = sourceToVideoUrl(context.source);\n video.src = url;\n\n // Wait for metadata so the player resolves only once playback is actually\n // ready. We expose errors via the player's \"error\" event, not by throwing\n // here, because failure here often means we should escalate to remux.\n await new Promise<void>((resolve, reject) => {\n const onMeta = () => {\n cleanup();\n resolve();\n };\n const onError = () => {\n cleanup();\n reject(new Error(`<video> failed to load: ${video.error?.message ?? \"unknown\"}`));\n };\n const cleanup = () => {\n video.removeEventListener(\"loadedmetadata\", onMeta);\n video.removeEventListener(\"error\", onError);\n };\n video.addEventListener(\"loadedmetadata\", onMeta);\n video.addEventListener(\"error\", onError);\n });\n\n let stats = { framesDecoded: 0, framesDropped: 0 };\n\n return {\n strategy: \"native\",\n async play() {\n await video.play();\n },\n pause() {\n video.pause();\n },\n async seek(time) {\n video.currentTime = time;\n },\n async setAudioTrack(id) {\n // HTMLMediaElement.audioTracks is not exposed in all browsers, so we\n // try-catch and no-op if not available.\n const tracks = (video as unknown as { audioTracks?: { length: number; [i: number]: { id: string; enabled: boolean } } }).audioTracks;\n if (!tracks) return;\n for (let i = 0; i < tracks.length; i++) {\n tracks[i].enabled = tracks[i].id === String(id) || i === id;\n }\n },\n async setSubtitleTrack(id) {\n const tracks = video.textTracks;\n for (let i = 0; i < tracks.length; i++) {\n tracks[i].mode = i === id ? \"showing\" : \"disabled\";\n }\n },\n async destroy() {\n video.pause();\n video.removeAttribute(\"src\");\n video.load();\n revoke?.();\n },\n getCurrentTime() {\n return video.currentTime || 0;\n },\n getRuntimeStats() {\n // getVideoPlaybackQuality is the standard hook; not all UAs implement it.\n const q = (video as unknown as { getVideoPlaybackQuality?: () => VideoPlaybackQuality }).getVideoPlaybackQuality?.();\n if (q) {\n stats = {\n framesDecoded: q.totalVideoFrames,\n framesDropped: q.droppedVideoFrames,\n };\n }\n return { ...stats, decoderType: \"native\" };\n },\n };\n}\n\nfunction sourceToVideoUrl(source: unknown): { url: string; revoke?: () => void } {\n if (source instanceof Blob) {\n const url = URL.createObjectURL(source);\n return { url, revoke: () => URL.revokeObjectURL(url) };\n }\n if (source instanceof ArrayBuffer || source instanceof Uint8Array) {\n const blob = new Blob([source as BlobPart]);\n const url = URL.createObjectURL(blob);\n return { url, revoke: () => URL.revokeObjectURL(url) };\n }\n if (typeof source === \"string\") return { url: source };\n if (source instanceof URL) return { url: source.toString() };\n throw new TypeError(\"native strategy: unsupported source type\");\n}\n\ninterface VideoPlaybackQuality {\n totalVideoFrames: number;\n droppedVideoFrames: number;\n}\n","/**\n * MediaSource Extensions plumbing. Wraps a `MediaSource` + single\n * `SourceBuffer` with an append queue that respects `updateend` backpressure.\n */\n\nimport { AvbridgeError, ERR_MSE_NOT_SUPPORTED, ERR_MSE_CODEC_NOT_SUPPORTED } from \"../../errors.js\";\n\nexport interface MseSinkOptions {\n mime: string;\n video: HTMLVideoElement;\n /** Called once the MediaSource is open and ready for appends. */\n onReady?: () => void;\n}\n\nexport class MseSink {\n private mediaSource: MediaSource;\n private sourceBuffer: SourceBuffer | null = null;\n private queue: ArrayBuffer[] = [];\n private endOfStreamCalled = false;\n private destroyed = false;\n private readyPromise: Promise<void>;\n private resolveReady!: () => void;\n private rejectReady!: (err: Error) => void;\n private objectUrl: string;\n\n constructor(private readonly options: MseSinkOptions) {\n if (typeof MediaSource === \"undefined\") {\n throw new AvbridgeError(\n ERR_MSE_NOT_SUPPORTED,\n \"MediaSource Extensions (MSE) are not supported in this environment.\",\n \"MSE is required for the remux strategy. Use a browser that supports MSE, or try the fallback strategy.\",\n );\n }\n if (!MediaSource.isTypeSupported(options.mime)) {\n throw new AvbridgeError(\n ERR_MSE_CODEC_NOT_SUPPORTED,\n `This browser's MSE does not support \"${options.mime}\".`,\n \"The codec combination can't be played via remux in this browser. The player will try the next strategy automatically.\",\n );\n }\n\n this.mediaSource = new MediaSource();\n this.objectUrl = URL.createObjectURL(this.mediaSource);\n options.video.src = this.objectUrl;\n\n this.readyPromise = new Promise((resolve, reject) => {\n this.resolveReady = resolve;\n this.rejectReady = reject;\n });\n\n this.mediaSource.addEventListener(\"sourceopen\", () => {\n try {\n this.sourceBuffer = this.mediaSource.addSourceBuffer(options.mime);\n this.sourceBuffer.mode = \"segments\";\n this.sourceBuffer.addEventListener(\"updateend\", () => this.pump());\n this.resolveReady();\n options.onReady?.();\n } catch (err) {\n this.rejectReady(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n ready(): Promise<void> {\n return this.readyPromise;\n }\n\n /** Queue a chunk of fMP4 bytes (init segment or media segment). */\n append(chunk: ArrayBuffer | Uint8Array): void {\n if (this.destroyed) return;\n const ab = chunk instanceof Uint8Array\n ? (chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength) as ArrayBuffer)\n : chunk;\n this.queue.push(ab);\n this.pump();\n }\n\n private pump(): void {\n const sb = this.sourceBuffer;\n if (!sb || sb.updating) return;\n\n // Apply deferred actions once the SourceBuffer has any data. Deferred\n // seek and deferred autoplay are independent — both can fire here, or\n // either alone. Setting `currentTime` before data exists causes the\n // browser to snap back to the nearest buffered range; calling `play()`\n // before data exists puts the video into a stuck waiting state.\n if (sb.buffered.length > 0) {\n if (this.pendingSeekTime !== null) {\n this.options.video.currentTime = this.pendingSeekTime;\n this.pendingSeekTime = null;\n } else if (!this.hasSnappedToFirstBuffered) {\n // First data arrival with no pending seek. If currentTime is\n // outside the first buffered range (typical for MPEG-TS sources\n // whose PTS doesn't start at 0), snap into the buffered range\n // so the video element doesn't wait forever for nonexistent data.\n const v = this.options.video;\n const firstStart = sb.buffered.start(0);\n const firstEnd = sb.buffered.end(0);\n if (v.currentTime < firstStart || v.currentTime > firstEnd) {\n v.currentTime = firstStart;\n }\n this.hasSnappedToFirstBuffered = true;\n }\n if (this.playOnSeek) {\n this.playOnSeek = false;\n this.options.video.play().catch(() => { /* ignore — autoplay may be blocked */ });\n }\n }\n\n const next = this.queue.shift();\n if (!next) return;\n try {\n sb.appendBuffer(next);\n } catch (err) {\n // QuotaExceededError → evict the oldest few seconds and retry once.\n if ((err as DOMException).name === \"QuotaExceededError\") {\n this.evict();\n try {\n sb.appendBuffer(next);\n return;\n } catch {\n /* fall through to error */\n }\n }\n this.rejectReady(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private evict(): void {\n const sb = this.sourceBuffer;\n if (!sb || sb.buffered.length === 0) return;\n const start = sb.buffered.start(0);\n const current = this.options.video.currentTime;\n // Drop everything that's at least 10s behind the current position.\n if (current - start > 10) {\n try {\n sb.remove(start, current - 10);\n } catch {\n /* ignore */\n }\n }\n }\n\n /** Indicate the source is finished. Future seeks past the end will fail. */\n endOfStream(): void {\n if (this.endOfStreamCalled || this.destroyed) return;\n this.endOfStreamCalled = true;\n const tryEnd = () => {\n if (this.queue.length > 0 || this.sourceBuffer?.updating) {\n // Wait for the queue to drain.\n this.sourceBuffer?.addEventListener(\"updateend\", tryEnd, { once: true });\n return;\n }\n try {\n if (this.mediaSource.readyState === \"open\") {\n this.mediaSource.endOfStream();\n }\n } catch {\n /* ignore */\n }\n };\n tryEnd();\n }\n\n /** Seconds of media buffered ahead of the current playback position. */\n bufferedAhead(): number {\n const sb = this.sourceBuffer;\n if (!sb || sb.buffered.length === 0) return 0;\n const current = this.options.video.currentTime;\n for (let i = 0; i < sb.buffered.length; i++) {\n if (sb.buffered.start(i) <= current && sb.buffered.end(i) > current) {\n return sb.buffered.end(i) - current;\n }\n }\n return 0;\n }\n\n /** Total seconds of media buffered across all ranges. */\n totalBuffered(): number {\n const sb = this.sourceBuffer;\n if (!sb || sb.buffered.length === 0) return 0;\n let total = 0;\n for (let i = 0; i < sb.buffered.length; i++) {\n total += sb.buffered.end(i) - sb.buffered.start(i);\n }\n return total;\n }\n\n /** Number of chunks waiting in the append queue. */\n queueLength(): number {\n return this.queue.length;\n }\n\n /** Time to seek to once the SourceBuffer has data at this position. */\n private pendingSeekTime: number | null = null;\n /** Whether to resume playback after the deferred seek completes. */\n private playOnSeek = false;\n /**\n * On the very first data arrival, if `currentTime` falls outside the first\n * buffered range, snap it to the start of that range. MPEG-TS sources\n * commonly start their PTS at a non-zero value (e.g. ~1.5s); without this\n * snap, the video element sits at `currentTime=0` waiting forever for\n * data that doesn't exist.\n */\n private hasSnappedToFirstBuffered = false;\n\n /** Request that playback resumes automatically once the deferred seek fires. */\n setPlayOnSeek(play: boolean): void {\n this.playOnSeek = play;\n }\n\n /**\n * Discard all buffered media and schedule a deferred seek. The actual\n * `video.currentTime` assignment happens in `pump()` once the SourceBuffer\n * has data at the target position — setting it earlier causes the browser\n * to snap back to the nearest buffered range.\n */\n invalidate(seekTime: number): void {\n const sb = this.sourceBuffer;\n // Clear the pending queue — stale fragments from the old pump position.\n this.queue = [];\n this.pendingSeekTime = seekTime;\n this.hasSnappedToFirstBuffered = true; // explicit seek overrides the auto-snap\n if (!sb || sb.buffered.length === 0) return;\n try {\n const start = sb.buffered.start(0);\n const end = sb.buffered.end(sb.buffered.length - 1);\n sb.remove(start, end);\n } catch {\n /* ignore — sourcebuffer may be in updating state */\n }\n }\n\n destroy(): void {\n this.destroyed = true;\n this.queue = [];\n try {\n if (this.mediaSource.readyState === \"open\") this.mediaSource.endOfStream();\n } catch {\n /* ignore */\n }\n URL.revokeObjectURL(this.objectUrl);\n }\n}\n","import type { MediaContext } from \"../../types.js\";\nimport { MseSink } from \"./mse.js\";\nimport {\n avbridgeVideoToMediabunny,\n avbridgeAudioToMediabunny,\n buildMediabunnySourceFromInput,\n} from \"../../probe/mediabunny.js\";\n\n/**\n * Remux pipeline built against mediabunny's real API.\n *\n * Key design notes:\n *\n * - mediabunny's fMP4 muxer is a streaming muxer that requires monotonically\n * increasing timestamps. It cannot accept out-of-order packets after a seek.\n * Therefore, on each seek we create a **fresh** Output + sources + StreamTarget.\n * The MseSink handles the SourceBuffer reset via `invalidate()`.\n *\n * - Backpressure is enforced at two levels: in the WritableStream write handler\n * (limits append queue depth and total buffered time) and in the pump loop\n * (limits buffered-ahead and total buffered time). Without this, long files\n * dump gigabytes into the SourceBuffer and exhaust memory.\n */\nexport interface RemuxPipeline {\n start(fromTime?: number, autoPlay?: boolean): Promise<void>;\n seek(time: number, autoPlay?: boolean): Promise<void>;\n /** Update the autoplay intent mid-flight — used when play() arrives after seek() but before the MseSink has been constructed. */\n setAutoPlay(autoPlay: boolean): void;\n destroy(): Promise<void>;\n stats(): Record<string, unknown>;\n}\n\nexport async function createRemuxPipeline(\n ctx: MediaContext,\n video: HTMLVideoElement,\n): Promise<RemuxPipeline> {\n const mb = await import(\"mediabunny\");\n\n const videoTrackInfo = ctx.videoTracks[0];\n const audioTrackInfo = ctx.audioTracks[0];\n if (!videoTrackInfo) throw new Error(\"remux: source has no video track\");\n\n // Map avbridge codec names back to mediabunny's enum strings.\n const mbVideoCodec = avbridgeVideoToMediabunny(videoTrackInfo.codec);\n if (!mbVideoCodec) {\n throw new Error(`remux: video codec \"${videoTrackInfo.codec}\" is not supported by mediabunny output`);\n }\n const mbAudioCodec = audioTrackInfo ? avbridgeAudioToMediabunny(audioTrackInfo.codec) : null;\n\n // Open the input. URL sources go through mediabunny's UrlSource so the\n // muxer streams via Range requests instead of buffering the whole file.\n const input = new mb.Input({\n source: await buildMediabunnySourceFromInput(mb, ctx.source),\n formats: mb.ALL_FORMATS,\n });\n const allTracks = await input.getTracks();\n const inputVideo = allTracks.find((t) => t.id === videoTrackInfo.id && t.isVideoTrack());\n const inputAudio = audioTrackInfo\n ? allTracks.find((t) => t.id === audioTrackInfo.id && t.isAudioTrack())\n : null;\n if (!inputVideo || !inputVideo.isVideoTrack()) {\n throw new Error(\"remux: video track not found in input\");\n }\n if (audioTrackInfo && (!inputAudio || !inputAudio.isAudioTrack())) {\n throw new Error(\"remux: audio track not found in input\");\n }\n\n // Pull WebCodecs decoder configs once — used as `meta` on the first packet.\n const videoConfig = await inputVideo.getDecoderConfig();\n const audioConfig = inputAudio && inputAudio.isAudioTrack() ? await inputAudio.getDecoderConfig() : null;\n\n // Packet sinks (input side) — reused across seeks.\n const videoSink = new mb.EncodedPacketSink(inputVideo);\n const audioSink = inputAudio?.isAudioTrack() ? new mb.EncodedPacketSink(inputAudio) : null;\n\n // MSE sink — created lazily on first output write, reused across seeks.\n let sink: MseSink | null = null;\n const stats = { videoPackets: 0, audioPackets: 0, bytesWritten: 0, fragments: 0 };\n\n let destroyed = false;\n let pumpToken = 0;\n let pendingAutoPlay = false;\n let pendingStartTime = 0;\n\n // The current Output instance. Recreated on each seek because mediabunny's\n // fMP4 muxer requires monotonically increasing timestamps.\n let currentOutput: InstanceType<typeof mb.Output> | null = null;\n\n /**\n * Create a fresh mediabunny Output wired to the MSE sink. Called once at\n * start and again on each seek.\n */\n function createOutput() {\n // Cancel the previous output if it exists.\n if (currentOutput) {\n try { void currentOutput.cancel(); } catch { /* ignore */ }\n }\n\n let mimePromise: Promise<string> | null = null;\n\n const writable = new WritableStream<{\n type: \"write\";\n data: Uint8Array<ArrayBuffer>;\n position: number;\n }>({\n write: async (chunk) => {\n if (destroyed) return;\n if (!sink) {\n const mime = await (mimePromise ??= output.getMimeType());\n sink = new MseSink({ mime, video });\n await sink.ready();\n // Apply deferred seek + autoPlay for the initial start.\n if (pendingStartTime > 0) {\n sink.invalidate(pendingStartTime);\n }\n sink.setPlayOnSeek(pendingAutoPlay);\n }\n // Backpressure: wait for the SourceBuffer append queue to drain.\n while (sink && !destroyed && (sink.queueLength() > 10 || sink.bufferedAhead() > 60 || sink.totalBuffered() > 120)) {\n await new Promise((r) => setTimeout(r, 500));\n }\n if (destroyed) return;\n sink.append(chunk.data);\n stats.bytesWritten += chunk.data.byteLength;\n stats.fragments++;\n },\n });\n\n const target = new mb.StreamTarget(writable);\n const output = new mb.Output({\n format: new mb.Mp4OutputFormat({ fastStart: \"fragmented\" }),\n target,\n });\n\n // Build the output sources.\n const videoSource = new mb.EncodedVideoPacketSource(mbVideoCodec!);\n output.addVideoTrack(videoSource);\n\n type AudioSourceCtorArg = ConstructorParameters<typeof mb.EncodedAudioPacketSource>[0];\n let audioSource: InstanceType<typeof mb.EncodedAudioPacketSource> | null = null;\n if (mbAudioCodec && inputAudio?.isAudioTrack()) {\n audioSource = new mb.EncodedAudioPacketSource(mbAudioCodec as AudioSourceCtorArg);\n output.addAudioTrack(audioSource);\n }\n\n currentOutput = output;\n return { output, videoSource, audioSource };\n }\n\n async function pumpLoop(token: number, fromTime: number) {\n const { output, videoSource, audioSource } = createOutput();\n\n await output.start();\n\n\n // Find the starting key packet so we never push partial GOPs.\n const startVideoPacket =\n fromTime > 0\n ? (await videoSink.getKeyPacket(fromTime)) ?? (await videoSink.getFirstPacket())\n : await videoSink.getFirstPacket();\n if (!startVideoPacket) return;\n\n const startAudioPacket = audioSink\n ? (audioSink && fromTime > 0\n ? (await audioSink.getPacket(fromTime)) ?? (await audioSink.getFirstPacket())\n : await audioSink.getFirstPacket())\n : null;\n\n const videoIter = videoSink.packets(startVideoPacket);\n const audioIter = audioSink && startAudioPacket ? audioSink.packets(startAudioPacket) : null;\n\n let vNext = await videoIter.next();\n let aNext = audioIter ? await audioIter.next() : { done: true as const, value: undefined };\n let firstVideo = true;\n let firstAudio = true;\n\n while (!destroyed && pumpToken === token && (!vNext.done || !aNext.done)) {\n // Backpressure: pause pumping when we've buffered enough.\n while (\n !destroyed &&\n pumpToken === token &&\n sink &&\n (sink.bufferedAhead() > 30 || sink.queueLength() > 20 || sink.totalBuffered() > 90)\n ) {\n await new Promise((r) => setTimeout(r, 500));\n }\n if (destroyed || pumpToken !== token) break;\n\n const vTs = !vNext.done ? vNext.value.timestamp : Number.POSITIVE_INFINITY;\n const aTs = !aNext.done ? aNext.value.timestamp : Number.POSITIVE_INFINITY;\n\n // Mediabunny's muxer requires the first packet on a fresh Output to\n // be a key packet. We fetched `startVideoPacket` via\n // `videoSink.getKeyPacket(fromTime)` so the first video packet is\n // guaranteed to be a keyframe — but a demuxer can hand us an audio\n // packet with a lower timestamp, which mediabunny rejects with\n // \"First packet must be a key packet.\" Force the first video\n // packet out before we let any audio through.\n const forceVideoFirst = firstVideo && !vNext.done;\n\n if (!vNext.done && (forceVideoFirst || vTs <= aTs)) {\n await videoSource.add(\n vNext.value,\n firstVideo && videoConfig ? { decoderConfig: videoConfig } : undefined,\n );\n firstVideo = false;\n stats.videoPackets++;\n vNext = await videoIter.next();\n } else if (audioIter && audioSource && !aNext.done) {\n await audioSource.add(\n aNext.value,\n firstAudio && audioConfig ? { decoderConfig: audioConfig } : undefined,\n );\n firstAudio = false;\n stats.audioPackets++;\n aNext = await audioIter.next();\n } else {\n break;\n }\n }\n\n if (!destroyed && pumpToken === token) {\n await output.finalize();\n sink?.endOfStream();\n }\n }\n\n return {\n async start(fromTime = 0, autoPlay = false) {\n // Store autoPlay/seekTime so the MseSink (created lazily on first\n // write) can apply the deferred seek and auto-play.\n pendingAutoPlay = autoPlay;\n pendingStartTime = fromTime;\n pumpLoop(++pumpToken, fromTime).catch((err) => {\n // eslint-disable-next-line no-console\n console.error(\"[avbridge] remux pipeline failed:\", err);\n try { sink?.destroy(); } catch { /* ignore */ }\n });\n },\n async seek(time, autoPlay = false) {\n if (sink) {\n sink.setPlayOnSeek(autoPlay);\n sink.invalidate(time);\n } else {\n pendingAutoPlay = autoPlay;\n pendingStartTime = time;\n }\n pumpLoop(++pumpToken, time).catch((err) => {\n // eslint-disable-next-line no-console\n console.error(\"[avbridge] remux pipeline reseek failed:\", err);\n });\n },\n setAutoPlay(autoPlay) {\n pendingAutoPlay = autoPlay;\n if (sink) sink.setPlayOnSeek(autoPlay);\n },\n async destroy() {\n destroyed = true;\n pumpToken++;\n try { if (currentOutput) await currentOutput.cancel(); } catch { /* ignore */ }\n try { await input.dispose(); } catch { /* ignore */ }\n sink?.destroy();\n },\n stats() {\n return { ...stats, decoderType: \"remux\" };\n },\n };\n}\n\n","import type { MediaContext, PlaybackSession } from \"../../types.js\";\nimport { createRemuxPipeline, type RemuxPipeline } from \"./pipeline.js\";\n\n/**\n * Strategy entry: build the remux pipeline, then expose a {@link PlaybackSession}\n * that delegates to the underlying `<video>` element for playback control and\n * to the pipeline for source-side seek invalidation.\n */\nexport async function createRemuxSession(\n context: MediaContext,\n video: HTMLVideoElement,\n): Promise<PlaybackSession> {\n let pipeline: RemuxPipeline;\n try {\n pipeline = await createRemuxPipeline(context, video);\n } catch (err) {\n throw new Error(\n `remux strategy failed to start: ${(err as Error).message}. The container or codec combination is not supported by mediabunny + MSE on this browser.`,\n );\n }\n\n // Don't pump yet — wait for the first play() or seek() to start from the\n // right position. The player's strategy-switch flow calls seek(currentTime)\n // immediately after creation, so pumping from 0 here would be wasted work.\n let started = false;\n let wantPlay = false;\n\n return {\n strategy: \"remux\",\n async play() {\n wantPlay = true;\n if (!started) {\n // First play — start the pump. The deferred seek in MseSink will\n // call video.play() once data is available (via autoPlay flag).\n started = true;\n await pipeline.start(video.currentTime || 0, true);\n return;\n }\n // seek() may have already started the pump with autoPlay=false\n // (strategy-switch flow calls seek before play). Flip the pipeline's\n // pending autoPlay so the MseSink fires video.play() once buffered\n // data lands, and also attempt an immediate video.play() in case the\n // sink is already wired up. The immediate call can reject when\n // video.src hasn't been set yet — that's fine, the deferred path will\n // catch it.\n pipeline.setAutoPlay(true);\n try {\n await video.play();\n } catch {\n /* sink not ready yet; setAutoPlay will handle playback on first buffered write */\n }\n },\n pause() {\n wantPlay = false;\n video.pause();\n },\n async seek(time) {\n if (!started) {\n started = true;\n // autoPlay=true so playback starts as soon as data arrives at\n // the seek target (handles the strategy-switch case where play()\n // is called right after seek()).\n await pipeline.seek(time, wantPlay);\n return;\n }\n const wasPlaying = !video.paused;\n await pipeline.seek(time, wasPlaying || wantPlay);\n },\n async setAudioTrack(_id) {\n // v1: single-track output. Multi-audio remuxing is post-MVP.\n },\n async setSubtitleTrack(id) {\n const tracks = video.textTracks;\n for (let i = 0; i < tracks.length; i++) {\n tracks[i].mode = i === id ? \"showing\" : \"disabled\";\n }\n },\n getCurrentTime() {\n return video.currentTime || 0;\n },\n async destroy() {\n video.pause();\n await pipeline.destroy();\n video.removeAttribute(\"src\");\n video.load();\n },\n getRuntimeStats() {\n return pipeline.stats();\n },\n };\n}\n","import type { ClockSource } from \"./audio-output.js\";\n\n/**\n * Renders decoded `VideoFrame`s into a 2D canvas overlaid on the user's\n * `<video>` element. The fallback strategy never assigns a src to the video,\n * so we hide it and put the canvas in its place visually.\n *\n * The renderer has two modes:\n *\n * 1. **Pre-roll** — `clock.isPlaying()` is false. The very first decoded\n * frame is painted as a \"poster\" so the user sees something while audio\n * buffers; subsequent frames stay queued without being dropped.\n *\n * 2. **Synced** — `clock.isPlaying()` is true. On each rAF tick, find the\n * latest frame whose timestamp ≤ `clock.now() + lookahead` and paint it.\n * Drop any older frames as \"late.\"\n *\n * The pre-roll behavior is what fixes the cold-start \"first minute is all\n * dropped\" problem: without it, the wall clock raced ahead while the\n * decoder was still warming up, and every frame was already in the past by\n * the time it landed in the queue.\n */\n// Periodic debug log — throttled to once per second so it doesn't\n// flood the console at 60Hz rAF rate.\nfunction isDebug(): boolean {\n return typeof globalThis !== \"undefined\" && !!(globalThis as Record<string, unknown>).AVBRIDGE_DEBUG;\n}\nlet lastDebugLog = 0;\n\nexport class VideoRenderer {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private queue: VideoFrame[] = [];\n private rafHandle: number | null = null;\n private destroyed = false;\n\n private framesPainted = 0;\n private framesDroppedLate = 0;\n private framesDroppedOverflow = 0;\n private prerolled = false;\n /** Wall-clock time of the last paint, in ms (performance.now()). */\n private lastPaintWall = 0;\n /** Minimum ms between paints — paces video at roughly source fps. */\n private paintIntervalMs: number;\n /** Cumulative count of frames skipped because all PTS are in the future. */\n private ticksWaiting = 0;\n /** Cumulative count of ticks where PTS mode painted a frame. */\n private ticksPainted = 0;\n\n /**\n * Calibration offset (microseconds) between video PTS and audio clock.\n * Video PTS and AudioContext.currentTime can drift ~0.1% relative to\n * each other (different clock domains). Over 45 minutes that's 2.6s.\n * We measure the offset on the first painted frame and update it\n * periodically so the PTS comparison stays calibrated.\n */\n private ptsCalibrationUs = 0;\n private ptsCalibrated = false;\n private lastCalibrationWall = 0;\n\n /** Resolves once the first decoded frame has been enqueued. */\n readonly firstFrameReady: Promise<void>;\n private resolveFirstFrame!: () => void;\n\n constructor(\n private readonly target: HTMLVideoElement,\n private readonly clock: ClockSource,\n fps = 30,\n ) {\n this.paintIntervalMs = Math.max(1, 1000 / fps);\n this.firstFrameReady = new Promise<void>((resolve) => {\n this.resolveFirstFrame = resolve;\n });\n\n this.canvas = document.createElement(\"canvas\");\n // object-fit:contain letterboxes the canvas bitmap (sized to\n // frame.displayWidth × displayHeight in paint()) inside the stage so\n // portrait / non-stage-aspect content isn't stretched. Canvas is a\n // replaced element, so object-fit applies.\n this.canvas.style.cssText =\n \"position:absolute;left:0;top:0;width:100%;height:100%;background:black;object-fit:contain;\";\n\n // Attach the canvas next to the video. When the video lives inside an\n // `<avbridge-video>` shadow root, `target.parentElement` is the\n // positioned `<div part=\"stage\">` wrapper the element created\n // precisely for this purpose. When the video is used standalone\n // (legacy `createPlayer({ target: videoEl })` path), we fall back to\n // `parentNode` — which handles plain Elements, and also ShadowRoots\n // if someone inserts a bare <video> inside their own shadow DOM\n // without a wrapper.\n const parent: ParentNode | null =\n (target.parentElement as ParentNode | null) ?? target.parentNode;\n if (parent && parent instanceof HTMLElement) {\n if (getComputedStyle(parent).position === \"static\") {\n parent.style.position = \"relative\";\n }\n }\n if (parent) {\n parent.insertBefore(this.canvas, target);\n } else {\n // No parent at all — the target is detached. Fall back to appending\n // the canvas to document.body so at least the frames are visible\n // somewhere while the consumer fixes their DOM layout. This is a\n // loud fallback: log a warning so the misuse is obvious.\n // eslint-disable-next-line no-console\n console.warn(\n \"[avbridge] fallback renderer: target <video> has no parent; \" +\n \"appending canvas to document.body as a fallback.\",\n );\n document.body.appendChild(this.canvas);\n }\n target.style.visibility = \"hidden\";\n\n const ctx = this.canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"video renderer: failed to acquire 2D context\");\n this.ctx = ctx;\n\n this.tick = this.tick.bind(this);\n this.rafHandle = requestAnimationFrame(this.tick);\n }\n\n /** True once at least one frame has been enqueued. */\n hasFrames(): boolean {\n return this.queue.length > 0 || this.framesPainted > 0;\n }\n\n /** Current depth of the frame queue. Used by the decoder for backpressure. */\n queueDepth(): number {\n return this.queue.length;\n }\n\n /**\n * Soft cap for decoder backpressure. The decoder pump throttles when\n * `queueDepth() >= queueHighWater`. Set high enough that normal decode\n * bursts don't trigger the renderer's overflow-drop loop (which runs at\n * every paint), but low enough that the decoder doesn't run unboundedly\n * ahead. The hard cap in `enqueue()` is 64.\n */\n readonly queueHighWater = 30;\n\n enqueue(frame: VideoFrame): void {\n if (this.destroyed) {\n frame.close();\n return;\n }\n this.queue.push(frame);\n if (this.queue.length === 1 && this.framesPainted === 0) {\n this.resolveFirstFrame();\n }\n // Hard cap. Should rarely trigger because the decoder backs off at\n // queueHighWater (30) and the drift correction trims gently. This is\n // the last-resort defense against runaway producers.\n while (this.queue.length > 60) {\n this.queue.shift()?.close();\n this.framesDroppedOverflow++;\n }\n }\n\n private tick(): void {\n if (this.destroyed) return;\n this.rafHandle = requestAnimationFrame(this.tick);\n\n if (this.queue.length === 0) return;\n\n const playing = this.clock.isPlaying();\n\n // Pre-roll: paint the very first frame as a poster while audio buffers.\n if (!playing) {\n if (!this.prerolled) {\n const head = this.queue.shift()!;\n this.paint(head);\n head.close();\n this.prerolled = true;\n this.lastPaintWall = performance.now();\n }\n return;\n }\n\n // PTS-based painting: find the latest frame whose presentation time\n // has arrived (timestamp ≤ audio clock), paint it, and discard any\n // older frames. This produces correct cadence at any display refresh\n // rate and any source fps — no 3:2 pulldown artifacts.\n //\n // Fallback: if frame timestamps are unreliable (all zero, synthetic),\n // fall back to wall-clock pacing as before.\n const rawAudioNowUs = this.clock.now() * 1_000_000;\n const headTs = this.queue[0].timestamp ?? 0;\n const hasPts = headTs > 0 || this.queue.length > 1;\n\n if (hasPts) {\n // Calibration: video PTS and audio clock (AudioContext.currentTime)\n // live in different clock domains with a fixed offset (different epoch)\n // plus a small rate drift (~7ms/s). We snap the offset on first paint\n // and re-snap every 10 seconds. Between snaps, max drift is ~70ms\n // (under 2 frames at 24fps, below lip-sync perception threshold).\n const wallNow = performance.now();\n if (!this.ptsCalibrated || wallNow - this.lastCalibrationWall > 10_000) {\n this.ptsCalibrationUs = headTs - rawAudioNowUs;\n this.ptsCalibrated = true;\n this.lastCalibrationWall = wallNow;\n }\n\n const audioNowUs = rawAudioNowUs + this.ptsCalibrationUs;\n const frameDurationUs = this.paintIntervalMs * 1000;\n const deadlineUs = audioNowUs + frameDurationUs;\n\n let bestIdx = -1;\n for (let i = 0; i < this.queue.length; i++) {\n const ts = this.queue[i].timestamp ?? 0;\n if (ts <= deadlineUs) {\n bestIdx = i;\n } else {\n break;\n }\n }\n\n if (bestIdx < 0) {\n this.ticksWaiting++;\n if (isDebug()) {\n const now = performance.now();\n if (now - lastDebugLog > 1000) {\n const headPtsMs = (headTs / 1000).toFixed(1);\n const audioMs = (audioNowUs / 1000).toFixed(1);\n const rawDriftMs = ((headTs - rawAudioNowUs) / 1000).toFixed(1);\n const calibMs = (this.ptsCalibrationUs / 1000).toFixed(1);\n // eslint-disable-next-line no-console\n console.log(\n `[avbridge:renderer] WAIT q=${this.queue.length} headPTS=${headPtsMs}ms calibAudio=${audioMs}ms ` +\n `rawDrift=${rawDriftMs}ms calib=${calibMs}ms painted=${this.framesPainted} dropped=${this.framesDroppedLate}`,\n );\n lastDebugLog = now;\n }\n }\n return;\n }\n\n // Only drop frames that are more than 2 frame-durations behind.\n const dropThresholdUs = audioNowUs - frameDurationUs * 2;\n let dropped = 0;\n while (bestIdx > 0) {\n const ts = this.queue[0].timestamp ?? 0;\n if (ts < dropThresholdUs) {\n this.queue.shift()?.close();\n this.framesDroppedLate++;\n bestIdx--;\n dropped++;\n } else {\n break;\n }\n }\n\n this.ticksPainted++;\n\n if (isDebug()) {\n const now = performance.now();\n if (now - lastDebugLog > 1000) {\n const paintedTs = (this.queue[0]?.timestamp ?? 0);\n const audioMs = (audioNowUs / 1000).toFixed(1);\n const ptsMs = (paintedTs / 1000).toFixed(1);\n const rawDriftMs = ((paintedTs - rawAudioNowUs) / 1000).toFixed(1);\n const calibMs = (this.ptsCalibrationUs / 1000).toFixed(1);\n // eslint-disable-next-line no-console\n console.log(\n `[avbridge:renderer] PAINT q=${this.queue.length} calibAudio=${audioMs}ms nextPTS=${ptsMs}ms ` +\n `rawDrift=${rawDriftMs}ms calib=${calibMs}ms dropped=${dropped} total_drops=${this.framesDroppedLate} painted=${this.framesPainted}`,\n );\n lastDebugLog = now;\n }\n }\n\n const frame = this.queue.shift()!;\n this.paint(frame);\n frame.close();\n this.lastPaintWall = performance.now();\n return;\n }\n\n // Wall-clock fallback: used when timestamps are unreliable (all zero).\n const wallNow = performance.now();\n if (wallNow - this.lastPaintWall < this.paintIntervalMs - 2) return;\n\n const frame = this.queue.shift()!;\n this.paint(frame);\n frame.close();\n this.lastPaintWall = wallNow;\n }\n\n private paint(frame: VideoFrame): void {\n if (\n this.canvas.width !== frame.displayWidth ||\n this.canvas.height !== frame.displayHeight\n ) {\n this.canvas.width = frame.displayWidth;\n this.canvas.height = frame.displayHeight;\n }\n try {\n this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);\n this.framesPainted++;\n } catch (err) {\n // Log only once so a structurally broken frame format doesn't spam\n // the console at 60 Hz, but we still find out about it.\n if (this.framesPainted === 0 && this.framesDroppedLate === 0) {\n // eslint-disable-next-line no-console\n console.warn(\"[avbridge] canvas drawImage failed:\", err);\n }\n }\n }\n\n /** Discard all queued frames. Used by seek to drop stale buffers. */\n flush(): void {\n const count = this.queue.length;\n while (this.queue.length > 0) this.queue.shift()?.close();\n this.prerolled = false;\n this.ptsCalibrated = false; // recalibrate at new seek position\n if (isDebug() && count > 0) {\n // eslint-disable-next-line no-console\n console.log(`[avbridge:renderer] FLUSH discarded=${count} painted=${this.framesPainted} drops=${this.framesDroppedLate}`);\n }\n }\n\n stats(): Record<string, unknown> {\n return {\n framesPainted: this.framesPainted,\n framesDroppedLate: this.framesDroppedLate,\n framesDroppedOverflow: this.framesDroppedOverflow,\n queueDepth: this.queue.length,\n };\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.rafHandle != null) cancelAnimationFrame(this.rafHandle);\n this.flush();\n this.canvas.remove();\n this.target.style.visibility = \"\";\n }\n}\n","/**\n * Web Audio output for the fallback strategy.\n *\n * Owns the **media-time clock** for fallback playback. Audio is the master:\n * decoded video frames are presented based on what `now()` returns here.\n *\n * State machine:\n *\n * ┌──────┐ schedule() ┌──────┐ ┌────────┐\n * │ idle │ ───────────▶ │ idle │ ── start() ──▶│ playing│\n * └──────┘ (queues) └──────┘ └────┬───┘\n * ▲ │\n * │ │ pause()\n * │ ▼\n * │ ┌────────┐\n * └────────────── reset(t) ─────────────── ── │ paused │\n * └────────┘\n *\n * - **idle**: AudioContext is suspended (no playback). `schedule()` queues\n * samples in `pendingQueue`; `now()` returns `mediaTimeOfAnchor`.\n * - **playing**: AudioContext is running. `schedule()` writes directly to\n * the audio graph at the right time. `now()` advances with `ctx.currentTime`.\n * - **paused**: AudioContext is suspended. `now()` returns the media time\n * captured at pause. `start()` resumes.\n *\n * Key invariant: between any two `start()` calls, `mediaTimeOfNext` (the\n * media time of the next sample to be scheduled) must equal the media time\n * the playback is at. This is what makes the cold-start race go away — we\n * never schedule audio with a stale wall-clock anchor.\n */\n\ninterface PendingChunk {\n samples: Float32Array;\n channels: number;\n sampleRate: number;\n frameCount: number;\n durationSec: number;\n}\n\nexport interface ClockSource {\n /** Current media time in seconds. */\n now(): number;\n /** True if media is currently playing (audio scheduler is running). */\n isPlaying(): boolean;\n}\n\nexport class AudioOutput implements ClockSource {\n private ctx: AudioContext;\n private gain: GainNode;\n\n private state: \"idle\" | \"playing\" | \"paused\" = \"idle\";\n\n /**\n * Wall-clock fallback mode. When true, this output behaves as if audio\n * is unavailable — `now()` advances from `performance.now()` instead of\n * the audio context, `schedule()` is a no-op, and `bufferAhead()` returns\n * Infinity so the session's `waitForBuffer()` doesn't block on audio.\n *\n * Set by the decoder via {@link setNoAudio} when audio decode init fails.\n * This is what lets video play even when the audio codec isn't supported\n * by the loaded libav variant.\n */\n private noAudio = false;\n /** Wall-clock anchor (ms from `performance.now()`) for noAudio mode. */\n private wallAnchorMs = 0;\n\n /** Media time at which the next sample will be scheduled. */\n private mediaTimeOfNext = 0;\n\n /** Anchor: media time `mediaTimeOfAnchor` corresponds to ctx time `ctxTimeAtAnchor`. */\n private mediaTimeOfAnchor = 0;\n private ctxTimeAtAnchor = 0;\n\n private pendingQueue: PendingChunk[] = [];\n\n private framesScheduled = 0;\n private destroyed = false;\n\n /** User-set volume (0..1). Applied to the gain node. */\n private _volume = 1;\n /** User-set muted flag. When true, gain is forced to 0. */\n private _muted = false;\n\n constructor() {\n this.ctx = new AudioContext();\n this.gain = this.ctx.createGain();\n this.gain.connect(this.ctx.destination);\n }\n\n /** Set volume (0..1). Applied immediately to the gain node. */\n setVolume(v: number): void {\n this._volume = Math.max(0, Math.min(1, v));\n this.applyGain();\n }\n\n getVolume(): number {\n return this._volume;\n }\n\n /** Set muted. When true, output is silenced regardless of volume. */\n setMuted(m: boolean): void {\n this._muted = m;\n this.applyGain();\n }\n\n getMuted(): boolean {\n return this._muted;\n }\n\n private applyGain(): void {\n const target = this._muted ? 0 : this._volume;\n try { this.gain.gain.value = target; } catch { /* ignore */ }\n }\n\n /**\n * Switch into wall-clock fallback mode. Called by the decoder when no\n * audio decoder could be initialized for the source. Once set, this\n * output drives playback time from `performance.now()` and ignores\n * any incoming audio samples.\n */\n setNoAudio(): void {\n this.noAudio = true;\n }\n\n // ── ClockSource ────────────────────────────────────────────────────────\n\n now(): number {\n if (this.noAudio) {\n if (this.state === \"playing\") {\n return this.mediaTimeOfAnchor + (performance.now() - this.wallAnchorMs) / 1000;\n }\n return this.mediaTimeOfAnchor;\n }\n if (this.state === \"playing\") {\n return this.mediaTimeOfAnchor + (this.ctx.currentTime - this.ctxTimeAtAnchor);\n }\n return this.mediaTimeOfAnchor;\n }\n\n isPlaying(): boolean {\n return this.state === \"playing\";\n }\n\n // ── Buffering ─────────────────────────────────────────────────────────\n\n /**\n * How many seconds of audio are buffered ahead of the current playback\n * position. While idle, this counts the pending queue. While playing,\n * it counts how far `mediaTimeOfNext` is ahead of `now()`.\n */\n bufferAhead(): number {\n // In wall-clock mode, no samples are ever scheduled — the buffer is\n // genuinely empty. Callers that want to gate cold-start should check\n // {@link isNoAudio} and skip the audio gate entirely instead.\n if (this.noAudio) return 0;\n if (this.state === \"idle\") {\n let sec = 0;\n for (const c of this.pendingQueue) sec += c.durationSec;\n return sec;\n }\n return Math.max(0, this.mediaTimeOfNext - this.now());\n }\n\n /** True if this output is in wall-clock fallback mode (no audio decode). */\n isNoAudio(): boolean {\n return this.noAudio;\n }\n\n /**\n * Schedule a chunk of decoded samples. Queues internally while idle (cold\n * start or post-seek), schedules directly to the audio graph while playing.\n * In wall-clock mode, samples are silently discarded.\n */\n schedule(samples: Float32Array, channels: number, sampleRate: number): void {\n if (this.destroyed || this.noAudio) return;\n const frameCount = samples.length / channels;\n const durationSec = frameCount / sampleRate;\n\n if (this.state === \"idle\" || this.state === \"paused\") {\n this.pendingQueue.push({ samples, channels, sampleRate, frameCount, durationSec });\n return;\n }\n\n this.scheduleNow(samples, channels, sampleRate, frameCount);\n }\n\n private scheduleNow(\n samples: Float32Array,\n channels: number,\n sampleRate: number,\n frameCount: number,\n ): void {\n const buffer = this.ctx.createBuffer(channels, frameCount, sampleRate);\n for (let ch = 0; ch < channels; ch++) {\n const channelData = buffer.getChannelData(ch);\n for (let i = 0; i < frameCount; i++) {\n channelData[i] = samples[i * channels + ch];\n }\n }\n const node = this.ctx.createBufferSource();\n node.buffer = buffer;\n node.connect(this.gain);\n\n // Convert media time → ctx time using the anchor.\n let ctxStart = this.ctxTimeAtAnchor + (this.mediaTimeOfNext - this.mediaTimeOfAnchor);\n\n // When the decoder is slower than realtime, `ctxStart` falls into\n // the past (ctx.currentTime has already passed it). Clamping each\n // sample to `ctx.currentTime` individually (the old behavior)\n // caused every stale sample in a burst to start at *the same\n // instant*, stacking them on top of each other — the audible\n // symptom was a series of clicks / a chord of stuttering cook\n // packets.\n //\n // Correct behavior: when the first sample of a burst is behind,\n // *rebase the anchor forward* so ctxStart = ctx.currentTime now.\n // Subsequent samples in the same burst then schedule at\n // ctxStart + offset as usual, laying out sequentially on the\n // timeline instead of piling up. The downside is a visible jump\n // in the audio clock — but the alternative was silent corruption.\n // `now()` readers (the video renderer) just see the clock step\n // forward and drop any frames older than the new time.\n if (ctxStart < this.ctx.currentTime) {\n this.ctxTimeAtAnchor = this.ctx.currentTime;\n this.mediaTimeOfAnchor = this.mediaTimeOfNext;\n ctxStart = this.ctx.currentTime;\n }\n\n node.start(ctxStart);\n\n this.mediaTimeOfNext += frameCount / sampleRate;\n this.framesScheduled++;\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────────\n\n /**\n * Start (or resume) playback. On a cold start (or after a reset), drains\n * the pending queue scheduling all queued samples to play starting at\n * `ctx.currentTime + STARTUP_DELAY`. On resume from pause, just re-anchors\n * the media↔ctx time mapping and unsuspends the context.\n */\n async start(): Promise<void> {\n if (this.destroyed || this.state === \"playing\") return;\n\n // Wall-clock mode: no audio context involved. Anchor to performance.now()\n // and let `now()` advance from there. The renderer's tick loop will see\n // `isPlaying() === true` and start painting frames.\n if (this.noAudio) {\n this.wallAnchorMs = performance.now();\n this.state = \"playing\";\n return;\n }\n\n if (this.ctx.state === \"suspended\") {\n await this.ctx.resume();\n }\n\n if (this.state === \"paused\") {\n // Resume: media time should continue from where we paused. ctx.currentTime\n // is preserved across suspend/resume, so re-anchoring it to \"now\" with\n // the same mediaTimeOfAnchor gives a continuous clock.\n this.ctxTimeAtAnchor = this.ctx.currentTime;\n this.state = \"playing\";\n // Drain anything that was scheduled while paused.\n const drain = this.pendingQueue;\n this.pendingQueue = [];\n for (const c of drain) {\n this.scheduleNow(c.samples, c.channels, c.sampleRate, c.frameCount);\n }\n return;\n }\n\n // Cold start (or post-seek). Anchor: the first sample we scheduled lands\n // at ctxTimeAtAnchor (a tiny bit in the future), and that ctx time\n // corresponds to media time mediaTimeOfAnchor.\n const STARTUP_DELAY = 0.05;\n this.ctxTimeAtAnchor = this.ctx.currentTime + STARTUP_DELAY;\n this.mediaTimeOfNext = this.mediaTimeOfAnchor;\n this.state = \"playing\";\n\n const drain = this.pendingQueue;\n this.pendingQueue = [];\n for (const c of drain) {\n this.scheduleNow(c.samples, c.channels, c.sampleRate, c.frameCount);\n }\n }\n\n /** Pause playback. Suspends the audio context. */\n async pause(): Promise<void> {\n if (this.state !== \"playing\") return;\n this.mediaTimeOfAnchor = this.now();\n this.state = \"paused\";\n if (this.noAudio) return;\n if (this.ctx.state === \"running\") {\n await this.ctx.suspend();\n }\n }\n\n /**\n * Reset to a new media time. Discards all queued and scheduled audio,\n * disconnects the gain node so any in-flight scheduled buffers are cut\n * off, and returns to the idle state. Used by `seek()`.\n *\n * After reset, callers should re-buffer audio (the decoder will start\n * supplying new samples) and then call `start()` to resume playback.\n */\n async reset(newMediaTime: number): Promise<void> {\n if (this.noAudio) {\n this.pendingQueue = [];\n this.mediaTimeOfAnchor = newMediaTime;\n this.wallAnchorMs = performance.now();\n this.state = \"idle\";\n return;\n }\n\n try { this.gain.disconnect(); } catch { /* ignore */ }\n this.gain = this.ctx.createGain();\n this.gain.connect(this.ctx.destination);\n this.applyGain();\n\n this.pendingQueue = [];\n this.mediaTimeOfAnchor = newMediaTime;\n this.mediaTimeOfNext = newMediaTime;\n this.ctxTimeAtAnchor = this.ctx.currentTime;\n this.state = \"idle\";\n\n if (this.ctx.state === \"running\") {\n await this.ctx.suspend();\n }\n }\n\n stats(): Record<string, unknown> {\n return {\n framesScheduled: this.framesScheduled,\n bufferAhead: this.bufferAhead(),\n audioState: this.state,\n clockMode: this.noAudio ? \"wall\" : \"audio\",\n };\n }\n\n destroy(): void {\n this.destroyed = true;\n try { this.ctx.close(); } catch { /* ignore */ }\n }\n}\n","import type { MediaContext, AudioCodec, VideoCodec } from \"../../types.js\";\nimport type { LibavVariant } from \"./libav-loader.js\";\n\n/**\n * Decide which libav.js variant to load for a given media context.\n *\n * - **webcodecs** (~5 MB, npm) — modern formats only, designed for the\n * WebCodecs bridge. Used when the codec is browser-supported and we just\n * need libav.js for demuxing or as a parser source.\n *\n * - **avbridge** (custom build, vendor/libav/) — has the AVI/ASF/FLV demuxers\n * and the legacy decoders (WMV3, MPEG-4 Part 2, VC-1, MS-MPEG4 v1/2/3,\n * AC-3, WMA*). Required for any of those formats; the npm variants ship\n * none of them.\n *\n * Rule: pick \"avbridge\" if either the container or any codec is one only the\n * custom build can handle. Otherwise pick \"webcodecs\".\n */\n\nconst LEGACY_CONTAINERS = new Set([\"avi\", \"asf\", \"flv\"]);\n\n/** Codecs the webcodecs variant can handle (native browser codecs only).\n * Anything not in these sets needs the custom avbridge variant. */\nconst WEBCODECS_AUDIO = new Set<AudioCodec>([\"aac\", \"mp3\", \"opus\", \"vorbis\", \"flac\"]);\nconst WEBCODECS_VIDEO = new Set<VideoCodec>([\"h264\", \"h265\", \"vp8\", \"vp9\", \"av1\"]);\n\nexport function pickLibavVariant(ctx: MediaContext): LibavVariant {\n if (LEGACY_CONTAINERS.has(ctx.container)) return \"avbridge\";\n for (const v of ctx.videoTracks) {\n // Any codec the webcodecs variant can't handle → need avbridge\n if (!WEBCODECS_VIDEO.has(v.codec)) return \"avbridge\";\n }\n for (const a of ctx.audioTracks) {\n if (!WEBCODECS_AUDIO.has(a.codec)) return \"avbridge\";\n }\n return \"webcodecs\";\n}\n","/**\n * Hybrid decoder: libav.js demux + WebCodecs VideoDecoder + libav audio decode.\n *\n * This is the hardware-accelerated path for files in containers mediabunny\n * can't read (AVI, ASF, FLV) but whose codecs ARE browser-supported.\n * libav.js handles demuxing, then:\n *\n * - **Video**: bridge.packetToEncodedVideoChunk → VideoDecoder (hardware)\n * - **Audio**: libav ff_decode_multi (software). Chrome's AudioDecoder\n * rejects raw MP3 packets from AVI, and audio decode is cheap enough\n * that software decode is fine.\n *\n * The demux pump loop, seek handling, and synthetic timestamp logic mirror\n * fallback/decoder.ts. The key difference is the video decode path.\n */\n\nimport { loadLibav, type LibavVariant } from \"../fallback/libav-loader.js\";\nimport { VideoRenderer } from \"../fallback/video-renderer.js\";\nimport { AudioOutput } from \"../fallback/audio-output.js\";\nimport type { MediaContext } from \"../../types.js\";\nimport { dbg } from \"../../util/debug.js\";\nimport { pickLibavVariant } from \"../fallback/variant-routing.js\";\n\nexport interface HybridDecoderHandles {\n destroy(): Promise<void>;\n seek(timeSec: number): Promise<void>;\n stats(): Record<string, unknown>;\n onFatalError(handler: (reason: string) => void): void;\n}\n\nexport interface StartHybridDecoderOptions {\n /** Normalized source — either a Blob in memory or a URL we'll stream via Range requests. */\n source: import(\"../../util/source.js\").NormalizedSource;\n filename: string;\n context: MediaContext;\n renderer: VideoRenderer;\n audio: AudioOutput;\n transport?: import(\"../../types.js\").TransportConfig;\n}\n\nexport async function startHybridDecoder(opts: StartHybridDecoderOptions): Promise<HybridDecoderHandles> {\n const variant: LibavVariant = pickLibavVariant(opts.context);\n const libav = (await loadLibav(variant)) as unknown as LibavRuntime;\n const bridge = await loadBridge();\n\n // For URL sources, prepareLibavInput attaches an HTTP block reader so\n // libav demuxes via Range requests. For Blob sources, it falls back to\n // mkreadaheadfile (in-memory). The returned handle owns cleanup.\n const { prepareLibavInput } = await import(\"../../util/libav-http-reader.js\");\n const inputHandle = await prepareLibavInput(libav as unknown as Parameters<typeof prepareLibavInput>[0], opts.filename, opts.source, opts.transport);\n\n const readPkt = await libav.av_packet_alloc();\n const [fmt_ctx, streams] = await libav.ff_init_demuxer_file(opts.filename);\n const videoStream = streams.find((s) => s.codec_type === libav.AVMEDIA_TYPE_VIDEO) ?? null;\n const audioStream = streams.find((s) => s.codec_type === libav.AVMEDIA_TYPE_AUDIO) ?? null;\n\n if (!videoStream && !audioStream) {\n throw new Error(\"hybrid decoder: file has no decodable streams\");\n }\n\n // ── Fatal error callback ──────────────────────────────────────────────\n let fatalHandler: ((reason: string) => void) | null = null;\n let fatalFired = false;\n\n function fireFatal(reason: string): void {\n if (fatalFired) return;\n fatalFired = true;\n fatalHandler?.(reason);\n }\n\n // ── WebCodecs VideoDecoder ────────────────────────────────────────────\n let videoDecoder: VideoDecoder | null = null;\n let videoTimeBase: [number, number] | undefined;\n\n if (videoStream) {\n try {\n const config = await bridge.videoStreamToConfig(libav, videoStream);\n if (!config) throw new Error(\"bridge returned null config\");\n\n const supported = await VideoDecoder.isConfigSupported(config);\n if (!supported.supported) throw new Error(`VideoDecoder does not support config: ${JSON.stringify(config)}`);\n\n videoDecoder = new VideoDecoder({\n output: (frame: VideoFrame) => {\n opts.renderer.enqueue(frame);\n videoFramesDecoded++;\n },\n error: (err: DOMException) => {\n console.error(\"[avbridge] WebCodecs VideoDecoder error:\", err);\n fireFatal(`WebCodecs VideoDecoder error: ${err.message}`);\n },\n });\n videoDecoder.configure(config);\n\n if (videoStream.time_base_num && videoStream.time_base_den) {\n videoTimeBase = [videoStream.time_base_num, videoStream.time_base_den];\n }\n } catch (err) {\n console.error(\"[avbridge] hybrid: failed to init WebCodecs VideoDecoder:\", err);\n fireFatal(`WebCodecs VideoDecoder init failed: ${(err as Error).message}`);\n // Clean up and throw — the player will escalate to fallback\n await inputHandle.detach().catch(() => {});\n throw err;\n }\n }\n\n // ── libav software AudioDecoder ───────────────────────────────────────\n let audioDec: SoftDecoder | null = null;\n let audioTimeBase: [number, number] | undefined;\n\n if (audioStream) {\n try {\n const [, c, pkt, frame] = await libav.ff_init_decoder(audioStream.codec_id, {\n codecpar: audioStream.codecpar,\n });\n audioDec = { c, pkt, frame };\n if (audioStream.time_base_num && audioStream.time_base_den) {\n audioTimeBase = [audioStream.time_base_num, audioStream.time_base_den];\n }\n } catch (err) {\n console.warn(\n \"[avbridge] hybrid: audio decoder unavailable for this codec — playing video with wall-clock timing:\",\n (err as Error).message,\n );\n }\n }\n\n // No audio decoder? Switch the audio output into wall-clock mode so the\n // video renderer doesn't stall waiting for an audio clock that never starts.\n if (!audioDec) {\n opts.audio.setNoAudio();\n }\n\n if (!videoDecoder && !audioDec) {\n await inputHandle.detach().catch(() => {});\n throw new Error(\"hybrid decoder: could not initialize any decoders\");\n }\n\n // ── Bitstream filter for MPEG-4 Part 2 packed B-frames ───────────────\n let bsfCtx: number | null = null;\n let bsfPkt: number | null = null;\n if (videoStream && opts.context.videoTracks[0]?.codec === \"mpeg4\") {\n try {\n bsfCtx = await libav.av_bsf_list_parse_str_js(\"mpeg4_unpack_bframes\");\n if (bsfCtx != null && bsfCtx >= 0) {\n const parIn = await libav.AVBSFContext_par_in(bsfCtx);\n await libav.avcodec_parameters_copy(parIn, videoStream.codecpar);\n await libav.av_bsf_init(bsfCtx);\n bsfPkt = await libav.av_packet_alloc();\n dbg.info(\"bsf\", \"mpeg4_unpack_bframes BSF active (hybrid)\");\n } else {\n // eslint-disable-next-line no-console\n console.warn(\"[avbridge] mpeg4_unpack_bframes BSF not available in hybrid decoder\");\n bsfCtx = null;\n }\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\"[avbridge] hybrid: failed to init BSF:\", (err as Error).message);\n bsfCtx = null;\n bsfPkt = null;\n }\n }\n\n async function applyBSF(packets: LibavPacket[]): Promise<LibavPacket[]> {\n if (!bsfCtx || !bsfPkt) return packets;\n const out: LibavPacket[] = [];\n for (const pkt of packets) {\n await libav.ff_copyin_packet(bsfPkt, pkt);\n const sendErr = await libav.av_bsf_send_packet(bsfCtx, bsfPkt);\n if (sendErr < 0) { out.push(pkt); continue; }\n while (true) {\n const recvErr = await libav.av_bsf_receive_packet(bsfCtx, bsfPkt);\n if (recvErr < 0) break;\n out.push(await libav.ff_copyout_packet(bsfPkt));\n }\n }\n return out;\n }\n\n async function flushBSF(): Promise<void> {\n if (!bsfCtx || !bsfPkt) return;\n try {\n await libav.av_bsf_send_packet(bsfCtx, 0);\n while (true) {\n const err = await libav.av_bsf_receive_packet(bsfCtx, bsfPkt);\n if (err < 0) break;\n }\n } catch { /* ignore */ }\n }\n\n // ── Mutable state ─────────────────────────────────────────────────────\n let destroyed = false;\n let pumpToken = 0;\n let pumpRunning: Promise<void> | null = null;\n\n let packetsRead = 0;\n let videoFramesDecoded = 0;\n let audioFramesDecoded = 0;\n let videoChunksFed = 0;\n\n let syntheticVideoUs = 0;\n let syntheticAudioUs = 0;\n\n const videoTrackInfo = opts.context.videoTracks.find((t) => t.id === videoStream?.index);\n const videoFps = videoTrackInfo?.fps && videoTrackInfo.fps > 0 ? videoTrackInfo.fps : 30;\n const videoFrameStepUs = Math.max(1, Math.round(1_000_000 / videoFps));\n\n // ── Pump loop ─────────────────────────────────────────────────────────\n\n async function pumpLoop(myToken: number): Promise<void> {\n while (!destroyed && myToken === pumpToken) {\n let readErr: number;\n let packets: Record<number, LibavPacket[]>;\n try {\n [readErr, packets] = await libav.ff_read_frame_multi(fmt_ctx, readPkt, {\n limit: 16 * 1024,\n });\n } catch (err) {\n console.error(\"[avbridge] hybrid ff_read_frame_multi failed:\", err);\n return;\n }\n\n if (myToken !== pumpToken || destroyed) return;\n\n const videoPackets = videoStream ? packets[videoStream.index] : undefined;\n const audioPackets = audioStream ? packets[audioStream.index] : undefined;\n\n // Decode audio BEFORE video. Same rationale as fallback decoder\n // (POSTMORTEMS.md entry 1, fix #2): audio decode via libav's\n // ff_decode_multi is a blocking WASM call that prevents rAF from\n // firing. For heavy codecs like DTS, a single batch can take\n // 10-50 ms. Processing audio first ensures the audio scheduler is\n // fed before video decode starts, reducing perceived stutter.\n if (audioDec && audioPackets && audioPackets.length > 0) {\n await decodeAudioBatch(audioPackets, myToken);\n }\n if (myToken !== pumpToken || destroyed) return;\n\n // Yield to the event loop so the video renderer's rAF callback\n // can fire between the audio decode (blocking) and the video feed\n // (async). Without this, the renderer starves during DTS decode.\n await new Promise((r) => setTimeout(r, 0));\n if (myToken !== pumpToken || destroyed) return;\n\n // Feed video packets to WebCodecs VideoDecoder (after BSF if applicable)\n if (videoDecoder && videoPackets && videoPackets.length > 0) {\n const processed = await applyBSF(videoPackets);\n for (const pkt of processed) {\n if (myToken !== pumpToken || destroyed) return;\n sanitizePacketTimestamp(pkt, () => {\n const ts = syntheticVideoUs;\n syntheticVideoUs += videoFrameStepUs;\n return ts;\n }, videoTimeBase);\n try {\n const chunk = bridge.packetToEncodedVideoChunk(pkt, videoStream);\n videoDecoder.decode(chunk);\n videoChunksFed++;\n } catch (err) {\n if (videoChunksFed === 0) {\n console.warn(\"[avbridge] hybrid: packetToEncodedVideoChunk failed:\", err);\n fireFatal(`WebCodecs chunk creation failed: ${(err as Error).message}`);\n return;\n }\n }\n }\n }\n\n packetsRead += (videoPackets?.length ?? 0) + (audioPackets?.length ?? 0);\n\n // Backpressure: WebCodecs decodeQueueSize + audio buffer + renderer queue\n while (\n !destroyed &&\n myToken === pumpToken &&\n ((videoDecoder && videoDecoder.decodeQueueSize > 10) ||\n opts.audio.bufferAhead() > 2.0 ||\n opts.renderer.queueDepth() >= opts.renderer.queueHighWater)\n ) {\n await new Promise((r) => setTimeout(r, 50));\n }\n\n if (readErr === libav.AVERROR_EOF) {\n // Flush WebCodecs decoder\n if (videoDecoder && videoDecoder.state === \"configured\") {\n try { await videoDecoder.flush(); } catch { /* ignore */ }\n }\n // Flush libav audio decoder\n if (audioDec) await decodeAudioBatch([], myToken, true);\n return;\n }\n if (readErr && readErr !== 0 && readErr !== -libav.EAGAIN) {\n console.warn(\"[avbridge] hybrid ff_read_frame_multi returned\", readErr);\n return;\n }\n }\n }\n\n async function decodeAudioBatch(pkts: LibavPacket[], myToken: number, flush = false) {\n if (!audioDec || destroyed || myToken !== pumpToken) return;\n\n // For heavy codecs (DTS, AC3), decode in small sub-batches and yield\n // between them so the event loop can run rAF for video painting.\n // Each ff_decode_multi call is a blocking WASM invocation.\n const AUDIO_SUB_BATCH = 4; // packets per sub-batch\n let allFrames: LibavFrame[] = [];\n\n for (let i = 0; i < pkts.length; i += AUDIO_SUB_BATCH) {\n if (myToken !== pumpToken || destroyed) return;\n const slice = pkts.slice(i, i + AUDIO_SUB_BATCH);\n const isLast = i + AUDIO_SUB_BATCH >= pkts.length;\n try {\n const frames = await libav.ff_decode_multi(\n audioDec.c,\n audioDec.pkt,\n audioDec.frame,\n slice,\n isLast && flush ? { fin: true, ignoreErrors: true } : { ignoreErrors: true },\n );\n allFrames = allFrames.concat(frames);\n } catch (err) {\n console.error(\"[avbridge] hybrid audio decode failed:\", err);\n return;\n }\n // Yield between sub-batches so rAF can fire\n if (!isLast) await new Promise((r) => setTimeout(r, 0));\n }\n\n // Handle flush-only call (empty pkts array)\n if (pkts.length === 0 && flush) {\n try {\n allFrames = await libav.ff_decode_multi(\n audioDec.c, audioDec.pkt, audioDec.frame, [],\n { fin: true, ignoreErrors: true },\n );\n } catch (err) {\n console.error(\"[avbridge] hybrid audio flush failed:\", err);\n return;\n }\n }\n\n if (myToken !== pumpToken || destroyed) return;\n const frames = allFrames;\n\n for (const f of frames) {\n if (myToken !== pumpToken || destroyed) return;\n sanitizeFrameTimestamp(\n f,\n () => {\n const ts = syntheticAudioUs;\n const samples = f.nb_samples ?? 1024;\n const sampleRate = f.sample_rate ?? 44100;\n syntheticAudioUs += Math.round((samples * 1_000_000) / sampleRate);\n return ts;\n },\n audioTimeBase,\n );\n const samples = libavFrameToInterleavedFloat32(f);\n if (samples) {\n opts.audio.schedule(samples.data, samples.channels, samples.sampleRate);\n audioFramesDecoded++;\n }\n }\n }\n\n // Kick off initial pump\n pumpToken = 1;\n pumpRunning = pumpLoop(pumpToken).catch((err) =>\n console.error(\"[avbridge] hybrid pump failed:\", err),\n );\n\n return {\n onFatalError(handler: (reason: string) => void): void {\n fatalHandler = handler;\n // If fatal already fired before handler was attached, fire immediately\n if (fatalFired) handler(\"WebCodecs decode failed (error occurred before handler attached)\");\n },\n\n async destroy() {\n destroyed = true;\n pumpToken++;\n try { await pumpRunning; } catch { /* ignore */ }\n try { if (bsfCtx) await libav.av_bsf_free(bsfCtx); } catch { /* ignore */ }\n try { if (bsfPkt) await libav.av_packet_free?.(bsfPkt); } catch { /* ignore */ }\n try { if (videoDecoder && videoDecoder.state !== \"closed\") videoDecoder.close(); } catch { /* ignore */ }\n try { if (audioDec) await libav.ff_free_decoder?.(audioDec.c, audioDec.pkt, audioDec.frame); } catch { /* ignore */ }\n try { await libav.av_packet_free?.(readPkt); } catch { /* ignore */ }\n try { await libav.avformat_close_input_js(fmt_ctx); } catch { /* ignore */ }\n try { await inputHandle.detach(); } catch { /* ignore */ }\n },\n\n async seek(timeSec) {\n const newToken = ++pumpToken;\n if (pumpRunning) {\n try { await pumpRunning; } catch { /* ignore */ }\n }\n if (destroyed) return;\n\n try {\n const tsUs = Math.floor(timeSec * 1_000_000);\n const [tsLo, tsHi] = libav.f64toi64\n ? libav.f64toi64(tsUs)\n : [tsUs | 0, Math.floor(tsUs / 0x100000000)];\n await libav.av_seek_frame(\n fmt_ctx,\n -1,\n tsLo,\n tsHi,\n libav.AVSEEK_FLAG_BACKWARD ?? 0,\n );\n } catch (err) {\n console.warn(\"[avbridge] hybrid av_seek_frame failed:\", err);\n }\n\n // Flush WebCodecs VideoDecoder\n try {\n if (videoDecoder && videoDecoder.state === \"configured\") {\n await videoDecoder.flush();\n }\n } catch { /* ignore */ }\n\n // Flush libav audio decoder\n try {\n if (audioDec) await libav.avcodec_flush_buffers?.(audioDec.c);\n } catch { /* ignore */ }\n await flushBSF();\n\n syntheticVideoUs = Math.round(timeSec * 1_000_000);\n syntheticAudioUs = Math.round(timeSec * 1_000_000);\n\n pumpRunning = pumpLoop(newToken).catch((err) =>\n console.error(\"[avbridge] hybrid pump failed (post-seek):\", err),\n );\n },\n\n stats() {\n return {\n decoderType: \"webcodecs-hybrid\",\n packetsRead,\n videoFramesDecoded,\n videoChunksFed,\n audioFramesDecoded,\n bsfApplied: bsfCtx ? [\"mpeg4_unpack_bframes\"] : [],\n videoDecodeQueueSize: videoDecoder?.decodeQueueSize ?? 0,\n // Confirmed transport info — see fallback decoder for the pattern.\n _transport: inputHandle.transport === \"http-range\" ? \"http-range\" : \"memory\",\n _rangeSupported: inputHandle.transport === \"http-range\",\n ...opts.renderer.stats(),\n ...opts.audio.stats(),\n };\n },\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Packet timestamp sanitizer for WebCodecs chunks.\n//\n// AVI packets often have AV_NOPTS_VALUE. The bridge's packetToEncodedVideoChunk\n// uses the packet's pts + time_base. We normalize to microseconds with a 1/1e6\n// time_base to avoid overflow.\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction sanitizePacketTimestamp(\n pkt: LibavPacket,\n nextUs: () => number,\n fallbackTimeBase?: [number, number],\n): void {\n const lo = pkt.pts ?? 0;\n const hi = pkt.ptshi ?? 0;\n const isInvalid = (hi === -2147483648 && lo === 0) || !Number.isFinite(lo);\n if (isInvalid) {\n const us = nextUs();\n pkt.pts = us;\n pkt.ptshi = 0;\n pkt.time_base_num = 1;\n pkt.time_base_den = 1_000_000;\n return;\n }\n const tb = fallbackTimeBase ?? [1, 1_000_000];\n const pts64 = hi * 0x100000000 + lo;\n const us = Math.round((pts64 * 1_000_000 * tb[0]) / tb[1]);\n if (Number.isFinite(us) && Math.abs(us) <= Number.MAX_SAFE_INTEGER) {\n pkt.pts = us;\n pkt.ptshi = us < 0 ? -1 : 0;\n pkt.time_base_num = 1;\n pkt.time_base_den = 1_000_000;\n return;\n }\n const fallback = nextUs();\n pkt.pts = fallback;\n pkt.ptshi = 0;\n pkt.time_base_num = 1;\n pkt.time_base_den = 1_000_000;\n}\n\n// Frame timestamp sanitizer (same as fallback/decoder.ts, for audio frames)\nfunction sanitizeFrameTimestamp(\n frame: LibavFrame,\n nextUs: () => number,\n fallbackTimeBase?: [number, number],\n): void {\n const lo = frame.pts ?? 0;\n const hi = frame.ptshi ?? 0;\n const isInvalid = (hi === -2147483648 && lo === 0) || !Number.isFinite(lo);\n if (isInvalid) {\n const us = nextUs();\n frame.pts = us;\n frame.ptshi = 0;\n return;\n }\n const tb = fallbackTimeBase ?? [1, 1_000_000];\n const pts64 = hi * 0x100000000 + lo;\n const us = Math.round((pts64 * 1_000_000 * tb[0]) / tb[1]);\n if (Number.isFinite(us) && Math.abs(us) <= Number.MAX_SAFE_INTEGER) {\n frame.pts = us;\n frame.ptshi = us < 0 ? -1 : 0;\n return;\n }\n const fallback = nextUs();\n frame.pts = fallback;\n frame.ptshi = 0;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Audio frame → interleaved Float32 (duplicated from fallback/decoder.ts)\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst AV_SAMPLE_FMT_U8 = 0;\nconst AV_SAMPLE_FMT_S16 = 1;\nconst AV_SAMPLE_FMT_S32 = 2;\nconst AV_SAMPLE_FMT_FLT = 3;\nconst AV_SAMPLE_FMT_U8P = 5;\nconst AV_SAMPLE_FMT_S16P = 6;\nconst AV_SAMPLE_FMT_S32P = 7;\nconst AV_SAMPLE_FMT_FLTP = 8;\n\ninterface InterleavedSamples {\n data: Float32Array;\n channels: number;\n sampleRate: number;\n}\n\nfunction libavFrameToInterleavedFloat32(frame: LibavFrame): InterleavedSamples | null {\n const channels = frame.channels ?? frame.ch_layout_nb_channels ?? 1;\n const sampleRate = frame.sample_rate ?? 44100;\n const nbSamples = frame.nb_samples ?? 0;\n if (nbSamples === 0) return null;\n\n const out = new Float32Array(nbSamples * channels);\n\n switch (frame.format) {\n case AV_SAMPLE_FMT_FLTP: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asFloat32(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = plane[i];\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_FLT: {\n const flat = asFloat32(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = flat[i];\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S16P: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asInt16(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = plane[i] / 32768;\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S16: {\n const flat = asInt16(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = flat[i] / 32768;\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S32P: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asInt32(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = plane[i] / 2147483648;\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S32: {\n const flat = asInt32(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = flat[i] / 2147483648;\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_U8P: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asUint8(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = (plane[i] - 128) / 128;\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_U8: {\n const flat = asUint8(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = (flat[i] - 128) / 128;\n return { data: out, channels, sampleRate };\n }\n default:\n return null;\n }\n}\n\nfunction ensurePlanes(data: unknown, channels: number): unknown[] {\n if (Array.isArray(data)) return data;\n const arr = data as { length: number; subarray?: (a: number, b: number) => unknown };\n const len = arr.length;\n const perChannel = Math.floor(len / channels);\n const planes: unknown[] = [];\n for (let ch = 0; ch < channels; ch++) {\n planes.push(arr.subarray ? arr.subarray(ch * perChannel, (ch + 1) * perChannel) : arr);\n }\n return planes;\n}\n\nfunction asFloat32(x: unknown): Float32Array {\n if (x instanceof Float32Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Float32Array(ta.buffer, ta.byteOffset, ta.byteLength / 4);\n}\nfunction asInt16(x: unknown): Int16Array {\n if (x instanceof Int16Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Int16Array(ta.buffer, ta.byteOffset, ta.byteLength / 2);\n}\nfunction asInt32(x: unknown): Int32Array {\n if (x instanceof Int32Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Int32Array(ta.buffer, ta.byteOffset, ta.byteLength / 4);\n}\nfunction asUint8(x: unknown): Uint8Array {\n if (x instanceof Uint8Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Uint8Array(ta.buffer, ta.byteOffset, ta.byteLength);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bridge loader\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function loadBridge(): Promise<BridgeModule> {\n try {\n const wrapper = await import(\"../fallback/libav-import.js\");\n return wrapper.libavBridge as unknown as BridgeModule;\n } catch (err) {\n throw new Error(\n `failed to load libavjs-webcodecs-bridge: ${(err as Error).message}`,\n );\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Structural types\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface SoftDecoder {\n c: number;\n pkt: number;\n frame: number;\n}\n\ninterface LibavStream {\n index: number;\n codec_type: number;\n codec_id: number;\n codecpar: number;\n time_base_num?: number;\n time_base_den?: number;\n}\n\ninterface LibavPacket {\n data: Uint8Array;\n pts: number;\n ptshi?: number;\n duration?: number;\n durationhi?: number;\n flags: number;\n stream_index: number;\n time_base_num?: number;\n time_base_den?: number;\n}\n\ninterface LibavFrame {\n data: unknown;\n format: number;\n channels?: number;\n ch_layout_nb_channels?: number;\n sample_rate?: number;\n nb_samples?: number;\n pts?: number;\n ptshi?: number;\n width?: number;\n height?: number;\n}\n\ninterface LibavRuntime {\n AVMEDIA_TYPE_VIDEO: number;\n AVMEDIA_TYPE_AUDIO: number;\n AVERROR_EOF: number;\n EAGAIN: number;\n AVSEEK_FLAG_BACKWARD?: number;\n\n mkreadaheadfile(name: string, blob: Blob): Promise<void>;\n unlinkreadaheadfile(name: string): Promise<void>;\n ff_init_demuxer_file(name: string): Promise<[number, LibavStream[]]>;\n ff_read_frame_multi(\n fmt_ctx: number,\n pkt: number,\n opts?: { limit?: number },\n ): Promise<[number, Record<number, LibavPacket[]>]>;\n ff_init_decoder(\n codec: number | string,\n config?: { codecpar?: number; time_base?: [number, number] },\n ): Promise<[number, number, number, number]>;\n ff_decode_multi(\n c: number,\n pkt: number,\n frame: number,\n packets: LibavPacket[],\n opts?: { fin?: boolean; ignoreErrors?: boolean },\n ): Promise<LibavFrame[]>;\n ff_free_decoder?(c: number, pkt: number, frame: number): Promise<void>;\n av_packet_alloc(): Promise<number>;\n av_packet_free?(pkt: number): Promise<void>;\n av_seek_frame(\n fmt_ctx: number,\n stream: number,\n tsLo: number,\n tsHi: number,\n flags: number,\n ): Promise<number>;\n avcodec_flush_buffers?(c: number): Promise<void>;\n avformat_close_input_js(ctx: number): Promise<void>;\n f64toi64?(val: number): [number, number];\n\n // BSF methods\n av_bsf_list_parse_str_js(str: string): Promise<number>;\n AVBSFContext_par_in(ctx: number): Promise<number>;\n avcodec_parameters_copy(dst: number, src: number): Promise<number>;\n av_bsf_init(ctx: number): Promise<number>;\n av_bsf_send_packet(ctx: number, pkt: number): Promise<number>;\n av_bsf_receive_packet(ctx: number, pkt: number): Promise<number>;\n av_bsf_free(ctx: number): Promise<void>;\n ff_copyin_packet(pktPtr: number, packet: LibavPacket): Promise<void>;\n ff_copyout_packet(pkt: number): Promise<LibavPacket>;\n}\n\ninterface BridgeModule {\n videoStreamToConfig(libav: unknown, stream: unknown): Promise<VideoDecoderConfig | null>;\n packetToEncodedVideoChunk(pkt: unknown, stream: unknown): EncodedVideoChunk;\n}\n","import type { MediaContext, PlaybackSession, TransportConfig } from \"../../types.js\";\nimport { VideoRenderer } from \"../fallback/video-renderer.js\";\nimport { AudioOutput } from \"../fallback/audio-output.js\";\nimport { startHybridDecoder, type HybridDecoderHandles } from \"./decoder.js\";\n\n/**\n * Hybrid strategy session.\n *\n * Uses libav.js for demuxing + WebCodecs VideoDecoder for hardware-accelerated\n * video decode + libav.js software decode for audio. Same canvas + Web Audio\n * output as the fallback strategy.\n *\n * Falls back to the pure-WASM fallback strategy if WebCodecs fails (via the\n * onFatalError callback that the player wires to its escalation mechanism).\n */\n\nconst READY_AUDIO_BUFFER_SECONDS = 0.3;\nconst READY_TIMEOUT_SECONDS = 10;\n\nexport async function createHybridSession(\n ctx: MediaContext,\n target: HTMLVideoElement,\n transport?: TransportConfig,\n): Promise<PlaybackSession> {\n // Normalize the source so URL inputs go through the libav HTTP block\n // reader instead of being buffered into memory.\n const { normalizeSource } = await import(\"../../util/source.js\");\n const source = await normalizeSource(ctx.source);\n\n const fps = ctx.videoTracks[0]?.fps ?? 30;\n const audio = new AudioOutput();\n const renderer = new VideoRenderer(target, audio, fps);\n\n let handles: HybridDecoderHandles;\n try {\n handles = await startHybridDecoder({\n source,\n filename: ctx.name ?? \"input.bin\",\n context: ctx,\n renderer,\n audio,\n transport,\n });\n } catch (err) {\n audio.destroy();\n renderer.destroy();\n throw err;\n }\n\n // Patch <video> element for the unified player layer. The underlying\n // <video> never has its own src; all playback state lives in the audio\n // clock + canvas renderer. We expose that state via property getters\n // so standard HTMLMediaElement consumers (like <avbridge-player>'s\n // controls UI) see the real values.\n Object.defineProperty(target, \"currentTime\", {\n configurable: true,\n get: () => audio.now(),\n set: (v: number) => { void doSeek(v); },\n });\n Object.defineProperty(target, \"paused\", {\n configurable: true,\n get: () => !audio.isPlaying(),\n });\n Object.defineProperty(target, \"volume\", {\n configurable: true,\n get: () => audio.getVolume(),\n set: (v: number) => {\n audio.setVolume(v);\n target.dispatchEvent(new Event(\"volumechange\"));\n },\n });\n Object.defineProperty(target, \"muted\", {\n configurable: true,\n get: () => audio.getMuted(),\n set: (m: boolean) => {\n audio.setMuted(m);\n target.dispatchEvent(new Event(\"volumechange\"));\n },\n });\n if (ctx.duration && Number.isFinite(ctx.duration)) {\n Object.defineProperty(target, \"duration\", {\n configurable: true,\n get: () => ctx.duration ?? NaN,\n });\n }\n\n async function waitForBuffer(): Promise<void> {\n const start = performance.now();\n while (true) {\n const audioReady = audio.isNoAudio() || audio.bufferAhead() >= READY_AUDIO_BUFFER_SECONDS;\n if (audioReady && renderer.hasFrames()) {\n return;\n }\n if ((performance.now() - start) / 1000 > READY_TIMEOUT_SECONDS) return;\n await new Promise((r) => setTimeout(r, 50));\n }\n }\n\n async function doSeek(timeSec: number): Promise<void> {\n const wasPlaying = audio.isPlaying();\n await audio.pause().catch(() => {});\n await handles.seek(timeSec).catch((err) =>\n console.warn(\"[avbridge] hybrid decoder seek failed:\", err),\n );\n await audio.reset(timeSec);\n renderer.flush();\n if (wasPlaying) {\n await waitForBuffer();\n await audio.start();\n }\n }\n\n // Store the fatal error handler so the player can wire escalation\n let fatalErrorHandler: ((reason: string) => void) | null = null;\n handles.onFatalError((reason) => fatalErrorHandler?.(reason));\n\n return {\n strategy: \"hybrid\",\n\n async play() {\n if (!audio.isPlaying()) {\n await waitForBuffer();\n await audio.start();\n // Dispatch play/playing events so HTMLMediaElement consumers\n // (e.g. <avbridge-player>'s controls UI) update their state.\n target.dispatchEvent(new Event(\"play\"));\n target.dispatchEvent(new Event(\"playing\"));\n }\n },\n\n pause() {\n void audio.pause();\n target.dispatchEvent(new Event(\"pause\"));\n },\n\n async seek(time) {\n await doSeek(time);\n },\n\n async setAudioTrack(_id) {\n // Post-MVP for hybrid strategy\n },\n\n async setSubtitleTrack(_id) {\n // Post-MVP for hybrid strategy\n },\n\n getCurrentTime() {\n return audio.now();\n },\n\n onFatalError(handler: (reason: string) => void) {\n fatalErrorHandler = handler;\n },\n\n async destroy() {\n await handles.destroy();\n renderer.destroy();\n audio.destroy();\n try {\n delete (target as unknown as Record<string, unknown>).currentTime;\n delete (target as unknown as Record<string, unknown>).duration;\n delete (target as unknown as Record<string, unknown>).paused;\n delete (target as unknown as Record<string, unknown>).volume;\n delete (target as unknown as Record<string, unknown>).muted;\n } catch { /* ignore */ }\n },\n\n getRuntimeStats() {\n return handles.stats();\n },\n };\n}\n","/**\n * libav.js demux + decode loop for the fallback strategy.\n *\n * Design:\n *\n * - **Always software decode.** The fallback strategy is only entered when\n * classification has decided no browser decoder will handle the codec set,\n * so the WebCodecs hardware path is dead weight here. Going through libav\n * uniformly also avoids brittleness around `EncodedAudioChunk` framing for\n * codecs like MP3-in-AVI where the browser's AudioDecoder rejects libav's\n * raw demuxed packets.\n *\n * - **Cancellable pump loop.** Each pump iteration is gated on a token that\n * `seek()` increments. When the token changes mid-batch, the loop exits\n * and a fresh one starts at the new position. This is how seek interrupts\n * the decoder cleanly without having to await an arbitrarily long\n * `ff_decode_multi` call.\n *\n * - **Synthetic timestamps.** AVI demuxers report `AV_NOPTS_VALUE` for most\n * packets — they're frame-indexed, not time-indexed. We replace any\n * invalid pts with a per-stream synthetic counter (frame index × 1e6/fps\n * for video; sample-accurate for audio) so the bridge's chunk constructor\n * doesn't overflow int64.\n */\n\nimport { loadLibav, type LibavVariant } from \"./libav-loader.js\";\nimport { VideoRenderer } from \"./video-renderer.js\";\nimport { AudioOutput } from \"./audio-output.js\";\nimport type { MediaContext } from \"../../types.js\";\nimport { pickLibavVariant } from \"./variant-routing.js\";\nimport { dbg } from \"../../util/debug.js\";\n\nexport interface DecoderHandles {\n destroy(): Promise<void>;\n /** Seek to the given time in seconds. Returns once the new pump has been kicked off. */\n seek(timeSec: number): Promise<void>;\n stats(): Record<string, unknown>;\n}\n\nexport interface StartDecoderOptions {\n /** Normalized source — either a Blob in memory or a URL we'll stream via Range requests. */\n source: import(\"../../util/source.js\").NormalizedSource;\n filename: string;\n context: MediaContext;\n renderer: VideoRenderer;\n audio: AudioOutput;\n transport?: import(\"../../types.js\").TransportConfig;\n}\n\nexport async function startDecoder(opts: StartDecoderOptions): Promise<DecoderHandles> {\n const variant: LibavVariant = pickLibavVariant(opts.context);\n const libav = (await loadLibav(variant)) as unknown as LibavRuntime;\n const bridge = await loadBridge();\n\n // For URL sources, prepareLibavInput attaches an HTTP block reader so\n // libav demuxes via Range requests. For Blob sources, it falls back to\n // mkreadaheadfile (in-memory). The returned handle owns cleanup.\n const { prepareLibavInput } = await import(\"../../util/libav-http-reader.js\");\n const inputHandle = await prepareLibavInput(libav as unknown as Parameters<typeof prepareLibavInput>[0], opts.filename, opts.source, opts.transport);\n\n // Pre-allocate one AVPacket for ff_read_frame_multi to reuse.\n const readPkt = await libav.av_packet_alloc();\n\n const [fmt_ctx, streams] = await libav.ff_init_demuxer_file(opts.filename);\n const videoStream = streams.find((s) => s.codec_type === libav.AVMEDIA_TYPE_VIDEO) ?? null;\n const audioStream = streams.find((s) => s.codec_type === libav.AVMEDIA_TYPE_AUDIO) ?? null;\n\n if (!videoStream && !audioStream) {\n throw new Error(\"fallback decoder: file has no decodable streams\");\n }\n\n // ── Set up software decoders ─────────────────────────────────────────\n let videoDec: SoftDecoder | null = null;\n let audioDec: SoftDecoder | null = null;\n let videoTimeBase: [number, number] | undefined;\n let audioTimeBase: [number, number] | undefined;\n\n if (videoStream) {\n try {\n const [, c, pkt, frame] = await libav.ff_init_decoder(videoStream.codec_id, {\n codecpar: videoStream.codecpar,\n });\n videoDec = { c, pkt, frame };\n if (videoStream.time_base_num && videoStream.time_base_den) {\n videoTimeBase = [videoStream.time_base_num, videoStream.time_base_den];\n }\n } catch (err) {\n console.error(\"[avbridge] failed to init video decoder:\", err);\n }\n }\n\n if (audioStream) {\n try {\n const [, c, pkt, frame] = await libav.ff_init_decoder(audioStream.codec_id, {\n codecpar: audioStream.codecpar,\n });\n audioDec = { c, pkt, frame };\n if (audioStream.time_base_num && audioStream.time_base_den) {\n audioTimeBase = [audioStream.time_base_num, audioStream.time_base_den];\n }\n } catch (err) {\n console.warn(\n \"[avbridge] fallback: audio decoder unavailable — playing video with wall-clock timing:\",\n (err as Error).message,\n );\n }\n }\n\n // No audio decoder? Switch audio output into wall-clock mode so video can\n // play even when the audio codec isn't supported by the loaded libav variant.\n if (!audioDec) {\n opts.audio.setNoAudio();\n }\n\n if (!videoDec && !audioDec) {\n await inputHandle.detach().catch(() => {});\n const codecs = [\n videoStream ? `video: ${opts.context.videoTracks[0]?.codec ?? \"unknown\"}` : null,\n audioStream ? `audio: ${opts.context.audioTracks[0]?.codec ?? \"unknown\"}` : null,\n ].filter(Boolean).join(\", \");\n const hint = variant === \"webcodecs\"\n ? ` The \"${variant}\" libav variant does not include software decoders for these codecs. ` +\n `Try the custom \"avbridge\" variant (scripts/build-libav.sh) for broader codec support, ` +\n `or use a lighter strategy (native, remux, hybrid) instead.`\n : \"\";\n throw new Error(\n `fallback decoder: could not initialize any libav decoders (${codecs}).${hint}`,\n );\n }\n\n // ── Bitstream filter for MPEG-4 Part 2 packed B-frames ───────────────\n // Applied unconditionally for mpeg4 video — the BSF is a no-op when\n // the stream doesn't actually have packed B-frames, so false positives\n // are harmless. Without it, DivX files with packed B-frames produce\n // garbled frame ordering.\n let bsfCtx: number | null = null;\n let bsfPkt: number | null = null;\n if (videoStream && opts.context.videoTracks[0]?.codec === \"mpeg4\") {\n try {\n bsfCtx = await libav.av_bsf_list_parse_str_js(\"mpeg4_unpack_bframes\");\n if (bsfCtx != null && bsfCtx >= 0) {\n const parIn = await libav.AVBSFContext_par_in(bsfCtx);\n await libav.avcodec_parameters_copy(parIn, videoStream.codecpar);\n await libav.av_bsf_init(bsfCtx);\n bsfPkt = await libav.av_packet_alloc();\n dbg.info(\"bsf\", \"mpeg4_unpack_bframes BSF active\");\n } else {\n // eslint-disable-next-line no-console\n console.warn(\"[avbridge] mpeg4_unpack_bframes BSF not available — decoding without it\");\n bsfCtx = null;\n }\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\"[avbridge] failed to init mpeg4_unpack_bframes BSF:\", (err as Error).message);\n bsfCtx = null;\n bsfPkt = null;\n }\n }\n\n /** Run video packets through the BSF. Returns original packets if no BSF active. */\n async function applyBSF(packets: LibavPacket[]): Promise<LibavPacket[]> {\n if (!bsfCtx || !bsfPkt) return packets;\n const out: LibavPacket[] = [];\n for (const pkt of packets) {\n await libav.ff_copyin_packet(bsfPkt, pkt);\n const sendErr = await libav.av_bsf_send_packet(bsfCtx, bsfPkt);\n if (sendErr < 0) {\n out.push(pkt); // BSF rejected — pass through original\n continue;\n }\n while (true) {\n const recvErr = await libav.av_bsf_receive_packet(bsfCtx, bsfPkt);\n if (recvErr < 0) break; // EAGAIN or EOF\n out.push(await libav.ff_copyout_packet(bsfPkt));\n }\n }\n return out;\n }\n\n /** Flush the BSF (on seek or EOF) to drain any internally buffered packets. */\n async function flushBSF(): Promise<void> {\n if (!bsfCtx || !bsfPkt) return;\n try {\n await libav.av_bsf_send_packet(bsfCtx, 0);\n while (true) {\n const err = await libav.av_bsf_receive_packet(bsfCtx, bsfPkt);\n if (err < 0) break;\n }\n } catch { /* ignore flush errors */ }\n }\n\n // ── Mutable state shared across pump loops ───────────────────────────\n let destroyed = false;\n let pumpToken = 0; // bumped on seek; pump loops bail when token changes\n let pumpRunning: Promise<void> | null = null;\n\n let packetsRead = 0;\n let videoFramesDecoded = 0;\n let audioFramesDecoded = 0;\n\n // Decode-rate watchdog. Samples framesDecoded every second and\n // compares against realtime expected frames for the source fps. If\n // the decoder sustains less than 60% of realtime for more than\n // 5 seconds (counting only time since the first frame emerged),\n // emits a one-shot diagnostic so users know why playback is\n // stuttering instead of guessing. A second one-shot fires if the\n // renderer's overflow-drop rate exceeds 10% of decoded frames —\n // that symptom means the decoder is BURSTING faster than the\n // renderer can drain, which is a different bug from \"decoder slow\".\n let watchdogFirstFrameMs = 0;\n let watchdogSlowSinceMs = 0;\n let watchdogSlowWarned = false;\n let watchdogOverflowWarned = false;\n\n // Synthetic timestamp counters. Reset on seek.\n let syntheticVideoUs = 0;\n let syntheticAudioUs = 0;\n\n const videoTrackInfo = opts.context.videoTracks.find((t) => t.id === videoStream?.index);\n const videoFps = videoTrackInfo?.fps && videoTrackInfo.fps > 0 ? videoTrackInfo.fps : 30;\n const videoFrameStepUs = Math.max(1, Math.round(1_000_000 / videoFps));\n\n // ── Pump loop ─────────────────────────────────────────────────────────\n\n async function pumpLoop(myToken: number): Promise<void> {\n while (!destroyed && myToken === pumpToken) {\n let readErr: number;\n let packets: Record<number, LibavPacket[]>;\n try {\n // Batch size tunes the tradeoff between JS↔WASM call overhead\n // (small = more crossings per second) and queue burstiness\n // (large = decoder hands the renderer big bursts at once that\n // can blow past the renderer's 64-frame hard cap before the\n // per-batch `queueHighWater` throttle runs).\n //\n // We tried 64 KB and saw ~30% overflow drops on RMVB:rv40 at\n // 1024x768 because one decode batch regularly produced >30\n // frames. 16 KB keeps each batch ≈ 4-6 video packets at\n // typical bitrates, so the worst-case queue spike stays under\n // `queueHighWater` and the throttle has a chance to apply\n // backpressure *between* batches rather than within one.\n [readErr, packets] = await libav.ff_read_frame_multi(fmt_ctx, readPkt, {\n limit: 16 * 1024,\n });\n } catch (err) {\n console.error(\"[avbridge] ff_read_frame_multi failed:\", err);\n return;\n }\n\n if (myToken !== pumpToken || destroyed) return;\n\n const videoPackets = videoStream ? packets[videoStream.index] : undefined;\n const audioPackets = audioStream ? packets[audioStream.index] : undefined;\n\n // Decode audio BEFORE video. On software-decode-bound content\n // (rv40/mpeg4/wmv3 @ 720p+) a single video batch can take\n // 200-400 ms of wall time; if the scheduler hasn't been fed\n // during that window, audio output runs dry and the user hears\n // clicks/gaps. Audio is time-critical; video can drop a frame\n // and nobody notices. Audio decode is also typically <1 ms per\n // packet for cook/mp3/aac, so doing it first barely delays\n // video decoding at all.\n if (audioDec && audioPackets && audioPackets.length > 0) {\n await decodeAudioBatch(audioPackets, myToken);\n }\n if (myToken !== pumpToken || destroyed) return;\n if (videoDec && videoPackets && videoPackets.length > 0) {\n const processed = await applyBSF(videoPackets);\n await decodeVideoBatch(processed, myToken);\n }\n\n packetsRead += (videoPackets?.length ?? 0) + (audioPackets?.length ?? 0);\n\n // ── Decode-rate watchdog ──────────────────────────────────────\n if (videoFramesDecoded > 0) {\n if (watchdogFirstFrameMs === 0) {\n watchdogFirstFrameMs = performance.now();\n }\n const elapsedSinceFirst = (performance.now() - watchdogFirstFrameMs) / 1000;\n\n // 1. Slow-decode detection (sustained <60% of realtime fps).\n if (elapsedSinceFirst > 1 && !watchdogSlowWarned) {\n const expectedFrames = elapsedSinceFirst * videoFps;\n const ratio = videoFramesDecoded / expectedFrames;\n if (ratio < 0.6) {\n if (watchdogSlowSinceMs === 0) watchdogSlowSinceMs = performance.now();\n if ((performance.now() - watchdogSlowSinceMs) / 1000 > 5) {\n watchdogSlowWarned = true;\n console.warn(\n \"[avbridge:decode-rate]\",\n `decoder is running slower than realtime: ` +\n `${videoFramesDecoded} frames in ${elapsedSinceFirst.toFixed(1)}s ` +\n `(${(videoFramesDecoded / elapsedSinceFirst).toFixed(1)} fps vs ${videoFps} fps source — ` +\n `${(ratio * 100).toFixed(0)}% of realtime). ` +\n `Playback will stutter. Typical causes: software decode of a codec with no WebCodecs support ` +\n `(rv40, mpeg4 @ 720p+, wmv3), or a resolution too large for single-threaded WASM to keep up with.`,\n );\n }\n } else {\n watchdogSlowSinceMs = 0;\n }\n }\n\n // 2. Overflow-drop detection (>10% of decoded frames dropped\n // by the renderer's hard cap). This means the decoder\n // produces BURSTS — it's fast enough on average but one\n // batch delivers >30 frames at a time, overflowing before\n // the queueHighWater throttle can apply backpressure.\n // Symptom is different from \"decoder slow\": here the fps\n // ratio looks fine but the user sees choppy playback.\n if (\n !watchdogOverflowWarned &&\n videoFramesDecoded > 100 // wait for a meaningful sample\n ) {\n const rendererStats = opts.renderer.stats() as { framesDroppedOverflow?: number };\n const overflow = rendererStats.framesDroppedOverflow ?? 0;\n if (overflow / videoFramesDecoded > 0.1) {\n watchdogOverflowWarned = true;\n console.warn(\n \"[avbridge:overflow-drop]\",\n `renderer is dropping ${overflow}/${videoFramesDecoded} frames ` +\n `(${((overflow / videoFramesDecoded) * 100).toFixed(0)}%) because the decoder ` +\n `is producing bursts faster than the canvas can drain. Symptom: choppy ` +\n `playback despite decoder keeping up on average. Fix would be smaller ` +\n `read batches in the pump loop or a lower queueHighWater cap — see ` +\n `src/strategies/fallback/decoder.ts.`,\n );\n }\n }\n }\n\n // Throttle: don't run too far ahead of playback. Two backpressure\n // signals:\n // - Audio buffer (mediaTimeOfNext - now()) > 2 sec — we have\n // plenty of audio scheduled.\n // - Renderer queue depth >= queueHighWater — the canvas can't\n // drain fast enough. Without this, fast software decode of\n // small frames piles up in the renderer and overflows.\n while (\n !destroyed &&\n myToken === pumpToken &&\n (opts.audio.bufferAhead() > 2.0 ||\n opts.renderer.queueDepth() >= opts.renderer.queueHighWater)\n ) {\n await new Promise((r) => setTimeout(r, 50));\n }\n\n if (readErr === libav.AVERROR_EOF) {\n if (videoDec) await decodeVideoBatch([], myToken, /*flush*/ true);\n if (audioDec) await decodeAudioBatch([], myToken, /*flush*/ true);\n return;\n }\n if (readErr && readErr !== 0 && readErr !== -libav.EAGAIN) {\n console.warn(\"[avbridge] ff_read_frame_multi returned\", readErr);\n return;\n }\n }\n }\n\n async function decodeVideoBatch(pkts: LibavPacket[], myToken: number, flush = false) {\n if (!videoDec || destroyed || myToken !== pumpToken) return;\n let frames: LibavFrame[];\n try {\n frames = await libav.ff_decode_multi(\n videoDec.c,\n videoDec.pkt,\n videoDec.frame,\n pkts,\n flush ? { fin: true, ignoreErrors: true } : { ignoreErrors: true },\n );\n } catch (err) {\n console.error(\"[avbridge] video decode batch failed:\", err);\n return;\n }\n if (myToken !== pumpToken || destroyed) return;\n\n for (const f of frames) {\n if (myToken !== pumpToken || destroyed) return;\n const bridgeOpts = sanitizeFrameTimestamp(\n f,\n () => {\n const ts = syntheticVideoUs;\n syntheticVideoUs += videoFrameStepUs;\n return ts;\n },\n videoTimeBase,\n );\n try {\n const vf = bridge.laFrameToVideoFrame(f, bridgeOpts);\n opts.renderer.enqueue(vf);\n videoFramesDecoded++;\n } catch (err) {\n if (videoFramesDecoded === 0) {\n console.warn(\"[avbridge] laFrameToVideoFrame failed:\", err);\n }\n }\n }\n }\n\n async function decodeAudioBatch(pkts: LibavPacket[], myToken: number, flush = false) {\n if (!audioDec || destroyed || myToken !== pumpToken) return;\n let frames: LibavFrame[];\n try {\n frames = await libav.ff_decode_multi(\n audioDec.c,\n audioDec.pkt,\n audioDec.frame,\n pkts,\n flush ? { fin: true, ignoreErrors: true } : { ignoreErrors: true },\n );\n } catch (err) {\n console.error(\"[avbridge] audio decode batch failed:\", err);\n return;\n }\n if (myToken !== pumpToken || destroyed) return;\n\n for (const f of frames) {\n if (myToken !== pumpToken || destroyed) return;\n sanitizeFrameTimestamp(\n f,\n () => {\n const ts = syntheticAudioUs;\n const samples = f.nb_samples ?? 1024;\n const sampleRate = f.sample_rate ?? 44100;\n syntheticAudioUs += Math.round((samples * 1_000_000) / sampleRate);\n return ts;\n },\n audioTimeBase,\n );\n const samples = libavFrameToInterleavedFloat32(f);\n if (samples) {\n opts.audio.schedule(samples.data, samples.channels, samples.sampleRate);\n audioFramesDecoded++;\n }\n }\n }\n\n // Kick off the initial pump.\n pumpToken = 1;\n pumpRunning = pumpLoop(pumpToken).catch((err) =>\n console.error(\"[avbridge] decoder pump failed:\", err),\n );\n\n return {\n async destroy() {\n destroyed = true;\n pumpToken++;\n try { await pumpRunning; } catch { /* ignore */ }\n try { if (bsfCtx) await libav.av_bsf_free(bsfCtx); } catch { /* ignore */ }\n try { if (bsfPkt) await libav.av_packet_free?.(bsfPkt); } catch { /* ignore */ }\n try { if (videoDec) await libav.ff_free_decoder?.(videoDec.c, videoDec.pkt, videoDec.frame); } catch { /* ignore */ }\n try { if (audioDec) await libav.ff_free_decoder?.(audioDec.c, audioDec.pkt, audioDec.frame); } catch { /* ignore */ }\n try { await libav.av_packet_free?.(readPkt); } catch { /* ignore */ }\n try { await libav.avformat_close_input_js(fmt_ctx); } catch { /* ignore */ }\n try { await inputHandle.detach(); } catch { /* ignore */ }\n },\n\n async seek(timeSec) {\n // Cancel the current pump and wait for it to actually exit before\n // we start moving file pointers around — concurrent ff_decode_multi\n // and av_seek_frame on the same context would be a recipe for memory\n // corruption inside libav.\n const newToken = ++pumpToken;\n if (pumpRunning) {\n try { await pumpRunning; } catch { /* ignore */ }\n }\n if (destroyed) return;\n\n try {\n // libav.js's `av_seek_frame` takes the timestamp as a *split*\n // (lo, hi) int64 pair, NOT a single number. The function signature\n // is: av_seek_frame(s, stream_index, tsLo, tsHi, flags). Passing a\n // single number put AVSEEK_FLAG_BACKWARD (1) into tsHi, which\n // produced a bogus int64 = 4.29e9 + tsLo ≈ 73 min for any small\n // seek target — seeking past EOF and stalling the pump.\n const tsUs = Math.floor(timeSec * 1_000_000);\n const [tsLo, tsHi] = libav.f64toi64\n ? libav.f64toi64(tsUs)\n : [tsUs | 0, Math.floor(tsUs / 0x100000000)];\n await libav.av_seek_frame(\n fmt_ctx,\n -1,\n tsLo,\n tsHi,\n libav.AVSEEK_FLAG_BACKWARD ?? 0,\n );\n } catch (err) {\n console.warn(\"[avbridge] av_seek_frame failed:\", err);\n }\n\n // Reset the decoder state. After the previous pump exited via the\n // EOF path it called ff_decode_multi with `fin: true`, which sends a\n // NULL packet to the decoder and puts it in drain mode — meaning all\n // subsequent decode calls return EOF. `avcodec_flush_buffers` clears\n // that state so a fresh stream of post-seek packets is accepted.\n // Also clears any internal frame reordering buffer, which is what we\n // want anyway since we just changed positions.\n try {\n if (videoDec) await libav.avcodec_flush_buffers?.(videoDec.c);\n } catch { /* ignore */ }\n try {\n if (audioDec) await libav.avcodec_flush_buffers?.(audioDec.c);\n } catch { /* ignore */ }\n await flushBSF();\n\n // Reset synthetic timestamp counters to the seek target so newly\n // decoded frames start at the right media time.\n syntheticVideoUs = Math.round(timeSec * 1_000_000);\n syntheticAudioUs = Math.round(timeSec * 1_000_000);\n\n // The renderer & audio output are reset by the fallback session\n // wrapper that called us — see strategies/fallback/index.ts.\n\n // Start a fresh pump for the new token.\n pumpRunning = pumpLoop(newToken).catch((err) =>\n console.error(\"[avbridge] decoder pump failed (post-seek):\", err),\n );\n },\n\n stats() {\n return {\n decoderType: \"libav-wasm\",\n packetsRead,\n videoFramesDecoded,\n audioFramesDecoded,\n bsfApplied: bsfCtx ? [\"mpeg4_unpack_bframes\"] : [],\n // Confirmed transport info: once prepareLibavInput returns\n // successfully, we *know* whether the source is http-range (probe\n // succeeded and returned 206) or in-memory blob. Diagnostics hoists\n // these `_`-prefixed keys to the typed fields.\n _transport: inputHandle.transport === \"http-range\" ? \"http-range\" : \"memory\",\n _rangeSupported: inputHandle.transport === \"http-range\",\n ...opts.renderer.stats(),\n ...opts.audio.stats(),\n };\n },\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Frame timestamp sanitizer.\n//\n// libav can hand back decoded frames with `pts = AV_NOPTS_VALUE` (encoded as\n// ptshi = -2147483648, pts = 0) for inputs whose demuxer can't determine\n// presentation times. AVI is the canonical example. The bridge's\n// `laFrameToVideoFrame` then multiplies pts × 1e6 × tbNum / tbDen and\n// overflows int64, throwing \"Value is outside the 'long long' value range\".\n//\n// Fix: replace any invalid pts with a synthetic microsecond counter, force\n// the frame's pts/ptshi to that value, and tell the bridge to use a 1/1e6\n// timebase so it does an identity conversion.\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface BridgeOpts {\n timeBase?: [number, number];\n transfer?: boolean;\n}\n\nfunction sanitizeFrameTimestamp(\n frame: LibavFrame,\n nextUs: () => number,\n fallbackTimeBase?: [number, number],\n): BridgeOpts {\n const lo = frame.pts ?? 0;\n const hi = frame.ptshi ?? 0;\n const isInvalid = (hi === -2147483648 && lo === 0) || !Number.isFinite(lo);\n if (isInvalid) {\n const us = nextUs();\n frame.pts = us;\n frame.ptshi = 0;\n return { timeBase: [1, 1_000_000] };\n }\n const tb = fallbackTimeBase ?? [1, 1_000_000];\n const pts64 = hi * 0x100000000 + lo;\n const us = Math.round((pts64 * 1_000_000 * tb[0]) / tb[1]);\n if (Number.isFinite(us) && Math.abs(us) <= Number.MAX_SAFE_INTEGER) {\n frame.pts = us;\n frame.ptshi = us < 0 ? -1 : 0;\n return { timeBase: [1, 1_000_000] };\n }\n const fallback = nextUs();\n frame.pts = fallback;\n frame.ptshi = 0;\n return { timeBase: [1, 1_000_000] };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// libav decoded `Frame` → interleaved Float32Array (the format AudioOutput\n// schedules).\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst AV_SAMPLE_FMT_U8 = 0;\nconst AV_SAMPLE_FMT_S16 = 1;\nconst AV_SAMPLE_FMT_S32 = 2;\nconst AV_SAMPLE_FMT_FLT = 3;\nconst AV_SAMPLE_FMT_U8P = 5;\nconst AV_SAMPLE_FMT_S16P = 6;\nconst AV_SAMPLE_FMT_S32P = 7;\nconst AV_SAMPLE_FMT_FLTP = 8;\n\ninterface InterleavedSamples {\n data: Float32Array;\n channels: number;\n sampleRate: number;\n}\n\nfunction libavFrameToInterleavedFloat32(frame: LibavFrame): InterleavedSamples | null {\n const channels = frame.channels ?? frame.ch_layout_nb_channels ?? 1;\n const sampleRate = frame.sample_rate ?? 44100;\n const nbSamples = frame.nb_samples ?? 0;\n if (nbSamples === 0) return null;\n\n const out = new Float32Array(nbSamples * channels);\n\n switch (frame.format) {\n case AV_SAMPLE_FMT_FLTP: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asFloat32(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = plane[i];\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_FLT: {\n const flat = asFloat32(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = flat[i];\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S16P: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asInt16(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = plane[i] / 32768;\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S16: {\n const flat = asInt16(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = flat[i] / 32768;\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S32P: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asInt32(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = plane[i] / 2147483648;\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_S32: {\n const flat = asInt32(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = flat[i] / 2147483648;\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_U8P: {\n const planes = ensurePlanes(frame.data, channels);\n for (let ch = 0; ch < channels; ch++) {\n const plane = asUint8(planes[ch]);\n for (let i = 0; i < nbSamples; i++) out[i * channels + ch] = (plane[i] - 128) / 128;\n }\n return { data: out, channels, sampleRate };\n }\n case AV_SAMPLE_FMT_U8: {\n const flat = asUint8(frame.data);\n for (let i = 0; i < nbSamples * channels; i++) out[i] = (flat[i] - 128) / 128;\n return { data: out, channels, sampleRate };\n }\n default:\n if (!(globalThis as { __avbridgeLoggedSampleFmt?: number }).__avbridgeLoggedSampleFmt) {\n (globalThis as { __avbridgeLoggedSampleFmt?: number }).__avbridgeLoggedSampleFmt = frame.format;\n console.warn(`[avbridge] unsupported audio sample format from libav: ${frame.format}`);\n }\n return null;\n }\n}\n\nfunction ensurePlanes(data: unknown, channels: number): unknown[] {\n if (Array.isArray(data)) return data;\n const arr = data as { length: number; subarray?: (a: number, b: number) => unknown };\n const len = arr.length;\n const perChannel = Math.floor(len / channels);\n const planes: unknown[] = [];\n for (let ch = 0; ch < channels; ch++) {\n planes.push(arr.subarray ? arr.subarray(ch * perChannel, (ch + 1) * perChannel) : arr);\n }\n return planes;\n}\n\nfunction asFloat32(x: unknown): Float32Array {\n if (x instanceof Float32Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Float32Array(ta.buffer, ta.byteOffset, ta.byteLength / 4);\n}\nfunction asInt16(x: unknown): Int16Array {\n if (x instanceof Int16Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Int16Array(ta.buffer, ta.byteOffset, ta.byteLength / 2);\n}\nfunction asInt32(x: unknown): Int32Array {\n if (x instanceof Int32Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Int32Array(ta.buffer, ta.byteOffset, ta.byteLength / 4);\n}\nfunction asUint8(x: unknown): Uint8Array {\n if (x instanceof Uint8Array) return x;\n const ta = x as { buffer: ArrayBuffer; byteOffset: number; byteLength: number };\n return new Uint8Array(ta.buffer, ta.byteOffset, ta.byteLength);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bridge loader (lazy via the static-import wrapper).\n// ─────────────────────────────────────────────────────────────────────────────\n\nasync function loadBridge(): Promise<BridgeModule> {\n try {\n const wrapper = await import(\"./libav-import.js\");\n return wrapper.libavBridge as unknown as BridgeModule;\n } catch (err) {\n throw new Error(\n `failed to load libavjs-webcodecs-bridge — install the optional peer deps with: ` +\n `npm i libavjs-webcodecs-bridge @libav.js/variant-webcodecs. ` +\n `(${(err as Error).message})`,\n );\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Structural types.\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface SoftDecoder {\n c: number;\n pkt: number;\n frame: number;\n}\n\ninterface LibavStream {\n index: number;\n codec_type: number;\n codec_id: number;\n codecpar: number;\n time_base_num?: number;\n time_base_den?: number;\n}\n\ninterface LibavPacket {\n data: Uint8Array;\n pts: number;\n ptshi?: number;\n duration?: number;\n durationhi?: number;\n flags: number;\n stream_index: number;\n time_base_num?: number;\n time_base_den?: number;\n}\n\ninterface LibavFrame {\n data: unknown;\n format: number;\n channels?: number;\n ch_layout_nb_channels?: number;\n sample_rate?: number;\n nb_samples?: number;\n pts?: number;\n ptshi?: number;\n width?: number;\n height?: number;\n}\n\ninterface LibavRuntime {\n AVMEDIA_TYPE_VIDEO: number;\n AVMEDIA_TYPE_AUDIO: number;\n AVERROR_EOF: number;\n EAGAIN: number;\n AVSEEK_FLAG_BACKWARD?: number;\n\n mkreadaheadfile(name: string, blob: Blob): Promise<void>;\n unlinkreadaheadfile(name: string): Promise<void>;\n ff_init_demuxer_file(name: string): Promise<[number, LibavStream[]]>;\n ff_read_frame_multi(\n fmt_ctx: number,\n pkt: number,\n opts?: { limit?: number },\n ): Promise<[number, Record<number, LibavPacket[]>]>;\n ff_init_decoder(\n codec: number | string,\n config?: { codecpar?: number; time_base?: [number, number] },\n ): Promise<[number, number, number, number]>;\n ff_decode_multi(\n c: number,\n pkt: number,\n frame: number,\n packets: LibavPacket[],\n opts?: { fin?: boolean; ignoreErrors?: boolean },\n ): Promise<LibavFrame[]>;\n ff_free_decoder?(c: number, pkt: number, frame: number): Promise<void>;\n av_packet_alloc(): Promise<number>;\n av_packet_free?(pkt: number): Promise<void>;\n av_seek_frame(\n fmt_ctx: number,\n stream: number,\n tsLo: number,\n tsHi: number,\n flags: number,\n ): Promise<number>;\n avcodec_flush_buffers?(c: number): Promise<void>;\n avformat_close_input_js(ctx: number): Promise<void>;\n /** Sync helper exposed by libav.js: split a JS number into (lo, hi) int64. */\n f64toi64?(val: number): [number, number];\n\n // BSF (bitstream filter) methods — used for mpeg4_unpack_bframes\n av_bsf_list_parse_str_js(str: string): Promise<number>;\n AVBSFContext_par_in(ctx: number): Promise<number>;\n avcodec_parameters_copy(dst: number, src: number): Promise<number>;\n av_bsf_init(ctx: number): Promise<number>;\n av_bsf_send_packet(ctx: number, pkt: number): Promise<number>;\n av_bsf_receive_packet(ctx: number, pkt: number): Promise<number>;\n av_bsf_free(ctx: number): Promise<void>;\n\n // Packet copy helpers — bridge JS packet objects to/from C-level pointers\n ff_copyin_packet(pktPtr: number, packet: LibavPacket): Promise<void>;\n ff_copyout_packet(pkt: number): Promise<LibavPacket>;\n}\n\ninterface BridgeModule {\n laFrameToVideoFrame(\n frame: LibavFrame,\n opts?: { VideoFrame?: unknown; timeBase?: [number, number]; transfer?: boolean },\n ): VideoFrame;\n laFrameToAudioData(\n frame: LibavFrame,\n opts?: { AudioData?: unknown; timeBase?: [number, number] },\n ): AudioData;\n}\n","import type { MediaContext, PlaybackSession, TransportConfig } from \"../../types.js\";\nimport { VideoRenderer } from \"./video-renderer.js\";\nimport { AudioOutput } from \"./audio-output.js\";\nimport { startDecoder, type DecoderHandles } from \"./decoder.js\";\nimport { dbg } from \"../../util/debug.js\";\n\n/**\n * Fallback strategy session.\n *\n * Owns the orchestration between the libav decoder, the audio scheduler,\n * and the canvas renderer. Three things make this non-trivial:\n *\n * 1. **Cold-start ready gate.** When `play()` is called, we wait until the\n * audio scheduler has buffered enough audio (≥ 300 ms) AND the renderer\n * has at least one decoded video frame, before actually telling the\n * audio context to start. Without this gate, audio and the wall clock\n * race ahead of the still-warming-up software decoder, and every video\n * frame lands \"in the past\" and gets dropped.\n *\n * 2. **Pause / resume.** The audio context is suspended on pause and\n * resumed on play. The media-time anchor is preserved across the\n * suspend so the clock is continuous.\n *\n * 3. **Seek.** Pauses the audio scheduler, asks the decoder to cancel its\n * current pump and `av_seek_frame` to the target, resets the audio\n * output's media-time anchor to the seek target, flushes the renderer\n * queue, then re-enters the ready gate. If we were playing before the\n * seek, we automatically resume once the buffer fills.\n *\n * The unified player API on top of this just sees `play() / pause() /\n * seek(t)` — none of the buffering choreography leaks out.\n */\n\n// Gate for cold-start playback. We want to start playing as soon as\n// there's any decoded output — the decoder will keep pumping during\n// playback, so more-is-better buffering only helps for fast decoders.\n//\n// For software-decode-bound content (rv40 / wmv3 / mpeg4 @ 720p+ on\n// single-threaded WASM), the decoder may run *slower* than realtime.\n// Waiting for a large audio-buffer threshold is actively wrong in that\n// case: it will never be reached, so the old gate would sit out its\n// full 10-second timeout before playing anything. An aggressive gate\n// ships the first frame to the screen fast, at the cost of the audio\n// clock racing a little ahead of video in the first few seconds —\n// which is the same situation we'd have been in after the timeout\n// anyway.\n//\n// READY_AUDIO_BUFFER_SECONDS: minimum audio queued before start. Set\n// low enough that a slow decoder still reaches it before the user\n// loses patience; 40 ms ≈ 2 cook packets or ~2 AAC packets.\n// READY_TIMEOUT_SECONDS: hard safety. If even 40 ms of audio can't be\n// produced in 3 s, give up and play whatever we have.\nconst READY_AUDIO_BUFFER_SECONDS = 0.04;\nconst READY_TIMEOUT_SECONDS = 3;\n\nexport async function createFallbackSession(\n ctx: MediaContext,\n target: HTMLVideoElement,\n transport?: TransportConfig,\n): Promise<PlaybackSession> {\n // Normalize the source so URL inputs go through the libav HTTP block\n // reader instead of being buffered into memory.\n const { normalizeSource } = await import(\"../../util/source.js\");\n const source = await normalizeSource(ctx.source);\n\n const fps = ctx.videoTracks[0]?.fps ?? 30;\n const audio = new AudioOutput();\n const renderer = new VideoRenderer(target, audio, fps);\n\n let handles: DecoderHandles;\n try {\n handles = await startDecoder({\n source,\n filename: ctx.name ?? \"input.bin\",\n context: ctx,\n renderer,\n audio,\n transport,\n });\n } catch (err) {\n audio.destroy();\n renderer.destroy();\n throw err;\n }\n\n // Patch the <video> element so the unified player layer (which polls\n // `target.currentTime` for `timeupdate` events and lets users assign to\n // it for seeks) gets the right values from the fallback strategy.\n Object.defineProperty(target, \"currentTime\", {\n configurable: true,\n get: () => audio.now(),\n set: (v: number) => {\n // Fire-and-forget — the user is expected to await player.seek() if\n // they want to know when the seek completes.\n void doSeek(v);\n },\n });\n // Mirror `paused` / `volume` / `muted` from the audio output — the\n // underlying <video> never has its own src, so its native state is\n // meaningless. This lets HTMLMediaElement consumers (<avbridge-player>\n // controls) see the real values and control volume through the audio\n // output's GainNode.\n Object.defineProperty(target, \"paused\", {\n configurable: true,\n get: () => !audio.isPlaying(),\n });\n Object.defineProperty(target, \"volume\", {\n configurable: true,\n get: () => audio.getVolume(),\n set: (v: number) => {\n audio.setVolume(v);\n target.dispatchEvent(new Event(\"volumechange\"));\n },\n });\n Object.defineProperty(target, \"muted\", {\n configurable: true,\n get: () => audio.getMuted(),\n set: (m: boolean) => {\n audio.setMuted(m);\n target.dispatchEvent(new Event(\"volumechange\"));\n },\n });\n // Mirror duration so the demo's controls can use target.duration too.\n if (ctx.duration && Number.isFinite(ctx.duration)) {\n Object.defineProperty(target, \"duration\", {\n configurable: true,\n get: () => ctx.duration ?? NaN,\n });\n }\n\n /**\n * Wait until the decoder has produced enough buffered output to start\n * playback smoothly. Returns early on timeout so we don't hang forever\n * if the decoder is producing nothing (e.g. immediately past EOF after\n * a seek to the end).\n *\n * The gate has three exit paths in order of preference:\n *\n * 1. **Fully ready** — audio buffer ≥ target AND ≥1 video frame.\n * The happy path for fast decoders (native + remux never reach\n * this function; this is fallback only).\n *\n * 2. **Video-ready, audio grace period elapsed** — we have video\n * frames but the audio scheduler is still empty. RM/AVI\n * containers commonly deliver a video GOP before their first\n * audio packet, so \"no audio yet\" ≠ \"no audio coming\". We give\n * the demuxer a 500 ms grace window from first-frame, then\n * start regardless. Audio will be scheduled at its correct\n * media time once its packets arrive.\n *\n * 3. **Hard timeout** — after {@link READY_TIMEOUT_SECONDS} seconds\n * with neither condition met, start anyway and emit an\n * unconditional diagnostic so the specific underflow is visible.\n *\n * Path #2 is what fixed the \"RMVB sits on the play button for 10 s\n * with audio=0ms, frames=N\" case — the gate was waiting on audio\n * packets that were several seconds behind in the file stream, and\n * the timeout was the only way out.\n */\n async function waitForBuffer(): Promise<void> {\n const start = performance.now();\n let firstFrameAtMs = 0;\n dbg.info(\"cold-start\",\n `gate entry: want audio ≥ ${READY_AUDIO_BUFFER_SECONDS * 1000}ms + 1 frame`,\n );\n while (true) {\n const audioAhead = audio.isNoAudio() ? Infinity : audio.bufferAhead();\n const audioReady = audio.isNoAudio() || audioAhead >= READY_AUDIO_BUFFER_SECONDS;\n const hasFrames = renderer.hasFrames();\n const nowMs = performance.now();\n\n if (hasFrames && firstFrameAtMs === 0) firstFrameAtMs = nowMs;\n\n // Happy path: both ready.\n if (audioReady && hasFrames) {\n dbg.info(\"cold-start\",\n `gate satisfied in ${(nowMs - start).toFixed(0)}ms ` +\n `(audio=${(audioAhead * 1000).toFixed(0)}ms, frames=${renderer.queueDepth()})`,\n );\n return;\n }\n\n // Grace path: have video, still waiting for audio that's\n // on its way (first 500 ms after first-frame).\n if (\n hasFrames &&\n firstFrameAtMs > 0 &&\n nowMs - firstFrameAtMs >= 500\n ) {\n dbg.info(\"cold-start\",\n `gate released on video-only grace at ${(nowMs - start).toFixed(0)}ms ` +\n `(frames=${renderer.queueDepth()}, audio=${(audioAhead * 1000).toFixed(0)}ms — ` +\n `demuxer hasn't delivered audio packets yet, starting anyway and letting ` +\n `the audio scheduler catch up at its media-time anchor)`,\n );\n return;\n }\n\n // Hard timeout.\n if ((nowMs - start) / 1000 > READY_TIMEOUT_SECONDS) {\n dbg.diag(\"cold-start\",\n `gate TIMEOUT after ${READY_TIMEOUT_SECONDS}s — ` +\n `audio=${(audioAhead * 1000).toFixed(0)}ms ` +\n `(needed ${READY_AUDIO_BUFFER_SECONDS * 1000}ms), ` +\n `frames=${renderer.queueDepth()} (needed ≥1). ` +\n `Decoder produced nothing in ${READY_TIMEOUT_SECONDS}s — either a corrupt source, ` +\n `a missing codec, or WASM is catastrophically slow on this file. ` +\n `Check getDiagnostics().runtime for decode counters.`,\n );\n return;\n }\n await new Promise((r) => setTimeout(r, 50));\n }\n }\n\n async function doSeek(timeSec: number): Promise<void> {\n const wasPlaying = audio.isPlaying();\n // 1. Stop audio (suspend ctx + capture media time).\n await audio.pause().catch(() => {});\n // 2. Tell the decoder to cancel its pump and seek the demuxer.\n await handles.seek(timeSec).catch((err) =>\n console.warn(\"[avbridge] decoder seek failed:\", err),\n );\n // 3. Reset audio + renderer to the new media time. New samples from\n // the decoder will queue against this anchor.\n await audio.reset(timeSec);\n renderer.flush();\n // 4. If we were playing, wait for the buffer to fill again and then\n // resume. If we were paused, leave it paused at the new position.\n if (wasPlaying) {\n await waitForBuffer();\n await audio.start();\n }\n }\n\n return {\n strategy: \"fallback\",\n\n async play() {\n // Either a cold start (very first play() call) or a resume from\n // pause. AudioOutput.start() handles both.\n if (!audio.isPlaying()) {\n await waitForBuffer();\n await audio.start();\n target.dispatchEvent(new Event(\"play\"));\n target.dispatchEvent(new Event(\"playing\"));\n }\n },\n\n pause() {\n void audio.pause();\n target.dispatchEvent(new Event(\"pause\"));\n },\n\n async seek(time) {\n await doSeek(time);\n },\n\n async setAudioTrack(_id) {\n // Multi-track audio is post-MVP for the fallback strategy.\n },\n\n async setSubtitleTrack(_id) {\n // Subtitle overlay support is post-MVP for the fallback strategy.\n },\n\n getCurrentTime() {\n return audio.now();\n },\n async destroy() {\n await handles.destroy();\n renderer.destroy();\n audio.destroy();\n try {\n delete (target as unknown as Record<string, unknown>).currentTime;\n delete (target as unknown as Record<string, unknown>).duration;\n delete (target as unknown as Record<string, unknown>).paused;\n delete (target as unknown as Record<string, unknown>).volume;\n delete (target as unknown as Record<string, unknown>).muted;\n } catch { /* ignore */ }\n },\n\n getRuntimeStats() {\n return handles.stats();\n },\n };\n}\n","import type { Plugin } from \"../types.js\";\nimport { createNativeSession } from \"../strategies/native.js\";\nimport { createRemuxSession } from \"../strategies/remux/index.js\";\nimport { createHybridSession } from \"../strategies/hybrid/index.js\";\nimport { createFallbackSession } from \"../strategies/fallback/index.js\";\nimport type { PluginRegistry } from \"./registry.js\";\n\nconst nativePlugin: Plugin = {\n name: \"native\",\n canHandle: () => true,\n execute: (ctx, video) => createNativeSession(ctx, video),\n};\n\nconst remuxPlugin: Plugin = {\n name: \"remux\",\n canHandle: () => true,\n execute: (ctx, video) => createRemuxSession(ctx, video),\n};\n\nconst hybridPlugin: Plugin = {\n name: \"hybrid\",\n canHandle: () => typeof VideoDecoder !== \"undefined\",\n execute: (ctx, video, transport) => createHybridSession(ctx, video, transport),\n};\n\nconst fallbackPlugin: Plugin = {\n name: \"fallback\",\n canHandle: () => true,\n execute: (ctx, video, transport) => createFallbackSession(ctx, video, transport),\n};\n\nexport function registerBuiltins(registry: PluginRegistry): void {\n registry.register(nativePlugin);\n registry.register(remuxPlugin);\n registry.register(hybridPlugin);\n registry.register(fallbackPlugin);\n}\n","/**\n * SRT → WebVTT converter.\n *\n * SRT cues:\n *\n * 1\n * 00:00:20,000 --> 00:00:24,400\n * Subtitle text, possibly multiple lines.\n *\n * WebVTT cues:\n *\n * WEBVTT\n *\n * 00:00:20.000 --> 00:00:24.400\n * Subtitle text, possibly multiple lines.\n *\n * The differences in v1 are:\n * - leading `WEBVTT` magic line\n * - `,` → `.` for milliseconds\n * - cue index lines are stripped (WebVTT allows them but SRT-style ints can\n * confuse some parsers; we drop them)\n * - BOM is stripped\n */\nexport function srtToVtt(srt: string): string {\n // Strip BOM\n if (srt.charCodeAt(0) === 0xfeff) srt = srt.slice(1);\n // Normalize line endings\n const normalized = srt.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\").trim();\n\n const blocks = normalized.split(/\\n{2,}/);\n const out: string[] = [\"WEBVTT\", \"\"];\n\n for (const block of blocks) {\n const lines = block.split(\"\\n\");\n // Drop the leading numeric index, if present.\n if (lines.length > 0 && /^\\d+$/.test(lines[0].trim())) {\n lines.shift();\n }\n if (lines.length === 0) continue;\n\n const timing = lines.shift()!;\n const vttTiming = convertTiming(timing);\n if (!vttTiming) continue; // skip malformed cue\n\n out.push(vttTiming);\n for (const l of lines) out.push(l);\n out.push(\"\");\n }\n\n return out.join(\"\\n\");\n}\n\nfunction convertTiming(line: string): string | null {\n // SRT: HH:MM:SS,mmm --> HH:MM:SS,mmm (optional cue settings after)\n const m = /^(\\d{1,2}):(\\d{2}):(\\d{2})[,.](\\d{1,3})\\s*-->\\s*(\\d{1,2}):(\\d{2}):(\\d{2})[,.](\\d{1,3})(.*)$/.exec(\n line.trim(),\n );\n if (!m) return null;\n const fmt = (h: string, mm: string, s: string, ms: string) =>\n `${h.padStart(2, \"0\")}:${mm}:${s}.${ms.padEnd(3, \"0\").slice(0, 3)}`;\n return `${fmt(m[1], m[2], m[3], m[4])} --> ${fmt(m[5], m[6], m[7], m[8])}${m[9] ?? \"\"}`;\n}\n","/** Light validation for incoming VTT — we do not parse cues, just confirm header. */\nexport function isVtt(text: string): boolean {\n const trimmed = text.replace(/^\\ufeff/, \"\").trimStart();\n return trimmed.startsWith(\"WEBVTT\");\n}\n","import type { SubtitleTrackInfo, TransportConfig } from \"../types.js\";\nimport { fetchWith } from \"../util/transport.js\";\nimport { srtToVtt } from \"./srt.js\";\nimport { isVtt } from \"./vtt.js\";\n\nexport { srtToVtt } from \"./srt.js\";\nexport { SubtitleOverlay } from \"./render.js\";\n\n/**\n * Discover sidecar `.srt` / `.vtt` files next to the source. Requires the\n * caller to pass a `FileSystemDirectoryHandle` (e.g. via the File System\n * Access API). Without that handle we can't enumerate sibling files.\n *\n * The returned `url` fields are blob URLs created via `URL.createObjectURL`.\n * They must be revoked by the caller (e.g. via `revokeSubtitleResources()`)\n * when the player tears down or the source changes — otherwise repeated\n * source swaps in a single-page app will leak.\n */\nexport interface DiscoveredSidecar {\n url: string;\n format: \"srt\" | \"vtt\";\n language?: string;\n}\n\nexport async function discoverSidecars(\n file: File,\n directory: FileSystemDirectoryHandle,\n): Promise<DiscoveredSidecar[]> {\n const baseName = file.name.replace(/\\.[^.]+$/, \"\");\n const found: DiscoveredSidecar[] = [];\n\n // Walk the directory and look for `${baseName}*.srt` / `*.vtt`.\n for await (const [name, handle] of (directory as unknown as AsyncIterable<[string, FileSystemHandle]>)) {\n if (handle.kind !== \"file\") continue;\n if (!name.startsWith(baseName)) continue;\n const lower = name.toLowerCase();\n let format: \"srt\" | \"vtt\" | null = null;\n if (lower.endsWith(\".srt\")) format = \"srt\";\n else if (lower.endsWith(\".vtt\")) format = \"vtt\";\n if (!format) continue;\n\n const sidecarFile = await (handle as FileSystemFileHandle).getFile();\n const url = URL.createObjectURL(sidecarFile);\n\n // Try to extract a language tag (eg. movie.en.srt → \"en\").\n const langMatch = name.slice(baseName.length).match(/[._-]([a-z]{2,3})(?:[._-]|\\.)/i);\n found.push({\n url,\n format,\n language: langMatch?.[1],\n });\n }\n\n return found;\n}\n\n/**\n * Owns every blob URL created during sidecar discovery and SRT→VTT\n * conversion for a single player session. Revoking the bag releases all of\n * them in one shot at teardown.\n */\nexport class SubtitleResourceBag {\n private urls = new Set<string>();\n\n /** Track an externally-created blob URL (e.g. from `discoverSidecars`). */\n track(url: string): void {\n this.urls.add(url);\n }\n\n /** Convenience: create a blob URL and track it in one call. */\n createObjectURL(blob: Blob): string {\n const url = URL.createObjectURL(blob);\n this.urls.add(url);\n return url;\n }\n\n /** Revoke every tracked URL. Idempotent — safe to call multiple times. */\n revokeAll(): void {\n for (const u of this.urls) URL.revokeObjectURL(u);\n this.urls.clear();\n }\n}\n\n/**\n * Attach `<track>` elements for each subtitle to the player's `<video>`. SRT\n * sources are converted to VTT first via blob URLs because `<track>` only\n * accepts WebVTT.\n *\n * Pass a {@link SubtitleResourceBag} so the player can revoke the generated\n * blob URLs at teardown. Without one, every SRT subtitle leaks a blob URL\n * per attach.\n *\n * Errors during fetch/parse are caught per-track and reported via the\n * `onError` callback (if provided) so a single bad subtitle doesn't break\n * bootstrap. Subtitles are *not* load-bearing for playback.\n */\nexport async function attachSubtitleTracks(\n video: HTMLVideoElement,\n tracks: SubtitleTrackInfo[],\n bag?: SubtitleResourceBag,\n onError?: (err: Error, track: SubtitleTrackInfo) => void,\n transport?: TransportConfig,\n): Promise<void> {\n const doFetch = fetchWith(transport);\n\n // Clear existing dynamically-attached tracks.\n for (const t of Array.from(video.querySelectorAll(\"track[data-avbridge]\"))) {\n t.remove();\n }\n\n for (const t of tracks) {\n if (!t.sidecarUrl) continue;\n try {\n let url = t.sidecarUrl;\n if (t.format === \"srt\") {\n const res = await doFetch(t.sidecarUrl, transport?.requestInit);\n const text = await res.text();\n const vtt = srtToVtt(text);\n const blob = new Blob([vtt], { type: \"text/vtt\" });\n url = bag ? bag.createObjectURL(blob) : URL.createObjectURL(blob);\n } else if (t.format === \"vtt\") {\n // Validate quickly so a malformed file fails loudly here.\n const res = await doFetch(t.sidecarUrl, transport?.requestInit);\n const text = await res.text();\n if (!isVtt(text)) {\n // eslint-disable-next-line no-console\n console.warn(\"[avbridge] subtitle missing WEBVTT header:\", t.sidecarUrl);\n }\n }\n const trackEl = document.createElement(\"track\");\n trackEl.kind = \"subtitles\";\n trackEl.src = url;\n trackEl.srclang = t.language ?? \"und\";\n trackEl.label = t.language ?? `Subtitle ${t.id}`;\n trackEl.dataset.avbridge = \"true\";\n video.appendChild(trackEl);\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n onError?.(e, t);\n }\n }\n}\n","import { TypedEmitter } from \"./events.js\";\nimport { probe } from \"./probe/index.js\";\nimport { classify } from \"./classify/index.js\";\nimport { Diagnostics } from \"./diagnostics.js\";\nimport { PluginRegistry } from \"./plugins/registry.js\";\nimport { registerBuiltins } from \"./plugins/builtin.js\";\nimport { discoverSidecars, attachSubtitleTracks, SubtitleResourceBag } from \"./subtitles/index.js\";\nimport { dbg } from \"./util/debug.js\";\nimport type {\n Classification,\n CreatePlayerOptions,\n DiagnosticsSnapshot,\n MediaContext,\n PlaybackSession,\n PlayerEventMap,\n PlayerEventName,\n StrategyName,\n TransportConfig,\n Listener,\n} from \"./types.js\";\nimport { AvbridgeError, ERR_PLAYER_NOT_READY, ERR_ALL_STRATEGIES_EXHAUSTED } from \"./errors.js\";\n\nexport class UnifiedPlayer {\n private emitter = new TypedEmitter<PlayerEventMap>();\n private session: PlaybackSession | null = null;\n private diag = new Diagnostics();\n private timeupdateInterval: ReturnType<typeof setInterval> | null = null;\n\n // Saved from bootstrap for strategy switching\n private mediaContext: MediaContext | null = null;\n private classification: Classification | null = null;\n\n // Stall detection\n private stallTimer: ReturnType<typeof setInterval> | null = null;\n private lastProgressTime = 0;\n private lastProgressPosition = -1;\n private errorListener: (() => void) | null = null;\n\n // Bound so we can removeEventListener in destroy(); without this the\n // listener outlives the player and accumulates on elements that swap\n // source (e.g. <avbridge-video>).\n private endedListener: (() => void) | null = null;\n\n // Background tab handling. userIntent is what the user last asked for\n // (play vs pause) — used to decide whether to auto-resume on visibility\n // return. autoPausedForVisibility tracks whether we paused because the\n // tab was hidden, so we don't resume playback the user deliberately\n // paused (e.g. via media keys while hidden).\n private userIntent: \"play\" | \"pause\" = \"pause\";\n private autoPausedForVisibility = false;\n private visibilityListener: (() => void) | null = null;\n\n // Serializes escalation / setStrategy calls\n private switchingPromise: Promise<void> = Promise.resolve();\n\n // Owns blob URLs created during sidecar discovery + SRT->VTT conversion.\n // Revoked at destroy() so repeated source swaps don't leak.\n private subtitleResources = new SubtitleResourceBag();\n\n // Transport config extracted from CreatePlayerOptions. Threaded to probe,\n // subtitle fetches, and strategy session creators. Not stored on MediaContext\n // because it's runtime config, not media analysis.\n private readonly transport: TransportConfig | undefined;\n\n /**\n * @internal Use {@link createPlayer} or {@link UnifiedPlayer.create} instead.\n */\n private constructor(\n private readonly options: CreatePlayerOptions,\n private readonly registry: PluginRegistry,\n ) {\n const { requestInit, fetchFn } = options;\n if (requestInit || fetchFn) {\n this.transport = { requestInit, fetchFn };\n }\n }\n\n static async create(options: CreatePlayerOptions): Promise<UnifiedPlayer> {\n const registry = new PluginRegistry();\n registerBuiltins(registry);\n if (options.plugins) {\n for (const p of options.plugins) registry.register(p, /* prepend */ true);\n }\n const player = new UnifiedPlayer(options, registry);\n try {\n await player.bootstrap();\n } catch (err) {\n (err as Error & { player?: UnifiedPlayer }).player = player;\n throw err;\n }\n return player;\n }\n\n private async bootstrap(): Promise<void> {\n const bootstrapStart = performance.now();\n try {\n dbg.info(\"bootstrap\", \"start\");\n const ctx = await dbg.timed(\"probe\", \"probe\", 3000, () => probe(this.options.source, this.transport));\n dbg.info(\"probe\",\n `container=${ctx.container} video=${ctx.videoTracks[0]?.codec ?? \"-\"} ` +\n `audio=${ctx.audioTracks[0]?.codec ?? \"-\"} probedBy=${ctx.probedBy}`,\n );\n this.diag.recordProbe(ctx);\n this.mediaContext = ctx;\n\n // Merge sidecar / explicit subtitles\n if (this.options.subtitles) {\n for (const s of this.options.subtitles) {\n ctx.subtitleTracks.push({\n id: ctx.subtitleTracks.length,\n format: s.format ?? (s.url.endsWith(\".srt\") ? \"srt\" : \"vtt\"),\n language: s.language,\n sidecarUrl: s.url,\n });\n }\n }\n if (this.options.directory && this.options.source instanceof File) {\n const found = await discoverSidecars(this.options.source, this.options.directory);\n for (const s of found) {\n // Track every blob URL we adopted from discovery so it gets\n // revoked at destroy() — otherwise repeated source changes leak.\n this.subtitleResources.track(s.url);\n ctx.subtitleTracks.push({\n id: ctx.subtitleTracks.length,\n format: s.format,\n language: s.language,\n sidecarUrl: s.url,\n });\n }\n }\n\n const decision = this.options.initialStrategy\n ? buildInitialDecision(this.options.initialStrategy, ctx)\n : classify(ctx);\n dbg.info(\"classify\",\n `strategy=${decision.strategy} class=${decision.class} reason=\"${decision.reason}\"` +\n (decision.fallbackChain ? ` fallback=${decision.fallbackChain.join(\"→\")}` : \"\"),\n );\n this.classification = decision;\n this.diag.recordClassification(decision);\n\n this.emitter.emitSticky(\"strategy\", {\n strategy: decision.strategy,\n reason: decision.reason,\n });\n\n // Try the primary strategy, falling through the chain on failure\n await this.startSession(decision.strategy, decision.reason);\n\n // Apply subtitles for non-canvas strategies. Per-track failures are\n // caught inside attachSubtitleTracks and logged via console.warn —\n // subtitles are not load-bearing, so a bad sidecar must not break\n // bootstrap.\n if (this.session!.strategy !== \"fallback\" && this.session!.strategy !== \"hybrid\") {\n await attachSubtitleTracks(\n this.options.target,\n ctx.subtitleTracks,\n this.subtitleResources,\n (err, track) => {\n // eslint-disable-next-line no-console\n console.warn(`[avbridge] subtitle ${track.id} failed: ${err.message}`);\n },\n this.transport,\n );\n }\n\n this.emitter.emitSticky(\"tracks\", {\n video: ctx.videoTracks,\n audio: ctx.audioTracks,\n subtitle: ctx.subtitleTracks,\n });\n\n this.startTimeupdateLoop();\n this.endedListener = () => this.emitter.emit(\"ended\", undefined);\n this.options.target.addEventListener(\"ended\", this.endedListener);\n\n // Auto-pause on background tab (unless explicitly opted out).\n // Chrome throttles rAF and setTimeout in hidden tabs, so playback\n // degrades anyway — better to pause cleanly and resume on return.\n if (this.options.backgroundBehavior !== \"continue\" && typeof document !== \"undefined\") {\n this.visibilityListener = () => this.onVisibilityChange();\n document.addEventListener(\"visibilitychange\", this.visibilityListener);\n }\n\n this.emitter.emitSticky(\"ready\", undefined);\n const bootstrapElapsed = performance.now() - bootstrapStart;\n dbg.info(\"bootstrap\", `ready in ${bootstrapElapsed.toFixed(0)}ms`);\n if (bootstrapElapsed > 5000) {\n // eslint-disable-next-line no-console\n console.warn(\n \"[avbridge:bootstrap]\",\n `total bootstrap time ${bootstrapElapsed.toFixed(0)}ms — unusually slow. ` +\n `Enable globalThis.AVBRIDGE_DEBUG for a per-phase breakdown.`,\n );\n }\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n this.diag.recordError(e);\n this.emitter.emit(\"error\", e);\n throw e;\n }\n }\n\n /**\n * Try to start a session with the given strategy. On failure, walk the\n * fallback chain. Throws only if all strategies are exhausted.\n */\n private async startSession(strategy: StrategyName, reason: string): Promise<void> {\n const plugin = this.registry.findFor(this.mediaContext!, strategy);\n if (!plugin) {\n throw new Error(`no plugin available for strategy \"${strategy}\"`);\n }\n\n try {\n this.session = await plugin.execute(this.mediaContext!, this.options.target, this.transport);\n } catch (err) {\n // Try the fallback chain\n const chain = this.classification?.fallbackChain;\n if (chain && chain.length > 0) {\n const next = chain.shift()!;\n console.warn(`[avbridge] ${strategy} failed (${(err as Error).message}), escalating to ${next}`);\n this.emitter.emit(\"strategychange\", {\n from: strategy,\n to: next,\n reason: `${strategy} failed: ${(err as Error).message}`,\n currentTime: 0,\n });\n this.diag.recordStrategySwitch(next, `${strategy} failed: ${(err as Error).message}`);\n return this.startSession(next, `escalated from ${strategy}`);\n }\n throw err;\n }\n\n // Wire up fatal error handler for hybrid/fallback escalation\n this.session.onFatalError?.((fatalReason) => {\n void this.escalate(fatalReason);\n });\n\n // Attach stall supervisor\n this.attachSupervisor();\n\n // Update sticky strategy event if we ended up on a different strategy\n if (this.session.strategy !== strategy) {\n this.emitter.emitSticky(\"strategy\", {\n strategy: this.session.strategy,\n reason,\n });\n }\n }\n\n // ── Escalation ──────────────────────────────────────────────────────────\n\n private async escalate(reason: string): Promise<void> {\n // Serialize with other switch operations\n this.switchingPromise = this.switchingPromise.then(() =>\n this.doEscalate(reason),\n ).catch((err) => {\n this.emitter.emit(\"error\", err instanceof Error ? err : new Error(String(err)));\n });\n await this.switchingPromise;\n }\n\n private async doEscalate(reason: string): Promise<void> {\n const chain = this.classification?.fallbackChain;\n if (!chain || chain.length === 0) {\n this.emitter.emit(\"error\", new Error(\n `strategy \"${this.session?.strategy}\" failed: ${reason} (no fallback available)`,\n ));\n return;\n }\n\n const currentTime = this.session?.getCurrentTime() ?? 0;\n const wasPlaying = this.session ? !this.options.target.paused : false;\n const fromStrategy = this.session?.strategy ?? \"native\";\n\n // Tear down the current session before walking the chain — once we\n // commit to escalating, the existing session is going away regardless\n // of which fallback step succeeds.\n this.clearSupervisor();\n if (this.session) {\n try { await this.session.destroy(); } catch { /* ignore */ }\n this.session = null;\n }\n\n // Walk every remaining entry in the chain. Previously this method\n // popped exactly one entry and gave up if its plugin failed to start —\n // a recoverable failure in one fallback step blocked later viable\n // strategies (inconsistent with startSession() which already loops).\n const errors: string[] = [];\n while (chain.length > 0) {\n const nextStrategy = chain.shift()!;\n console.warn(`[avbridge] escalating from ${fromStrategy} to ${nextStrategy}: ${reason}`);\n\n this.emitter.emit(\"strategychange\", {\n from: fromStrategy,\n to: nextStrategy,\n reason,\n currentTime,\n });\n this.diag.recordStrategySwitch(nextStrategy, reason);\n\n const plugin = this.registry.findFor(this.mediaContext!, nextStrategy);\n if (!plugin) {\n errors.push(`${nextStrategy}: no plugin available`);\n continue;\n }\n\n try {\n this.session = await plugin.execute(this.mediaContext!, this.options.target, this.transport);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push(`${nextStrategy}: ${msg}`);\n console.warn(`[avbridge] ${nextStrategy} failed during escalation, trying next: ${msg}`);\n continue;\n }\n\n // Success — finish wiring and restore playback.\n this.emitter.emitSticky(\"strategy\", {\n strategy: nextStrategy,\n reason: `escalated: ${reason}`,\n });\n this.session.onFatalError?.((fatalReason) => {\n void this.escalate(fatalReason);\n });\n this.attachSupervisor();\n try {\n await this.session.seek(currentTime);\n if (wasPlaying) await this.session.play();\n } catch (err) {\n console.warn(\"[avbridge] failed to restore position after escalation:\", err);\n }\n return;\n }\n\n // Chain exhausted with no working strategy.\n this.emitter.emit(\"error\", new AvbridgeError(\n ERR_ALL_STRATEGIES_EXHAUSTED,\n `All playback strategies failed: ${errors.join(\"; \")}`,\n \"This file may require a codec or container that isn't available in this browser. Try the fallback strategy or check browser codec support.\",\n ));\n }\n\n // ── Stall supervision ─────────────────────────────────────────────────\n\n private attachSupervisor(): void {\n this.clearSupervisor();\n if (this.options.autoEscalate === false) return;\n if (!this.classification?.fallbackChain?.length) return;\n\n const strategy = this.session?.strategy;\n if (strategy === \"native\" || strategy === \"remux\") {\n // Monitor currentTime progress\n this.lastProgressPosition = this.options.target.currentTime;\n this.lastProgressTime = performance.now();\n\n this.stallTimer = setInterval(() => {\n const t = this.options.target;\n if (t.paused || t.ended || t.readyState < 2) {\n this.lastProgressPosition = t.currentTime;\n this.lastProgressTime = performance.now();\n return;\n }\n if (t.currentTime !== this.lastProgressPosition) {\n this.lastProgressPosition = t.currentTime;\n this.lastProgressTime = performance.now();\n return;\n }\n if (performance.now() - this.lastProgressTime > 5000) {\n void this.escalate(\n `${strategy} strategy stalled for 5s at ${t.currentTime.toFixed(1)}s`,\n );\n }\n }, 1000);\n\n // Listen for media element errors\n const onError = () => {\n void this.escalate(\n `${strategy} strategy error: ${this.options.target.error?.message ?? \"unknown\"}`,\n );\n };\n this.options.target.addEventListener(\"error\", onError, { once: true });\n this.errorListener = onError;\n }\n // Hybrid/fallback escalation is handled via onFatalError callback\n }\n\n private clearSupervisor(): void {\n if (this.stallTimer) {\n clearInterval(this.stallTimer);\n this.stallTimer = null;\n }\n if (this.errorListener) {\n this.options.target.removeEventListener(\"error\", this.errorListener);\n this.errorListener = null;\n }\n }\n\n // ── Public: manual strategy switch ────────────────────────────────────\n\n /** Manually switch to a different playback strategy. Preserves current position and play/pause state. Concurrent calls are serialized. */\n async setStrategy(strategy: StrategyName, reason?: string): Promise<void> {\n if (!this.mediaContext) throw new AvbridgeError(ERR_PLAYER_NOT_READY, \"Player not ready — wait for the 'ready' event before calling playback methods.\", \"Await the 'ready' event or check player.readyState before calling play/pause/seek.\");\n if (this.session?.strategy === strategy) return;\n\n this.switchingPromise = this.switchingPromise.then(() =>\n this.doSetStrategy(strategy, reason),\n );\n await this.switchingPromise;\n }\n\n private async doSetStrategy(strategy: StrategyName, reason?: string): Promise<void> {\n const currentTime = this.session?.getCurrentTime() ?? 0;\n const wasPlaying = this.session ? !this.options.target.paused : false;\n const fromStrategy = this.session?.strategy ?? \"native\";\n const switchReason = reason ?? `manual switch to ${strategy}`;\n\n this.emitter.emit(\"strategychange\", {\n from: fromStrategy,\n to: strategy,\n reason: switchReason,\n currentTime,\n });\n this.diag.recordStrategySwitch(strategy, switchReason);\n\n this.clearSupervisor();\n if (this.session) {\n try { await this.session.destroy(); } catch { /* ignore */ }\n this.session = null;\n }\n\n const plugin = this.registry.findFor(this.mediaContext!, strategy);\n if (!plugin) throw new Error(`no plugin available for strategy \"${strategy}\"`);\n\n this.session = await plugin.execute(this.mediaContext!, this.options.target, this.transport);\n\n this.emitter.emitSticky(\"strategy\", {\n strategy,\n reason: switchReason,\n });\n\n this.session.onFatalError?.((fatalReason) => {\n void this.escalate(fatalReason);\n });\n this.attachSupervisor();\n\n try {\n await this.session.seek(currentTime);\n if (wasPlaying) await this.session.play();\n } catch (err) {\n console.warn(\"[avbridge] failed to restore position after strategy switch:\", err);\n }\n }\n\n // ── Timeupdate loop ───────────────────────────────────────────────────\n\n private startTimeupdateLoop(): void {\n this.timeupdateInterval = setInterval(() => {\n const t = this.session?.getCurrentTime() ?? this.options.target.currentTime;\n this.emitter.emit(\"timeupdate\", { currentTime: t });\n }, 250);\n }\n\n // ── Public API ────────────────────────────────────────────────────────\n\n /** Subscribe to a player event. Returns an unsubscribe function. Sticky events (strategy, ready, tracks) replay for late subscribers. */\n on<K extends PlayerEventName>(event: K, fn: Listener<PlayerEventMap[K]>): () => void {\n return this.emitter.on(event, fn);\n }\n\n /** Remove a previously registered event listener. */\n off<K extends PlayerEventName>(event: K, fn: Listener<PlayerEventMap[K]>): void {\n this.emitter.off(event, fn);\n }\n\n /** Begin or resume playback. Throws if the player is not ready. */\n async play(): Promise<void> {\n if (!this.session) throw new AvbridgeError(ERR_PLAYER_NOT_READY, \"Player not ready — wait for the 'ready' event before calling playback methods.\", \"Await the 'ready' event or check player.readyState before calling play/pause/seek.\");\n this.userIntent = \"play\";\n this.autoPausedForVisibility = false;\n await this.session.play();\n }\n\n /** Pause playback. No-op if the player is not ready or already paused. */\n pause(): void {\n this.userIntent = \"pause\";\n this.autoPausedForVisibility = false;\n this.session?.pause();\n }\n\n /**\n * Handle browser tab visibility changes. On hide: pause if the user\n * had been playing. On show: resume if we were the one who paused.\n * Skips when `backgroundBehavior: \"continue\"` is set (listener isn't\n * installed in that case).\n */\n private onVisibilityChange(): void {\n if (!this.session) return;\n const action = decideVisibilityAction({\n hidden: document.hidden,\n userIntent: this.userIntent,\n sessionIsPlaying: !this.options.target.paused,\n autoPausedForVisibility: this.autoPausedForVisibility,\n });\n if (action === \"pause\") {\n this.autoPausedForVisibility = true;\n dbg.info(\"visibility\", \"tab hidden — auto-paused\");\n this.session.pause();\n } else if (action === \"resume\") {\n this.autoPausedForVisibility = false;\n dbg.info(\"visibility\", \"tab visible — auto-resuming\");\n void this.session.play().catch((err) => {\n // eslint-disable-next-line no-console\n console.warn(\"[avbridge] auto-resume after tab return failed:\", err);\n });\n }\n }\n\n /** Seek to the given time in seconds. Throws if the player is not ready. */\n async seek(time: number): Promise<void> {\n if (!this.session) throw new AvbridgeError(ERR_PLAYER_NOT_READY, \"Player not ready — wait for the 'ready' event before calling playback methods.\", \"Await the 'ready' event or check player.readyState before calling play/pause/seek.\");\n await this.session.seek(time);\n }\n\n /** Switch the active audio track by track ID. Throws if the player is not ready. */\n async setAudioTrack(id: number): Promise<void> {\n if (!this.session) throw new AvbridgeError(ERR_PLAYER_NOT_READY, \"Player not ready — wait for the 'ready' event before calling playback methods.\", \"Await the 'ready' event or check player.readyState before calling play/pause/seek.\");\n await this.session.setAudioTrack(id);\n }\n\n /** Switch the active subtitle track by track ID, or pass `null` to disable subtitles. */\n async setSubtitleTrack(id: number | null): Promise<void> {\n if (!this.session) throw new AvbridgeError(ERR_PLAYER_NOT_READY, \"Player not ready — wait for the 'ready' event before calling playback methods.\", \"Await the 'ready' event or check player.readyState before calling play/pause/seek.\");\n await this.session.setSubtitleTrack(id);\n }\n\n /** Return a snapshot of current diagnostics: container, codecs, strategy, runtime stats, and strategy history. */\n getDiagnostics(): DiagnosticsSnapshot {\n if (this.session) {\n this.diag.recordRuntime(this.session.getRuntimeStats());\n }\n return this.diag.snapshot();\n }\n\n /** Return the total duration in seconds, or `NaN` if unknown. */\n getDuration(): number {\n const fromDiag = this.diag.snapshot().duration;\n if (typeof fromDiag === \"number\" && Number.isFinite(fromDiag)) return fromDiag;\n const fromVideo = this.options.target.duration;\n return Number.isFinite(fromVideo) ? fromVideo : NaN;\n }\n\n /** Return the current playback position in seconds. */\n getCurrentTime(): number {\n return this.session?.getCurrentTime() ?? this.options.target.currentTime ?? 0;\n }\n\n /** Tear down the player: stop timers, destroy the active session, remove all event listeners. The player is unusable after this call. */\n async destroy(): Promise<void> {\n if (this.timeupdateInterval) {\n clearInterval(this.timeupdateInterval);\n this.timeupdateInterval = null;\n }\n this.clearSupervisor();\n if (this.endedListener) {\n this.options.target.removeEventListener(\"ended\", this.endedListener);\n this.endedListener = null;\n }\n if (this.visibilityListener) {\n document.removeEventListener(\"visibilitychange\", this.visibilityListener);\n this.visibilityListener = null;\n }\n if (this.session) {\n await this.session.destroy();\n this.session = null;\n }\n // Revoke every blob URL we created for sidecar discovery / SRT->VTT\n // conversion. This is the cleanup leg of the leak fix.\n this.subtitleResources.revokeAll();\n this.emitter.removeAll();\n }\n}\n\nexport async function createPlayer(options: CreatePlayerOptions): Promise<UnifiedPlayer> {\n return UnifiedPlayer.create(options);\n}\n\n/**\n * Pure decision function for visibility-change handling. Separated from\n * the class method so it can be unit-tested without a full player\n * instance.\n *\n * @internal — exported for unit tests; not part of the public API.\n */\nexport function decideVisibilityAction(state: {\n hidden: boolean;\n userIntent: \"play\" | \"pause\";\n sessionIsPlaying: boolean;\n autoPausedForVisibility: boolean;\n}): \"pause\" | \"resume\" | \"noop\" {\n if (state.hidden) {\n // Tab hidden: pause if user had been playing and session is active\n if (state.userIntent === \"play\" && state.sessionIsPlaying) return \"pause\";\n return \"noop\";\n }\n // Tab visible: resume only if we're the one who paused\n if (state.autoPausedForVisibility) return \"resume\";\n return \"noop\";\n}\n\n/**\n * Build a synthetic classification for an explicit `initialStrategy` override.\n * The `class` is derived from the chosen strategy so diagnostics and any\n * downstream consumer of `strategyClass` see the real strategy. The fallback\n * chain is inherited from the natural classification but must never contain\n * `initial` itself — otherwise `startSession` would retry the strategy that\n * just failed before escalating.\n *\n * @internal — exported for unit tests; not part of the public API.\n */\nexport function buildInitialDecision(\n initial: StrategyName,\n ctx: MediaContext,\n): Classification {\n const natural = classify(ctx);\n const cls = strategyToClass(initial, natural);\n const inherited = natural.fallbackChain ?? defaultFallbackChain(initial);\n const fallbackChain = inherited.filter((s) => s !== initial);\n return {\n class: cls,\n strategy: initial,\n reason: `initial strategy \"${initial}\" requested via options.initialStrategy`,\n fallbackChain,\n };\n}\n\nfunction strategyToClass(\n strategy: StrategyName,\n natural: Classification,\n): Classification[\"class\"] {\n // If the natural classification picked the same strategy, use its class.\n if (natural.strategy === strategy) return natural.class;\n switch (strategy) {\n case \"native\": return \"NATIVE\";\n case \"remux\": return \"REMUX_CANDIDATE\";\n case \"hybrid\": return \"HYBRID_CANDIDATE\";\n case \"fallback\": return \"FALLBACK_REQUIRED\";\n }\n}\n\nfunction defaultFallbackChain(strategy: StrategyName): StrategyName[] {\n switch (strategy) {\n case \"native\": return [\"remux\", \"hybrid\", \"fallback\"];\n case \"remux\": return [\"hybrid\", \"fallback\"];\n case \"hybrid\": return [\"fallback\"];\n case \"fallback\": return [];\n }\n}\n","/**\n * `<avbridge-video>` — `HTMLMediaElement`-compatible primitive backed by the\n * avbridge engine. Drop-in replacement for a `<video>` element with no\n * built-in UI.\n *\n * Purpose:\n *\n * 1. Validate the public API by being a real consumer of `createPlayer()`.\n * 2. Drive lifecycle correctness in the core via adversarial integration tests.\n * 3. Give consumers a `<video>`-compatible primitive they can wrap with\n * their own UI.\n *\n * **It is not a player UI framework.** The tag name `<avbridge-player>` is\n * reserved for a future controls-bearing element. See\n * `docs/dev/WEB_COMPONENT_SPEC.md` for the full spec, lifecycle invariants,\n * and edge case list.\n */\n\nimport { createPlayer, type UnifiedPlayer } from \"../player.js\";\nimport type {\n MediaInput,\n StrategyName,\n StrategyClass,\n AudioTrackInfo,\n SubtitleTrackInfo,\n DiagnosticsSnapshot,\n} from \"../types.js\";\n\n/** Strategy preference passed via the `preferstrategy` attribute. */\ntype PreferredStrategy = \"auto\" | StrategyName;\n\nconst PREFERRED_STRATEGY_VALUES = new Set<PreferredStrategy>([\n \"auto\",\n \"native\",\n \"remux\",\n \"hybrid\",\n \"fallback\",\n]);\n\n/**\n * Standard `HTMLMediaElement` events we forward from the inner `<video>`\n * to the wrapper element so consumers can `el.addEventListener(\"loadedmetadata\", ...)`\n * exactly like they would with a real `<video>`. The element also dispatches\n * its own custom events (`strategychange`, `ready`, `error`, etc.) — those\n * are NOT in this list because they're avbridge-specific.\n *\n * Note: `progress` and `timeupdate` are deliberately NOT forwarded here.\n * `progress` is dispatched by the constructor with our own `{ buffered }`\n * detail. `timeupdate` is dispatched by the player layer (so it works for\n * canvas-rendered fallback playback too, where the inner <video> never\n * fires its own timeupdate).\n */\nconst FORWARDED_VIDEO_EVENTS = [\n \"loadstart\",\n \"loadedmetadata\",\n \"loadeddata\",\n \"canplay\",\n \"canplaythrough\",\n \"play\",\n \"playing\",\n \"pause\",\n \"seeking\",\n \"seeked\",\n \"volumechange\",\n \"ratechange\",\n \"durationchange\",\n \"waiting\",\n \"stalled\",\n \"emptied\",\n \"resize\",\n \"error\",\n] as const;\n\n/**\n * `HTMLElement` is a browser-only global. SSR frameworks (Next.js, Astro,\n * Remix, etc.) commonly import library modules on the server to extract\n * types or do tree-shaking, even if the user only ends up using them in\n * the browser. If we extended `HTMLElement` directly, the `class extends`\n * expression would be evaluated at module load time and crash in Node.\n *\n * The fix: in non-browser environments, fall back to an empty stub class.\n * The element is never *constructed* server-side (the registration in\n * `element.ts` is guarded by `typeof customElements !== \"undefined\"`), so\n * the stub is never instantiated — it just lets the class declaration\n * evaluate cleanly so the module can be imported anywhere.\n */\nconst HTMLElementCtor: typeof HTMLElement =\n typeof HTMLElement !== \"undefined\"\n ? HTMLElement\n : (class {} as unknown as typeof HTMLElement);\n\n/**\n * Custom element. Lifecycle correctness is enforced via a monotonically\n * increasing `_bootstrapId`: every async bootstrap captures the ID at start\n * and discards itself if the ID has changed by the time it resolves. This\n * single pattern handles disconnect-during-bootstrap, rapid src reassignment,\n * bootstrap races, and destroy-during-bootstrap.\n */\nexport class AvbridgeVideoElement extends HTMLElementCtor {\n static readonly observedAttributes = [\n \"src\",\n \"autoplay\",\n \"muted\",\n \"loop\",\n \"preload\",\n \"poster\",\n \"playsinline\",\n \"crossorigin\",\n \"disableremoteplayback\",\n \"diagnostics\",\n \"preferstrategy\",\n ];\n\n // ── Internal state ─────────────────────────────────────────────────────\n\n /** The shadow DOM `<video>` element that strategies render into. */\n private _videoEl!: HTMLVideoElement;\n\n /** Active player session, if any. Cleared on teardown. */\n private _player: UnifiedPlayer | null = null;\n\n /**\n * Monotonic counter incremented on every (re)bootstrap. Async bootstrap\n * work captures the current ID; if it doesn't match by the time the work\n * resolves, the work is discarded.\n */\n private _bootstrapId = 0;\n\n /** True after destroy() — element is permanently unusable. */\n private _destroyed = false;\n\n /** Internal source state. Either string-form (src) OR rich (source). */\n private _src: string | null = null;\n private _source: MediaInput | null = null;\n\n /**\n * Set when the `source` property setter is in the middle of clearing the\n * `src` attribute as part of mutual exclusion. The attributeChangedCallback\n * checks this flag and skips its normal \"clear source\" side effect, which\n * would otherwise wipe the value we just set.\n */\n private _suppressSrcAttrCallback = false;\n\n /** Last-known runtime state surfaced via getters. */\n private _strategy: StrategyName | null = null;\n private _strategyClass: StrategyClass | null = null;\n private _audioTracks: AudioTrackInfo[] = [];\n private _subtitleTracks: SubtitleTrackInfo[] = [];\n\n /**\n * Initial strategy preference. `\"auto\"` means \"let the classifier decide\";\n * any other value is passed to `createPlayer({ initialStrategy })` and\n * skips classification on the next bootstrap. Note that this only affects\n * the *initial* pick — runtime fallback escalation still applies, so a\n * preference of `\"native\"` may still escalate to remux/hybrid/fallback if\n * native fails.\n */\n private _preferredStrategy: PreferredStrategy = \"auto\";\n\n /** Set if currentTime was assigned before the player was ready. */\n private _pendingSeek: number | null = null;\n /** Set if play() was called before the player was ready. */\n private _pendingPlay = false;\n\n /** MutationObserver tracking light-DOM `<track>` children. */\n private _trackObserver: MutationObserver | null = null;\n\n // ── Construction & lifecycle ───────────────────────────────────────────\n\n constructor() {\n super();\n const root = this.attachShadow({ mode: \"open\" });\n\n // A positioned wrapper inside the shadow root. The fallback strategy\n // overlays a canvas on top of the <video> via `target.parentNode` —\n // that only works if the parent is a real Element with layout. Without\n // this wrapper, `target.parentElement` would be null (ShadowRoot is\n // not an Element) and the canvas would never attach to the DOM.\n const stage = document.createElement(\"div\");\n stage.setAttribute(\"part\", \"stage\");\n stage.style.cssText = \"position:relative;width:100%;height:100%;display:block;\";\n root.appendChild(stage);\n\n this._videoEl = document.createElement(\"video\");\n this._videoEl.setAttribute(\"part\", \"video\");\n this._videoEl.style.cssText = \"width:100%;height:100%;display:block;background:#000;\";\n this._videoEl.playsInline = true;\n stage.appendChild(this._videoEl);\n\n // Forward the underlying <video>'s `progress` event so consumers can\n // observe buffered-range updates without reaching into the shadow DOM.\n // This works for native + remux (real video element with buffered\n // ranges) and is a no-op for hybrid/fallback (canvas-rendered, no\n // buffered ranges yet).\n this._videoEl.addEventListener(\"progress\", () => {\n if (this._destroyed) return;\n this._dispatch(\"progress\", { buffered: this._videoEl.buffered });\n });\n\n // Forward all standard HTMLMediaElement events from the inner <video>\n // so consumers can use the element as a drop-in <video> replacement.\n // Each event is re-dispatched on the wrapper element with no detail —\n // listeners that need state should read it from the element directly.\n for (const eventName of FORWARDED_VIDEO_EVENTS) {\n this._videoEl.addEventListener(eventName, () => {\n if (this._destroyed) return;\n this.dispatchEvent(new Event(eventName, { bubbles: false }));\n });\n }\n }\n\n connectedCallback(): void {\n if (this._destroyed) return;\n // Pick up any <track> children that were declared in HTML before the\n // element upgraded, and watch for future additions/removals.\n this._syncTextTracks();\n if (!this._trackObserver) {\n this._trackObserver = new MutationObserver(() => this._syncTextTracks());\n this._trackObserver.observe(this, { childList: true, subtree: false });\n }\n // Connection is the trigger for bootstrap. If we have a pending source\n // (set before connect), kick off bootstrap now.\n const source = this._activeSource();\n if (source != null) {\n void this._bootstrap(source);\n }\n }\n\n disconnectedCallback(): void {\n if (this._destroyed) return;\n if (this._trackObserver) {\n this._trackObserver.disconnect();\n this._trackObserver = null;\n }\n // Bump the bootstrap token so any in-flight async work is invalidated\n // before we tear down. _teardown() also bumps but we want the bump to\n // happen synchronously here so any awaited promise that resolves\n // between `disconnect` and `_teardown` sees the new ID.\n this._bootstrapId++;\n void this._teardown();\n }\n\n attributeChangedCallback(name: string, _oldValue: string | null, newValue: string | null): void {\n if (this._destroyed) return;\n switch (name) {\n case \"src\":\n if (this._suppressSrcAttrCallback) break;\n this._setSrcInternal(newValue);\n break;\n case \"autoplay\":\n case \"muted\":\n case \"loop\":\n case \"playsinline\":\n case \"disableremoteplayback\":\n // Reflect onto the underlying <video> element.\n if (newValue == null) this._videoEl.removeAttribute(name);\n else this._videoEl.setAttribute(name, newValue);\n break;\n case \"preload\":\n case \"poster\":\n case \"crossorigin\":\n if (newValue == null) this._videoEl.removeAttribute(name);\n else this._videoEl.setAttribute(name, newValue);\n break;\n case \"diagnostics\":\n // Phase A: no UI. Property is observable for users via getDiagnostics().\n break;\n case \"preferstrategy\":\n if (newValue && PREFERRED_STRATEGY_VALUES.has(newValue as PreferredStrategy)) {\n this._preferredStrategy = newValue as PreferredStrategy;\n } else {\n this._preferredStrategy = \"auto\";\n }\n break;\n }\n }\n\n // ── Source handling ────────────────────────────────────────────────────\n\n /** Returns the currently-active source (src or source), whichever is set. */\n private _activeSource(): MediaInput | null {\n if (this._source != null) return this._source;\n if (this._src != null) return this._src;\n return null;\n }\n\n /**\n * Mirror light-DOM `<track>` children into the shadow `<video>` so that\n * the browser's native text-track machinery picks them up. Called on\n * connect, on every mutation of light-DOM children, and once after each\n * source change so newly-set tracks survive a fresh `<video>`.\n *\n * Strategy: clone the children. We don't move them because the user's\n * code may still hold references to the originals (e.g. to set `default`).\n * The shadow copies are throwaway — we wipe them on every sync.\n */\n private _syncTextTracks(): void {\n // Remove existing shadow tracks.\n const existing = this._videoEl.querySelectorAll(\"track\");\n for (const t of Array.from(existing)) t.remove();\n // Clone every <track> light-DOM child into the shadow video.\n for (const child of Array.from(this.children)) {\n if (child.tagName === \"TRACK\") {\n const clone = child.cloneNode(true) as HTMLTrackElement;\n this._videoEl.appendChild(clone);\n }\n }\n }\n\n /** Internal src setter — separate from the property setter so the\n * attributeChangedCallback can use it without re-entering reflection. */\n private _setSrcInternal(value: string | null): void {\n // Same-value reassignment: no-op (#11 in the lifecycle list).\n if (value === this._src && this._source == null) return;\n this._src = value;\n this._source = null;\n this._onSourceChanged();\n }\n\n /** Called whenever the active source changes (src or source). */\n private _onSourceChanged(): void {\n if (this._destroyed) return;\n const source = this._activeSource();\n if (source == null) {\n // Null transition: tear down and stay idle.\n this._bootstrapId++;\n void this._teardown();\n return;\n }\n // Only bootstrap if we're connected to the DOM.\n if (this.isConnected) {\n void this._bootstrap(source);\n }\n }\n\n // ── Bootstrap (the only place a UnifiedPlayer is created) ──────────────\n\n private async _bootstrap(source: MediaInput): Promise<void> {\n if (this._destroyed) return;\n const id = ++this._bootstrapId;\n\n // Tear down any existing player before starting a new one. Pass the\n // bootstrap id we just claimed so teardown doesn't bump it again\n // (which would invalidate ourselves).\n await this._teardown(id);\n if (id !== this._bootstrapId || this._destroyed) return;\n\n this._dispatch(\"loadstart\", {});\n\n let player: UnifiedPlayer;\n try {\n player = await createPlayer({\n source,\n target: this._videoEl,\n // Honor the consumer's preferred initial strategy. \"auto\" means\n // \"let the classifier decide\" — the createPlayer call simply doesn't\n // pass initialStrategy in that case.\n ...(this._preferredStrategy !== \"auto\"\n ? { initialStrategy: this._preferredStrategy }\n : {}),\n });\n } catch (err) {\n // Stale or destroyed — silently abandon.\n if (id !== this._bootstrapId || this._destroyed) return;\n this._dispatchError(err);\n return;\n }\n\n // Race check: if anything happened during the await above, bail.\n if (id !== this._bootstrapId || this._destroyed || !this.isConnected) {\n try { await player.destroy(); } catch { /* ignore */ }\n return;\n }\n\n this._player = player;\n\n // Resync any light-DOM <track> children into the (possibly fresh) shadow\n // <video>. Strategies that swap or reset the inner video state would\n // otherwise lose the tracks the user declared in HTML.\n this._syncTextTracks();\n\n // Wire events. The unsubscribe handles are not stored individually\n // because destroy() will tear down the whole session anyway.\n player.on(\"strategy\", ({ strategy, reason }) => {\n // strategy event fires on initial classification AND any escalation.\n const cls = player.getDiagnostics().strategyClass;\n this._strategy = strategy;\n this._strategyClass = cls === \"pending\" ? null : cls;\n this._dispatch(\"strategychange\", {\n strategy,\n strategyClass: this._strategyClass,\n reason,\n diagnostics: player.getDiagnostics(),\n });\n });\n\n player.on(\"strategychange\", ({ from, to, reason, currentTime }) => {\n this._dispatch(\"strategychange\", {\n from,\n strategy: to,\n strategyClass: player.getDiagnostics().strategyClass === \"pending\" ? null : player.getDiagnostics().strategyClass,\n reason,\n currentTime,\n diagnostics: player.getDiagnostics(),\n });\n });\n\n player.on(\"tracks\", ({ video: _v, audio, subtitle }) => {\n this._audioTracks = audio;\n this._subtitleTracks = subtitle;\n this._dispatch(\"trackschange\", {\n audioTracks: audio,\n subtitleTracks: subtitle,\n });\n });\n\n player.on(\"error\", (err: Error) => {\n this._dispatchError(err);\n });\n\n player.on(\"timeupdate\", ({ currentTime }) => {\n this._dispatch(\"timeupdate\", { currentTime });\n });\n\n player.on(\"ended\", () => {\n this._dispatch(\"ended\", {});\n });\n\n player.on(\"ready\", () => {\n this._dispatch(\"ready\", { diagnostics: player.getDiagnostics() });\n // Apply any pending seek that was set before the player existed.\n if (this._pendingSeek != null) {\n const t = this._pendingSeek;\n this._pendingSeek = null;\n void player.seek(t).catch(() => { /* ignore */ });\n }\n // Honor any pending play() that was queued before bootstrap finished.\n if (this._pendingPlay) {\n this._pendingPlay = false;\n void player.play().catch(() => { /* ignore — autoplay may be blocked */ });\n } else if (this.autoplay) {\n void player.play().catch(() => { /* ignore */ });\n }\n });\n }\n\n /**\n * Tear down the active player and reset runtime state. Idempotent.\n * If `currentBootstrapId` is provided, the bootstrap counter is NOT\n * incremented (used by `_bootstrap()` to avoid invalidating itself).\n */\n private async _teardown(currentBootstrapId?: number): Promise<void> {\n if (currentBootstrapId == null) {\n // External callers (disconnect, destroy, source change) should bump\n // the counter so any in-flight bootstrap is invalidated. The internal\n // _bootstrap() call passes its own ID and we skip the bump.\n this._bootstrapId++;\n }\n const player = this._player;\n this._player = null;\n this._strategy = null;\n this._strategyClass = null;\n this._audioTracks = [];\n this._subtitleTracks = [];\n if (player) {\n try { await player.destroy(); } catch { /* ignore */ }\n }\n }\n\n // ── Public properties ──────────────────────────────────────────────────\n\n get src(): string | null {\n return this._src;\n }\n\n set src(value: string | null) {\n if (value == null) {\n this.removeAttribute(\"src\");\n } else {\n this.setAttribute(\"src\", value);\n }\n // attributeChangedCallback handles the rest.\n }\n\n get source(): MediaInput | null {\n return this._source;\n }\n\n set source(value: MediaInput | null) {\n // Same-value reassignment for rich values is identity-based.\n if (value === this._source && this._src == null) return;\n this._source = value;\n if (value != null) {\n // Setting source clears src. Suppress the attribute callback so\n // removing the src attribute doesn't wipe the source we just set.\n this._src = null;\n if (this.hasAttribute(\"src\")) {\n this._suppressSrcAttrCallback = true;\n try {\n this.removeAttribute(\"src\");\n } finally {\n this._suppressSrcAttrCallback = false;\n }\n }\n }\n this._onSourceChanged();\n }\n\n get autoplay(): boolean {\n return this.hasAttribute(\"autoplay\");\n }\n\n set autoplay(value: boolean) {\n if (value) this.setAttribute(\"autoplay\", \"\");\n else this.removeAttribute(\"autoplay\");\n }\n\n get muted(): boolean {\n return this.hasAttribute(\"muted\");\n }\n\n set muted(value: boolean) {\n if (value) this.setAttribute(\"muted\", \"\");\n else this.removeAttribute(\"muted\");\n }\n\n get loop(): boolean {\n return this.hasAttribute(\"loop\");\n }\n\n set loop(value: boolean) {\n if (value) this.setAttribute(\"loop\", \"\");\n else this.removeAttribute(\"loop\");\n }\n\n get preload(): \"none\" | \"metadata\" | \"auto\" {\n const v = this.getAttribute(\"preload\");\n return v === \"none\" || v === \"metadata\" || v === \"auto\" ? v : \"auto\";\n }\n\n set preload(value: \"none\" | \"metadata\" | \"auto\") {\n this.setAttribute(\"preload\", value);\n }\n\n get diagnostics(): boolean {\n return this.hasAttribute(\"diagnostics\");\n }\n\n set diagnostics(value: boolean) {\n if (value) this.setAttribute(\"diagnostics\", \"\");\n else this.removeAttribute(\"diagnostics\");\n }\n\n get preferredStrategy(): PreferredStrategy {\n return this._preferredStrategy;\n }\n\n set preferredStrategy(value: PreferredStrategy) {\n if (PREFERRED_STRATEGY_VALUES.has(value)) {\n this.setAttribute(\"preferstrategy\", value);\n }\n }\n\n get currentTime(): number {\n return this._player?.getCurrentTime() ?? 0;\n }\n\n set currentTime(value: number) {\n if (this._player) {\n void this._player.seek(value).catch(() => { /* ignore */ });\n } else {\n // Defer to the next bootstrap. The `ready` handler applies it.\n this._pendingSeek = value;\n }\n }\n\n get duration(): number {\n return this._player?.getDuration() ?? NaN;\n }\n\n get paused(): boolean {\n return this._videoEl.paused;\n }\n\n get ended(): boolean {\n return this._videoEl.ended;\n }\n\n get readyState(): number {\n return this._videoEl.readyState;\n }\n\n /**\n * Buffered time ranges for the active source. Mirrors the standard\n * `<video>.buffered` `TimeRanges` API. For the native and remux strategies\n * this reflects the underlying SourceBuffer / progressive download state.\n * For the hybrid and fallback (canvas-rendered) strategies it currently\n * returns an empty TimeRanges; a future release will synthesize a coarse\n * range from the decoder's read position.\n */\n get buffered(): TimeRanges {\n return this._videoEl.buffered;\n }\n\n // ── HTMLMediaElement parity ───────────────────────────────────────────\n // Mirror the standard <video> surface so consumers can drop the element\n // in as a <video> replacement. Each property is a thin passthrough to the\n // shadow `<video>`.\n\n get poster(): string {\n return this._videoEl.poster;\n }\n set poster(value: string) {\n if (value == null || value === \"\") this.removeAttribute(\"poster\");\n else this.setAttribute(\"poster\", value);\n }\n\n get volume(): number {\n return this._videoEl.volume;\n }\n set volume(value: number) {\n this._videoEl.volume = value;\n }\n\n get playbackRate(): number {\n return this._videoEl.playbackRate;\n }\n set playbackRate(value: number) {\n this._videoEl.playbackRate = value;\n }\n\n get videoWidth(): number {\n return this._videoEl.videoWidth;\n }\n\n get videoHeight(): number {\n return this._videoEl.videoHeight;\n }\n\n get played(): TimeRanges {\n return this._videoEl.played;\n }\n\n get seekable(): TimeRanges {\n return this._videoEl.seekable;\n }\n\n get crossOrigin(): string | null {\n return this._videoEl.crossOrigin;\n }\n set crossOrigin(value: string | null) {\n if (value == null) this.removeAttribute(\"crossorigin\");\n else this.setAttribute(\"crossorigin\", value);\n }\n\n get disableRemotePlayback(): boolean {\n return this._videoEl.disableRemotePlayback;\n }\n set disableRemotePlayback(value: boolean) {\n if (value) this.setAttribute(\"disableremoteplayback\", \"\");\n else this.removeAttribute(\"disableremoteplayback\");\n }\n\n /**\n * Native `HTMLMediaElement.canPlayType()` passthrough. Note that this\n * answers about the *browser's* native support, not avbridge's full\n * capabilities — avbridge can play many formats this method returns \"\"\n * for, by routing them to the remux/hybrid/fallback strategies.\n */\n canPlayType(mimeType: string): CanPlayTypeResult {\n return this._videoEl.canPlayType(mimeType);\n }\n\n /**\n * **Escape hatch.** The underlying shadow-DOM `<video>` element.\n *\n * Use for native browser APIs the wrapper doesn't expose:\n * - `el.videoElement.requestPictureInPicture()`\n * - `el.videoElement.audioTracks` (browser native, not avbridge's track list)\n * - direct integration with libraries that need a real HTMLVideoElement\n *\n * **Caveat:** When the active strategy is `\"fallback\"` or `\"hybrid\"`,\n * frames are rendered to a canvas overlay, not into this `<video>`.\n * APIs that depend on the actual pixels (Picture-in-Picture, captureStream)\n * will not show the playing content in those modes. Check `el.strategy`\n * before using such APIs.\n */\n get videoElement(): HTMLVideoElement {\n return this._videoEl;\n }\n\n get strategy(): StrategyName | null {\n return this._strategy;\n }\n\n get strategyClass(): StrategyClass | null {\n return this._strategyClass;\n }\n\n get player(): UnifiedPlayer | null {\n return this._player;\n }\n\n get audioTracks(): AudioTrackInfo[] {\n return this._audioTracks;\n }\n\n get subtitleTracks(): SubtitleTrackInfo[] {\n return this._subtitleTracks;\n }\n\n // ── Public methods ─────────────────────────────────────────────────────\n\n /** Force a (re-)bootstrap if a source is currently set. */\n async load(): Promise<void> {\n if (this._destroyed) return;\n const source = this._activeSource();\n if (source == null) return;\n await this._bootstrap(source);\n }\n\n /**\n * Begin or resume playback. If the player isn't ready yet, the call is\n * queued and applied once `ready` fires.\n */\n async play(): Promise<void> {\n if (this._destroyed) return;\n if (this._player) {\n await this._player.play();\n } else {\n this._pendingPlay = true;\n }\n }\n\n pause(): void {\n if (this._destroyed) return;\n this._pendingPlay = false;\n this._player?.pause();\n }\n\n /**\n * Tear down the element permanently. After destroy(), the element ignores\n * all method calls and attribute changes.\n */\n async destroy(): Promise<void> {\n if (this._destroyed) return;\n this._destroyed = true;\n await this._teardown();\n this._dispatch(\"destroy\", {});\n }\n\n async setAudioTrack(id: number): Promise<void> {\n if (this._destroyed || !this._player) return;\n await this._player.setAudioTrack(id);\n }\n\n async setSubtitleTrack(id: number | null): Promise<void> {\n if (this._destroyed || !this._player) return;\n await this._player.setSubtitleTrack(id);\n }\n\n getDiagnostics(): DiagnosticsSnapshot | null {\n return this._player?.getDiagnostics() ?? null;\n }\n\n // ── Event helpers ──────────────────────────────────────────────────────\n\n private _dispatch<T>(name: string, detail: T): void {\n this.dispatchEvent(new CustomEvent(name, { detail, bubbles: false }));\n }\n\n private _dispatchError(err: unknown): void {\n const error = err instanceof Error ? err : new Error(String(err));\n this._dispatch(\"error\", { error, diagnostics: this._player?.getDiagnostics() ?? null });\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"avbridge-video\": AvbridgeVideoElement;\n }\n}\n","/**\n * Shadow DOM CSS for <avbridge-player>.\n * YouTube-inspired dark theme. All controls use ::part() for external styling.\n */\n\nexport const PLAYER_STYLES = /* css */ `\n:host {\n display: block;\n position: relative;\n width: 100%;\n background: #000;\n overflow: hidden;\n user-select: none;\n -webkit-user-select: none;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n color: #fff;\n line-height: 1;\n}\n\n:host(:fullscreen),\n:host(:fullscreen) .avp {\n width: 100vw;\n height: 100vh;\n}\n\n/* ── Container ────────────────────────────────────────────────────────── */\n\n.avp {\n position: relative;\n width: 100%;\n height: 100%;\n cursor: pointer;\n}\n\n.avp avbridge-video {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n/* ── Center overlay ───────────────────────────────────────────────────── */\n\n.avp-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 2;\n}\n\n.avp-overlay-btn {\n width: 68px;\n height: 68px;\n border-radius: 50%;\n background: rgba(0, 0, 0, 0.6);\n border: none;\n color: #fff;\n cursor: pointer;\n pointer-events: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity 0.2s, transform 0.15s;\n opacity: 0;\n transform: scale(0.9);\n}\n\n.avp-overlay-btn svg {\n width: 36px;\n height: 36px;\n}\n\n.avp-overlay-btn:hover {\n background: rgba(0, 0, 0, 0.75);\n transform: scale(1);\n}\n\n:host([data-state=\"idle\"]) .avp-overlay-btn,\n:host([data-state=\"paused\"]) .avp-overlay-btn {\n opacity: 1;\n transform: scale(1);\n}\n\n/* ── Loading spinner ──────────────────────────────────────────────────── */\n\n.avp-spinner {\n width: 48px;\n height: 48px;\n border: 4px solid rgba(255, 255, 255, 0.3);\n border-top-color: #fff;\n border-radius: 50%;\n display: none;\n pointer-events: none;\n}\n\n:host([data-state=\"loading\"]) .avp-spinner,\n:host([data-state=\"buffering\"]) .avp-spinner {\n display: block;\n animation: avp-spin 0.8s linear infinite;\n}\n\n:host([data-state=\"loading\"]) .avp-overlay-btn,\n:host([data-state=\"buffering\"]) .avp-overlay-btn {\n display: none;\n}\n\n@keyframes avp-spin {\n to { transform: rotate(360deg); }\n}\n\n/* ── Double-tap ripple ────────────────────────────────────────────────── */\n\n.avp-ripple {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 100px;\n height: 100px;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.3);\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n opacity: 0;\n z-index: 3;\n}\n\n.avp-ripple svg { width: 28px; height: 28px; }\n.avp-ripple-left { left: 15%; }\n.avp-ripple-right { right: 15%; }\n\n.avp-ripple.active {\n animation: avp-ripple 0.5s ease-out;\n}\n\n@keyframes avp-ripple {\n 0% { opacity: 1; transform: translateY(-50%) scale(0.5); }\n 100% { opacity: 0; transform: translateY(-50%) scale(1.5); }\n}\n\n/* ── Speed indicator (tap-and-hold) ───────────────────────────────────── */\n\n.avp-speed-indicator {\n position: absolute;\n top: 12px;\n left: 50%;\n transform: translateX(-50%);\n background: rgba(0, 0, 0, 0.7);\n padding: 6px 16px;\n border-radius: 20px;\n font-size: 14px;\n font-weight: 600;\n pointer-events: none;\n opacity: 0;\n z-index: 4;\n transition: opacity 0.15s;\n}\n\n.avp-speed-indicator.active { opacity: 1; }\n\n/* ── Controls bar ─────────────────────────────────────────────────────── */\n\n.avp-controls {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 5;\n padding: 0 12px 8px;\n background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));\n display: flex;\n flex-direction: column;\n gap: 4px;\n opacity: 1;\n transition: opacity 0.25s;\n}\n\n:host([data-controls-hidden]) .avp-controls {\n opacity: 0;\n pointer-events: none;\n}\n\n:host([data-controls-hidden]) { cursor: none; }\n\n/* ── Seek bar ─────────────────────────────────────────────────────────── */\n\n.avp-seek {\n position: relative;\n height: 20px;\n display: flex;\n align-items: center;\n cursor: pointer;\n}\n\n.avp-seek-track {\n position: absolute;\n left: 0;\n right: 0;\n height: 3px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 2px;\n overflow: hidden;\n transition: height 0.1s;\n}\n\n.avp-seek:hover .avp-seek-track { height: 5px; }\n\n.avp-seek-buffered {\n position: absolute;\n left: 0;\n height: 100%;\n background: rgba(255, 255, 255, 0.35);\n border-radius: inherit;\n}\n\n.avp-seek-progress {\n position: absolute;\n left: 0;\n height: 100%;\n background: #f00;\n border-radius: inherit;\n}\n\n.avp-seek-input {\n position: absolute;\n width: 100%;\n height: 100%;\n margin: 0;\n opacity: 0;\n /* Disable pointer events — we handle clicks/drags manually on .avp-seek\n * so the click position maps linearly across the full track width.\n * The input is still used for keyboard accessibility. */\n pointer-events: none;\n z-index: 1;\n}\n\n.avp-seek-thumb {\n position: absolute;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: #f00;\n top: 50%;\n /* Thumb center follows the cursor exactly: left = pct% of track width,\n * then translate(-50%) centers the thumb on that point. Matches the\n * manual pointer-to-time mapping in _timeFromSeekPointer which is\n * also linear from 0% to 100% of the track width. */\n left: calc(var(--pct, 0) * 1%);\n transform: translate(-50%, -50%) scale(0);\n transition: transform 0.1s;\n pointer-events: none;\n}\n\n.avp-seek:hover .avp-seek-thumb { transform: translate(-50%, -50%) scale(1); }\n\n.avp-seek-tooltip {\n position: absolute;\n bottom: 24px;\n background: rgba(0, 0, 0, 0.8);\n padding: 4px 8px;\n border-radius: 3px;\n font-size: 12px;\n white-space: nowrap;\n transform: translateX(-50%);\n pointer-events: none;\n display: none;\n}\n\n.avp-seek:hover .avp-seek-tooltip { display: block; }\n\n/* ── Bottom row ───────────────────────────────────────────────────────── */\n\n.avp-bottom {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 36px;\n}\n\n.avp-btn {\n background: none;\n border: none;\n color: #fff;\n padding: 4px;\n cursor: pointer;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0.9;\n transition: opacity 0.1s;\n}\n\n.avp-btn:hover { opacity: 1; }\n.avp-btn svg { width: 24px; height: 24px; }\n\n/* ── Volume ───────────────────────────────────────────────────────────── */\n\n.avp-volume {\n display: flex;\n align-items: center;\n gap: 0;\n}\n\n.avp-volume-slider {\n width: 0;\n overflow: hidden;\n transition: width 0.15s;\n display: flex;\n align-items: center;\n /* Extra padding so the thumb isn't clipped at track edges */\n padding: 6px 0;\n margin: -6px 0;\n}\n\n.avp-volume:hover .avp-volume-slider { width: 68px; }\n\n.avp-volume-input {\n width: 60px;\n height: 4px;\n -webkit-appearance: none;\n appearance: none;\n background: rgba(255, 255, 255, 0.3);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n /* Prevent thumb clipping — the thumb is taller than the track */\n overflow: visible;\n margin: 0;\n}\n\n.avp-volume-input::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: #fff;\n cursor: pointer;\n}\n\n.avp-volume-input::-moz-range-thumb {\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background: #fff;\n border: none;\n cursor: pointer;\n}\n\n/* ── Time display ─────────────────────────────────────────────────────── */\n\n.avp-time {\n font-size: 13px;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n opacity: 0.9;\n}\n\n/* ── Strategy badge ───────────────────────────────────────────────────── */\n\n.avp-badge {\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 3px;\n background: rgba(255, 255, 255, 0.15);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n opacity: 0.8;\n}\n\n.avp-badge[data-strategy=\"native\"] { background: rgba(45, 106, 79, 0.7); }\n.avp-badge[data-strategy=\"remux\"] { background: rgba(30, 96, 145, 0.7); }\n.avp-badge[data-strategy=\"hybrid\"] { background: rgba(199, 125, 255, 0.4); }\n.avp-badge[data-strategy=\"fallback\"] { background: rgba(157, 78, 221, 0.5); }\n\n/* ── Spacer ───────────────────────────────────────────────────────────── */\n\n.avp-spacer { flex: 1; }\n\n/* ── Settings menu ────────────────────────────────────────────────────── */\n\n.avp-settings {\n position: absolute;\n bottom: 52px;\n right: 12px;\n background: rgba(28, 28, 28, 0.95);\n border-radius: 8px;\n min-width: 220px;\n max-height: 300px;\n overflow-y: auto;\n display: none;\n z-index: 10;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);\n}\n\n.avp-settings.open { display: block; }\n\n.avp-settings-section {\n padding: 8px 0;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.avp-settings-section:last-child { border-bottom: none; }\n\n.avp-settings-label {\n padding: 4px 16px;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n opacity: 0.5;\n}\n\n.avp-settings-item {\n display: flex;\n align-items: center;\n padding: 8px 16px;\n font-size: 13px;\n cursor: pointer;\n transition: background 0.1s;\n}\n\n.avp-settings-item:hover { background: rgba(255, 255, 255, 0.1); }\n\n.avp-settings-item.active {\n color: #3ea6ff;\n}\n\n.avp-settings-item.active::before {\n content: \"\\\\2713\";\n margin-right: 8px;\n font-weight: bold;\n}\n\n/* ── Stats for nerds ──────────────────────────────────────────────────── */\n\n.avp-stats {\n position: absolute;\n top: 12px;\n left: 12px;\n background: rgba(0, 0, 0, 0.8);\n padding: 12px 16px;\n border-radius: 6px;\n font-size: 12px;\n font-family: \"SF Mono\", \"Menlo\", \"Consolas\", monospace;\n line-height: 1.6;\n white-space: pre;\n pointer-events: auto;\n z-index: 6;\n max-width: 400px;\n overflow: auto;\n display: none;\n}\n\n.avp-stats.open { display: block; }\n\n/* ── Mobile adjustments ───────────────────────────────────────────────── */\n\n@media (pointer: coarse) {\n .avp-btn svg { width: 28px; height: 28px; }\n .avp-btn { padding: 8px; }\n .avp-seek-track { height: 4px; }\n .avp-seek:hover .avp-seek-track { height: 4px; }\n .avp-seek-thumb { transform: translate(-50%, -50%) scale(1); }\n .avp-volume:hover .avp-volume-slider { width: 0; }\n .avp-overlay-btn { width: 56px; height: 56px; }\n .avp-overlay-btn svg { width: 30px; height: 30px; }\n}\n`;\n","/**\n * Inline SVG icons for <avbridge-player> controls.\n * All icons are 24x24 viewBox, stroke-based where possible for\n * easy theming via CSS `color` (currentColor fill/stroke).\n */\n\nexport const ICON_PLAY = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>`;\n\nexport const ICON_PAUSE = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M6 19h4V5H6zm8-14v14h4V5z\"/></svg>`;\n\nexport const ICON_VOLUME_UP = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\"/></svg>`;\n\nexport const ICON_VOLUME_OFF = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\"/></svg>`;\n\nexport const ICON_SETTINGS = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 00.12-.61l-1.92-3.32a.49.49 0 00-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 00-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96a.49.49 0 00-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58a.49.49 0 00-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z\"/></svg>`;\n\nexport const ICON_FULLSCREEN = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\"/></svg>`;\n\nexport const ICON_FULLSCREEN_EXIT = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\"/></svg>`;\n\nexport const ICON_REPLAY_10 = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M11.99 5V1l-5 5 5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6h-2c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z\"/><text x=\"10\" y=\"16\" font-size=\"8\" text-anchor=\"middle\" fill=\"currentColor\" font-family=\"sans-serif\">10</text></svg>`;\n\nexport const ICON_FORWARD_10 = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M18 13c0 3.31-2.69 6-6 6s-6-2.69-6-6 2.69-6 6-6v4l5-5-5-5v4c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8h-2z\"/><text x=\"14\" y=\"16\" font-size=\"8\" text-anchor=\"middle\" fill=\"currentColor\" font-family=\"sans-serif\">10</text></svg>`;\n\nexport const ICON_SPEED = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 8v8l6-4-6-4zm10.77-1.67L22 7.67l-.77-1.34c-.3-.53-.8-.93-1.41-1.05l-1.7-.3c-.16-.43-.36-.84-.6-1.22l.8-1.54-.77-1.34-.77 1.34.8 1.54c-.24.38-.44.79-.6 1.22l-1.7.3c-.61.12-1.11.52-1.41 1.05L13 7.67l1.23-1.34c-.3.53-.3 1.15 0 1.67L15.46 10l-1.23 2.34c-.3.53-.3 1.15 0 1.67L15.46 16l-1.23 2.34.77 1.34.77-1.34-1.23-2.34c.3-.53.3-1.15 0-1.67L13.31 12l1.23-2.34c.3-.53.3-1.15 0-1.67z\"/></svg>`;\n","/**\n * `<avbridge-player>` — YouTube-style controls element.\n *\n * Wraps `<avbridge-video>` with a full player UI: play/pause, seek bar,\n * volume, settings menu (speed, subtitles, audio tracks), fullscreen,\n * keyboard shortcuts, touch gestures, and auto-hiding controls.\n *\n * All properties, methods, and events from `<avbridge-video>` are proxied\n * through. Consumers interact with `<avbridge-player>` exclusively.\n */\n\n// Import the class concretely and register — side-effect-only imports\n// are tree-shaken by Rollup in production builds.\nimport { AvbridgeVideoElement } from \"./avbridge-video.js\";\nif (typeof customElements !== \"undefined\" && !customElements.get(\"avbridge-video\")) {\n customElements.define(\"avbridge-video\", AvbridgeVideoElement);\n}\nimport { PLAYER_STYLES } from \"./player-styles.js\";\nimport {\n ICON_PLAY, ICON_PAUSE,\n ICON_VOLUME_UP, ICON_VOLUME_OFF,\n ICON_SETTINGS,\n ICON_FULLSCREEN, ICON_FULLSCREEN_EXIT,\n ICON_REPLAY_10, ICON_FORWARD_10,\n} from \"./player-icons.js\";\n\n// ── Helpers ──────────────────────────────────────────────────────────────\n\nfunction formatTime(sec: number): string {\n if (!Number.isFinite(sec) || sec < 0) sec = 0;\n const total = Math.floor(sec);\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = total % 60;\n const mm = String(m).padStart(h > 0 ? 2 : 1, \"0\");\n const ss = String(s).padStart(2, \"0\");\n return h > 0 ? `${h}:${mm}:${ss}` : `${mm}:${ss}`;\n}\n\nconst PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] as const;\nconst CONTROLS_HIDE_MS = 3000;\n\ntype PlayerState = \"idle\" | \"loading\" | \"playing\" | \"paused\" | \"buffering\" | \"ended\" | \"error\";\n\n// ── Forwarded events ─────────────────────────────────────────────────────\n\nconst FORWARDED_EVENTS = [\n \"ready\", \"error\", \"strategychange\", \"trackschange\", \"loadstart\", \"destroy\",\n \"play\", \"playing\", \"pause\", \"seeking\", \"seeked\", \"volumechange\",\n \"ratechange\", \"durationchange\", \"canplay\", \"canplaythrough\",\n \"waiting\", \"stalled\", \"emptied\", \"resize\",\n \"loadedmetadata\", \"loadeddata\", \"timeupdate\", \"ended\", \"progress\",\n] as const;\n\n// ── Observed attributes ──────────────────────────────────────────────────\n\nconst PROXY_ATTRIBUTES = [\n \"src\", \"autoplay\", \"muted\", \"loop\", \"preload\", \"poster\",\n \"playsinline\", \"crossorigin\", \"disableremoteplayback\", \"preferstrategy\",\n] as const;\n\n// ═══════════════════════════════════════════════════════════════════════════\n\nexport class AvbridgePlayerElement extends HTMLElement {\n static readonly observedAttributes = [...PROXY_ATTRIBUTES];\n\n // ── Internal DOM refs ──────────────────────────────────────────────────\n\n private _video!: AvbridgeVideoElement;\n private _playBtn!: HTMLButtonElement;\n private _overlayBtn!: HTMLButtonElement;\n private _seekInput!: HTMLInputElement;\n private _seekProgress!: HTMLDivElement;\n private _seekBuffered!: HTMLDivElement;\n private _seekThumb!: HTMLDivElement;\n private _seekTooltip!: HTMLDivElement;\n private _timeDisplay!: HTMLSpanElement;\n private _volumeBtn!: HTMLButtonElement;\n private _volumeInput!: HTMLInputElement;\n private _settingsBtn!: HTMLButtonElement;\n private _settingsMenu!: HTMLDivElement;\n private _fullscreenBtn!: HTMLButtonElement;\n // Strategy badge removed — visible in Stats for Nerds instead.\n // Spinner is rendered but driven entirely by CSS :host([data-state]) selectors.\n private _speedIndicator!: HTMLDivElement;\n private _rippleLeft!: HTMLDivElement;\n private _rippleRight!: HTMLDivElement;\n\n // ── State ──────────────────────────────────────────────────────────────\n\n private _state: PlayerState = \"idle\";\n private _controlsTimer: ReturnType<typeof setTimeout> | null = null;\n private _settingsOpen = false;\n private _userSeeking = false;\n private _holdTimer: ReturnType<typeof setTimeout> | null = null;\n private _holdSpeedActive = false;\n private _savedPlaybackRate = 1;\n private _lastTapTime = 0;\n private _tapTimer: ReturnType<typeof setTimeout> | null = null;\n private _statsOpen = false;\n private _statsEl!: HTMLDivElement;\n private _statsInterval: ReturnType<typeof setInterval> | null = null;\n private _eventCleanup: (() => void)[] = [];\n\n // ── Constructor ────────────────────────────────────────────────────────\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = `<style>${PLAYER_STYLES}</style>${this._template()}`;\n\n // Grab refs\n this._video = shadow.querySelector(\"avbridge-video\") as AvbridgeVideoElement;\n this._playBtn = shadow.querySelector(\".avp-play\") as HTMLButtonElement;\n this._overlayBtn = shadow.querySelector(\".avp-overlay-btn\") as HTMLButtonElement;\n this._seekInput = shadow.querySelector(\".avp-seek-input\") as HTMLInputElement;\n this._seekProgress = shadow.querySelector(\".avp-seek-progress\") as HTMLDivElement;\n this._seekBuffered = shadow.querySelector(\".avp-seek-buffered\") as HTMLDivElement;\n this._seekThumb = shadow.querySelector(\".avp-seek-thumb\") as HTMLDivElement;\n this._seekTooltip = shadow.querySelector(\".avp-seek-tooltip\") as HTMLDivElement;\n this._timeDisplay = shadow.querySelector(\".avp-time\") as HTMLSpanElement;\n this._volumeBtn = shadow.querySelector(\".avp-volume-btn\") as HTMLButtonElement;\n this._volumeInput = shadow.querySelector(\".avp-volume-input\") as HTMLInputElement;\n this._settingsBtn = shadow.querySelector(\".avp-settings-btn\") as HTMLButtonElement;\n this._settingsMenu = shadow.querySelector(\".avp-settings\") as HTMLDivElement;\n this._fullscreenBtn = shadow.querySelector(\".avp-fullscreen\") as HTMLButtonElement;\n // Badge removed from controls bar — strategy visible in Stats for Nerds.\n // Spinner is rendered in shadow DOM, driven by CSS :host([data-state]).\n this._speedIndicator = shadow.querySelector(\".avp-speed-indicator\") as HTMLDivElement;\n this._statsEl = shadow.querySelector(\".avp-stats\") as HTMLDivElement;\n this._rippleLeft = shadow.querySelector(\".avp-ripple-left\") as HTMLDivElement;\n this._rippleRight = shadow.querySelector(\".avp-ripple-right\") as HTMLDivElement;\n\n this._bindEvents();\n }\n\n private _template(): string {\n return `\n<div part=\"container\" class=\"avp\">\n <avbridge-video part=\"video\"></avbridge-video>\n <div part=\"overlay\" class=\"avp-overlay\">\n <button class=\"avp-overlay-btn\" aria-label=\"Play\">${ICON_PLAY}</button>\n <div class=\"avp-spinner\"></div>\n </div>\n <div class=\"avp-speed-indicator\">2x</div>\n <div class=\"avp-stats\" part=\"stats-panel\"></div>\n <div class=\"avp-ripple avp-ripple-left\">${ICON_REPLAY_10}</div>\n <div class=\"avp-ripple avp-ripple-right\">${ICON_FORWARD_10}</div>\n <div part=\"controls\" class=\"avp-controls\">\n <div class=\"avp-seek\" part=\"seek-bar\">\n <div class=\"avp-seek-track\">\n <div class=\"avp-seek-buffered\"></div>\n <div class=\"avp-seek-progress\"></div>\n </div>\n <div class=\"avp-seek-thumb\"></div>\n <div class=\"avp-seek-tooltip\">0:00</div>\n <input class=\"avp-seek-input\" type=\"range\" min=\"0\" max=\"0\" step=\"any\" value=\"0\" aria-label=\"Seek\">\n </div>\n <div class=\"avp-bottom\">\n <button class=\"avp-btn avp-play\" part=\"play-button\" aria-label=\"Play\">${ICON_PLAY}</button>\n <div class=\"avp-volume\">\n <button class=\"avp-btn avp-volume-btn\" part=\"volume-button\" aria-label=\"Mute\">${ICON_VOLUME_UP}</button>\n <div class=\"avp-volume-slider\">\n <input class=\"avp-volume-input\" part=\"volume-slider\" type=\"range\" min=\"0\" max=\"1\" step=\"0.05\" value=\"1\" aria-label=\"Volume\">\n </div>\n </div>\n <span class=\"avp-time\" part=\"time-display\">0:00 / 0:00</span>\n <span class=\"avp-spacer\"></span>\n <button class=\"avp-btn avp-settings-btn\" part=\"settings-button\" aria-label=\"Settings\">${ICON_SETTINGS}</button>\n <button class=\"avp-btn avp-fullscreen\" part=\"fullscreen-button\" aria-label=\"Fullscreen\">${ICON_FULLSCREEN}</button>\n </div>\n <div class=\"avp-settings\" part=\"settings-menu\"></div>\n </div>\n</div>`;\n }\n\n // ── Event wiring ───────────────────────────────────────────────────────\n\n private _bindEvents(): void {\n const on = <K extends keyof HTMLElementEventMap>(\n el: EventTarget, event: K | string, fn: (e: Event) => void, opts?: AddEventListenerOptions,\n ) => {\n el.addEventListener(event, fn, opts);\n this._eventCleanup.push(() => el.removeEventListener(event, fn, opts));\n };\n\n // Forward events from inner video\n for (const name of FORWARDED_EVENTS) {\n on(this._video, name, (e) => {\n const detail = (e as CustomEvent).detail;\n this.dispatchEvent(\n detail !== undefined\n ? new CustomEvent(name, { detail, bubbles: e.bubbles, composed: true })\n : new Event(name, { bubbles: e.bubbles }),\n );\n });\n }\n\n // State tracking\n on(this._video, \"loadstart\", () => this._setState(\"loading\"));\n on(this._video, \"ready\", () => {\n this._setState(this._video.paused ? \"paused\" : \"playing\");\n this._seekInput.max = String(this._video.duration || 0);\n this._updateTime();\n this._buildSettingsMenu();\n });\n on(this._video, \"play\", () => this._setState(\"playing\"));\n on(this._video, \"playing\", () => this._setState(\"playing\"));\n on(this._video, \"pause\", () => this._setState(\"paused\"));\n on(this._video, \"waiting\", () => this._setState(\"buffering\"));\n on(this._video, \"ended\", () => this._setState(\"ended\"));\n on(this._video, \"error\", () => this._setState(\"error\"));\n on(this._video, \"timeupdate\", () => this._updateTime());\n on(this._video, \"volumechange\", () => this._updateVolume());\n // Strategy changes are visible in Stats for Nerds.\n on(this._video, \"trackschange\", () => this._buildSettingsMenu());\n on(this._video, \"durationchange\", () => {\n this._seekInput.max = String(this._video.duration || 0);\n });\n\n // Play / pause\n on(this._playBtn, \"click\", (e) => { e.stopPropagation(); this._togglePlay(); });\n on(this._overlayBtn, \"click\", (e) => { e.stopPropagation(); this._togglePlay(); });\n\n // Seek bar — manual pointer handling so the click position maps\n // linearly across the FULL track width (native <input type=\"range\">\n // clamps the thumb center inside [thumbWidth/2, trackWidth -\n // thumbWidth/2], which causes a visible click-to-thumb offset at\n // the edges). The input is still used for keyboard accessibility\n // (arrow keys, home/end) via its 'input' event.\n on(this._seekInput, \"input\", () => {\n // Only accept keyboard-driven input events (not synthesized\n // from pointer, which we handle manually below).\n if (this._userSeeking) return;\n this._onSeekInput();\n });\n on(this._seekInput, \"change\", () => {\n if (this._userSeeking) return;\n this._onSeekCommit();\n });\n const seekBar = this.shadowRoot!.querySelector(\".avp-seek\") as HTMLElement;\n on(seekBar, \"pointerdown\", (e) => this._onSeekPointerDown(e as PointerEvent));\n on(seekBar, \"pointermove\", (e) => this._onSeekHover(e as PointerEvent));\n\n // Volume\n on(this._volumeBtn, \"click\", (e) => { e.stopPropagation(); this._toggleMute(); });\n on(this._volumeInput, \"input\", () => {\n const vol = Number(this._volumeInput.value);\n this._video.volume = vol;\n this._video.videoElement.volume = vol;\n this._video.muted = false;\n this._video.videoElement.muted = false;\n this._updateVolume();\n });\n\n // Settings\n on(this._settingsBtn, \"click\", (e) => { e.stopPropagation(); this._toggleSettings(); });\n\n // Fullscreen\n on(this._fullscreenBtn, \"click\", (e) => { e.stopPropagation(); this._toggleFullscreen(); });\n on(document, \"fullscreenchange\", () => this._updateFullscreenIcon());\n\n // Click / tap on video area — uses a delayed-tap pattern (like YouTube)\n // to distinguish single-tap (play/pause) from double-tap (seek ±10s).\n // On mouse: single click → play/pause, dblclick → fullscreen.\n // On touch: single tap (after 250ms) → play/pause, double tap → seek.\n const container = this.shadowRoot!.querySelector(\".avp\")!;\n on(container, \"click\", (e) => this._onContainerClick(e as MouseEvent));\n on(container, \"dblclick\", (e) => this._onContainerDblClick(e as MouseEvent));\n\n // Dismiss settings menu on click outside (inside or outside the player)\n on(container, \"click\", (e) => {\n if (this._settingsOpen &&\n !(e.target as HTMLElement).closest?.(\".avp-settings-btn, .avp-settings\")) {\n this._closeSettings();\n }\n });\n // Also dismiss if user clicks outside the player element entirely\n on(document, \"click\", (e) => {\n if (this._settingsOpen && !this.contains(e.target as Node)) {\n this._closeSettings();\n }\n });\n\n // Auto-hide controls\n on(container, \"pointermove\", () => this._showControls());\n on(container, \"pointerleave\", () => this._scheduleHide());\n\n // Touch gestures: hold for 2x speed\n on(container, \"pointerdown\", (e) => this._onPointerDown(e as PointerEvent));\n on(container, \"pointerup\", (e) => this._onPointerUp(e as PointerEvent));\n on(container, \"pointercancel\", () => this._cancelHold());\n\n // Keyboard\n on(this, \"keydown\", (e) => this._onKeydown(e as KeyboardEvent));\n\n // Make focusable for keyboard events\n if (!this.hasAttribute(\"tabindex\")) {\n this.setAttribute(\"tabindex\", \"0\");\n }\n }\n\n // ── Lifecycle ──────────────────────────────────────────────────────────\n\n connectedCallback(): void {\n this._setState(\"idle\");\n }\n\n disconnectedCallback(): void {\n this._clearTimers();\n }\n\n attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n // Proxy attributes down to inner avbridge-video\n if (!this._video) return;\n if (value == null) this._video.removeAttribute(name);\n else this._video.setAttribute(name, value);\n }\n\n // ── State management ───────────────────────────────────────────────────\n\n private _setState(state: PlayerState): void {\n this._state = state;\n this.dataset.state = state;\n\n // Update play/pause icons\n const playing = state === \"playing\" || state === \"buffering\";\n this._playBtn.innerHTML = playing ? ICON_PAUSE : ICON_PLAY;\n this._playBtn.ariaLabel = playing ? \"Pause\" : \"Play\";\n this._overlayBtn.innerHTML = ICON_PLAY;\n\n // Auto-hide logic\n if (playing) this._scheduleHide();\n else this._showControls();\n }\n\n // ── Controls: play/pause ───────────────────────────────────────────────\n\n private _togglePlay(): void {\n if (this._state === \"idle\" || this._state === \"error\") return;\n if (this._video.paused) void this._video.play();\n else this._video.pause();\n }\n\n // ── Controls: seek ─────────────────────────────────────────────────────\n\n private _onSeekInput(): void {\n const t = Number(this._seekInput.value);\n this._updateSeekVisuals(t);\n this._timeDisplay.textContent = `${formatTime(t)} / ${formatTime(this._video.duration)}`;\n }\n\n private _onSeekCommit(): void {\n this._video.currentTime = Number(this._seekInput.value);\n this._userSeeking = false;\n }\n\n /** Linear click-to-time mapping across the full track width (no edge clamping). */\n private _timeFromSeekPointer(clientX: number): number {\n const seekBar = this.shadowRoot!.querySelector(\".avp-seek\") as HTMLElement;\n const rect = seekBar.getBoundingClientRect();\n const frac = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n return frac * (this._video.duration || 0);\n }\n\n private _onSeekPointerDown(e: PointerEvent): void {\n // Ignore synthetic clicks originating from the input's own handling\n if (e.button !== 0 && e.pointerType === \"mouse\") return;\n e.preventDefault();\n this._userSeeking = true;\n const seekBar = this.shadowRoot!.querySelector(\".avp-seek\") as HTMLElement;\n seekBar.setPointerCapture(e.pointerId);\n\n const initial = this._timeFromSeekPointer(e.clientX);\n this._seekInput.value = String(initial);\n this._onSeekInput();\n\n const onMove = (ev: PointerEvent) => {\n const t = this._timeFromSeekPointer(ev.clientX);\n this._seekInput.value = String(t);\n this._onSeekInput();\n };\n const onUp = (ev: PointerEvent) => {\n const t = this._timeFromSeekPointer(ev.clientX);\n this._seekInput.value = String(t);\n this._onSeekCommit();\n this._seekInput.focus(); // keep keyboard nav responsive\n seekBar.removeEventListener(\"pointermove\", onMove);\n seekBar.removeEventListener(\"pointerup\", onUp);\n seekBar.removeEventListener(\"pointercancel\", onUp);\n try { seekBar.releasePointerCapture(e.pointerId); } catch { /* ignore */ }\n };\n seekBar.addEventListener(\"pointermove\", onMove);\n seekBar.addEventListener(\"pointerup\", onUp);\n seekBar.addEventListener(\"pointercancel\", onUp);\n }\n\n private _onSeekHover(e: PointerEvent): void {\n const rect = this._seekInput.getBoundingClientRect();\n const frac = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));\n const t = frac * (this._video.duration || 0);\n this._seekTooltip.textContent = formatTime(t);\n this._seekTooltip.style.left = `${frac * 100}%`;\n }\n\n private _updateSeekVisuals(t: number): void {\n const dur = this._video.duration || 0;\n const pct = dur > 0 ? (t / dur) * 100 : 0;\n this._seekProgress.style.width = `${pct}%`;\n // Thumb position uses a CSS calc that matches the native range input's\n // click-to-value math (thumb stays within track bounds). See player-styles.ts.\n this._seekThumb.style.setProperty(\"--pct\", String(pct));\n }\n\n // ── Controls: time ─────────────────────────────────────────────────────\n\n private _updateTime(): void {\n if (this._userSeeking) return;\n const t = this._video.currentTime;\n const d = this._video.duration;\n this._seekInput.value = String(t);\n this._updateSeekVisuals(t);\n this._timeDisplay.textContent = `${formatTime(t)} / ${formatTime(d)}`;\n\n // Buffered ranges\n try {\n const buf = this._video.buffered;\n if (buf && buf.length > 0 && d > 0) {\n const end = buf.end(buf.length - 1);\n this._seekBuffered.style.width = `${(end / d) * 100}%`;\n }\n } catch { /* ignore */ }\n }\n\n // ── Controls: volume ───────────────────────────────────────────────────\n\n private _toggleMute(): void {\n // Set both the element attribute AND the inner <video> property directly,\n // because avbridge-video's attribute-based muted toggling can diverge\n // from the <video> property on a running element.\n const newMuted = !this._video.muted;\n this._video.muted = newMuted;\n this._video.videoElement.muted = newMuted;\n this._updateVolume();\n }\n\n private _updateVolume(): void {\n const muted = this._video.muted || this._video.videoElement.muted || this._video.volume === 0;\n this._volumeBtn.innerHTML = muted ? ICON_VOLUME_OFF : ICON_VOLUME_UP;\n this._volumeInput.value = muted ? \"0\" : String(this._video.volume);\n }\n\n // ── Controls: settings ─────────────────────────────────────────────────\n\n private _toggleSettings(): void {\n this._settingsOpen = !this._settingsOpen;\n this._settingsMenu.classList.toggle(\"open\", this._settingsOpen);\n if (this._settingsOpen) this._showControls();\n }\n\n private _closeSettings(): void {\n this._settingsOpen = false;\n this._settingsMenu.classList.remove(\"open\");\n }\n\n private _buildSettingsMenu(): void {\n const sections: string[] = [];\n\n // Playback speed\n const currentRate = this._video.playbackRate ?? 1;\n let speedItems = \"\";\n for (const spd of PLAYBACK_SPEEDS) {\n const active = Math.abs(spd - currentRate) < 0.01;\n const label = spd === 1 ? \"Normal\" : `${spd}x`;\n speedItems += `<div class=\"avp-settings-item${active ? \" active\" : \"\"}\" data-speed=\"${spd}\">${label}</div>`;\n }\n sections.push(`<div class=\"avp-settings-section\"><div class=\"avp-settings-label\">Speed</div>${speedItems}</div>`);\n\n // Subtitle tracks\n const subs = this._video.subtitleTracks ?? [];\n if (subs.length > 0) {\n let subItems = `<div class=\"avp-settings-item\" data-subtitle=\"-1\">Off</div>`;\n for (const t of subs) {\n subItems += `<div class=\"avp-settings-item\" data-subtitle=\"${t.id}\">${t.language ?? `Track ${t.id}`}</div>`;\n }\n sections.push(`<div class=\"avp-settings-section\"><div class=\"avp-settings-label\">Subtitles</div>${subItems}</div>`);\n }\n\n // Audio tracks\n const audios = this._video.audioTracks ?? [];\n if (audios.length > 1) {\n let audioItems = \"\";\n for (const t of audios) {\n audioItems += `<div class=\"avp-settings-item\" data-audio=\"${t.id}\">${t.language ?? `Track ${t.id}`}</div>`;\n }\n sections.push(`<div class=\"avp-settings-section\"><div class=\"avp-settings-label\">Audio</div>${audioItems}</div>`);\n }\n\n // Stats for nerds\n sections.push(`<div class=\"avp-settings-section\"><div class=\"avp-settings-item\" data-stats>Stats for nerds</div></div>`);\n\n this._settingsMenu.innerHTML = sections.join(\"\");\n\n // Bind click handlers\n for (const item of this._settingsMenu.querySelectorAll(\"[data-speed]\")) {\n item.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this._video.playbackRate = Number((item as HTMLElement).dataset.speed);\n this._buildSettingsMenu();\n });\n }\n for (const item of this._settingsMenu.querySelectorAll(\"[data-subtitle]\")) {\n item.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n const id = Number((item as HTMLElement).dataset.subtitle);\n void this._video.setSubtitleTrack(id >= 0 ? id : null);\n this._closeSettings();\n });\n }\n for (const item of this._settingsMenu.querySelectorAll(\"[data-audio]\")) {\n item.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n void this._video.setAudioTrack(Number((item as HTMLElement).dataset.audio));\n this._closeSettings();\n });\n }\n const statsItem = this._settingsMenu.querySelector(\"[data-stats]\");\n if (statsItem) {\n statsItem.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this._toggleStats();\n this._closeSettings();\n });\n }\n }\n\n // ── Stats for nerds ────────────────────────────────────────────────────\n\n private _toggleStats(): void {\n this._statsOpen = !this._statsOpen;\n this._statsEl.classList.toggle(\"open\", this._statsOpen);\n if (this._statsOpen) {\n this._updateStats();\n this._statsInterval = setInterval(() => this._updateStats(), 1000);\n } else {\n if (this._statsInterval) { clearInterval(this._statsInterval); this._statsInterval = null; }\n }\n }\n\n private _updateStats(): void {\n const d = this._video.getDiagnostics() as Record<string, unknown> | null;\n if (!d) { this._statsEl.textContent = \"No diagnostics\"; return; }\n const rt = (d.runtime ?? {}) as Record<string, unknown>;\n const lines: string[] = [\n `Container: ${d.container ?? \"?\"}`,\n `Video: ${d.videoCodec ?? \"?\"} ${d.width ?? \"?\"}×${d.height ?? \"?\"}`,\n `Audio: ${d.audioCodec ?? \"none\"}`,\n `Strategy: ${d.strategy ?? \"?\"} Class: ${d.strategyClass ?? \"?\"}`,\n `Transport: ${d.transport ?? \"?\"} Range: ${d.rangeSupported ?? \"?\"}`,\n `Duration: ${typeof d.duration === \"number\" ? d.duration.toFixed(1) + \"s\" : \"?\"}`,\n ];\n if (rt.framesDecoded != null) lines.push(`Frames: ${rt.framesDecoded} decoded, ${rt.framesDropped ?? 0} dropped`);\n if (rt.framesPainted != null) lines.push(`Painted: ${rt.framesPainted} Late: ${rt.framesDroppedLate ?? 0} Overflow: ${rt.framesDroppedOverflow ?? 0}`);\n if (rt.videoFramesDecoded != null) lines.push(`Video decoded: ${rt.videoFramesDecoded} Chunks fed: ${rt.videoChunksFed ?? \"?\"}`);\n if (rt.audioFramesDecoded != null) lines.push(`Audio decoded: ${rt.audioFramesDecoded}`);\n if (rt.packetsRead != null) lines.push(`Packets read: ${rt.packetsRead}`);\n if (rt.bsfApplied && (rt.bsfApplied as string[]).length > 0) lines.push(`BSF: ${(rt.bsfApplied as string[]).join(\", \")}`);\n if (rt.audioState != null) lines.push(`Audio state: ${rt.audioState} Clock: ${rt.clockMode ?? \"?\"}`);\n if (d.probedBy) lines.push(`Probed by: ${d.probedBy}`);\n this._statsEl.textContent = lines.join(\"\\n\");\n }\n\n // ── Controls: fullscreen ───────────────────────────────────────────────\n\n private _toggleFullscreen(): void {\n if (document.fullscreenElement === this) {\n void document.exitFullscreen();\n } else {\n void this.requestFullscreen();\n }\n }\n\n private _updateFullscreenIcon(): void {\n const fs = document.fullscreenElement === this;\n this._fullscreenBtn.innerHTML = fs ? ICON_FULLSCREEN_EXIT : ICON_FULLSCREEN;\n }\n\n // ── Controls: auto-hide ────────────────────────────────────────────────\n\n private _showControls(): void {\n this.removeAttribute(\"data-controls-hidden\");\n this._scheduleHide();\n }\n\n private _scheduleHide(): void {\n if (this._controlsTimer) clearTimeout(this._controlsTimer);\n if (this._state !== \"playing\" && this._state !== \"buffering\") return;\n if (this._settingsOpen) return;\n this._controlsTimer = setTimeout(() => {\n if (this._state === \"playing\") {\n this.setAttribute(\"data-controls-hidden\", \"\");\n }\n }, CONTROLS_HIDE_MS);\n }\n\n // Strategy is visible in Stats for Nerds, no badge in controls bar.\n\n // ── Click / tap handling (YouTube delayed-tap pattern) ──────────────────\n //\n // Problem: single click toggles play, double click toggles fullscreen (or\n // seek on touch). Firing play on the first click causes a play→pause\n // glitch on every double-click. YouTube solves this by delaying the\n // single-click action by ~250ms; if a second click arrives in that window\n // it's treated as a double-click and the single-click action is cancelled.\n\n /** Track whether the last interaction was touch so click handler can skip. */\n private _lastPointerTypeWasTouch = false;\n\n private _onContainerClick(e: MouseEvent): void {\n // Ignore clicks on controls\n if ((e.target as HTMLElement).closest?.(\".avp-controls, .avp-settings, .avp-overlay-btn\")) return;\n\n // Touch taps are handled by _onPointerUp (show/hide controls + double-tap).\n // The browser fires a synthetic click after touchend — skip it.\n if (this._lastPointerTypeWasTouch) {\n this._lastPointerTypeWasTouch = false;\n return;\n }\n\n // Mouse: delay single-click to let dblclick cancel it\n if (this._tapTimer) { clearTimeout(this._tapTimer); this._tapTimer = null; }\n this._tapTimer = setTimeout(() => {\n this._tapTimer = null;\n this._togglePlay();\n }, 250);\n }\n\n private _onContainerDblClick(e: MouseEvent): void {\n if ((e.target as HTMLElement).closest?.(\".avp-controls, .avp-settings\")) return;\n // Cancel the pending single-click play/pause\n if (this._tapTimer) { clearTimeout(this._tapTimer); this._tapTimer = null; }\n this._toggleFullscreen();\n }\n\n // ── Touch gestures ─────────────────────────────────────────────────────\n\n private _onPointerDown(e: PointerEvent): void {\n if (e.pointerType !== \"touch\") return;\n // Tap-and-hold for 2x speed\n this._holdTimer = setTimeout(() => {\n this._holdSpeedActive = true;\n this._savedPlaybackRate = this._video.playbackRate;\n this._video.playbackRate = 2;\n this._speedIndicator.classList.add(\"active\");\n }, 500);\n }\n\n private _onPointerUp(e: PointerEvent): void {\n this._cancelHold();\n if (e.pointerType !== \"touch\") return;\n this._lastPointerTypeWasTouch = true;\n\n // Ignore touches on controls — buttons have their own handlers\n if ((e.target as HTMLElement).closest?.(\".avp-controls, .avp-settings, .avp-overlay-btn\")) return;\n\n // Double-tap detection\n const now = Date.now();\n if (now - this._lastTapTime < 300) {\n // Double tap — cancel pending single tap and seek\n if (this._tapTimer) { clearTimeout(this._tapTimer); this._tapTimer = null; }\n const rect = this.getBoundingClientRect();\n const x = e.clientX - rect.left;\n if (x < rect.width / 3) {\n this._doDoubleTap(\"left\");\n } else if (x > (rect.width * 2) / 3) {\n this._doDoubleTap(\"right\");\n } else {\n this._toggleFullscreen();\n }\n this._lastTapTime = 0;\n return;\n }\n // Single tap on touch — toggle controls visibility (NOT play/pause).\n // YouTube mobile: tap shows/hides controls. Play button toggles playback.\n this._lastTapTime = now;\n this._tapTimer = setTimeout(() => {\n this._tapTimer = null;\n if (this.hasAttribute(\"data-controls-hidden\")) {\n this._showControls();\n } else {\n this.setAttribute(\"data-controls-hidden\", \"\");\n }\n }, 250);\n }\n\n private _cancelHold(): void {\n if (this._holdTimer) {\n clearTimeout(this._holdTimer);\n this._holdTimer = null;\n }\n if (this._holdSpeedActive) {\n this._holdSpeedActive = false;\n this._video.playbackRate = this._savedPlaybackRate;\n this._speedIndicator.classList.remove(\"active\");\n }\n }\n\n private _doDoubleTap(side: \"left\" | \"right\"): void {\n const ripple = side === \"left\" ? this._rippleLeft : this._rippleRight;\n ripple.classList.remove(\"active\");\n // Force reflow to restart animation\n void ripple.offsetWidth;\n ripple.classList.add(\"active\");\n\n const delta = side === \"left\" ? -10 : 10;\n this._video.currentTime = Math.max(0, this._video.currentTime + delta);\n }\n\n // ── Keyboard shortcuts ─────────────────────────────────────────────────\n\n private _onKeydown(e: KeyboardEvent): void {\n // Don't intercept if the user is typing in an input\n if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;\n\n switch (e.key) {\n case \" \":\n case \"k\":\n e.preventDefault();\n this._togglePlay();\n break;\n case \"f\":\n e.preventDefault();\n this._toggleFullscreen();\n break;\n case \"m\":\n e.preventDefault();\n this._toggleMute();\n break;\n case \"ArrowLeft\":\n case \"j\":\n e.preventDefault();\n this._video.currentTime = Math.max(0, this._video.currentTime - 5);\n break;\n case \"ArrowRight\":\n case \"l\":\n e.preventDefault();\n this._video.currentTime = Math.min(this._video.duration || 0, this._video.currentTime + 5);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n this._video.volume = Math.min(1, this._video.volume + 0.1);\n break;\n case \"ArrowDown\":\n e.preventDefault();\n this._video.volume = Math.max(0, this._video.volume - 0.1);\n break;\n case \">\":\n e.preventDefault();\n this._video.playbackRate = Math.min(2, this._video.playbackRate + 0.25);\n this._buildSettingsMenu();\n break;\n case \"<\":\n e.preventDefault();\n this._video.playbackRate = Math.max(0.25, this._video.playbackRate - 0.25);\n this._buildSettingsMenu();\n break;\n case \"Escape\":\n if (this._settingsOpen) {\n e.preventDefault();\n this._closeSettings();\n }\n break;\n }\n this._showControls();\n }\n\n // ── Cleanup ────────────────────────────────────────────────────────────\n\n private _clearTimers(): void {\n if (this._controlsTimer) { clearTimeout(this._controlsTimer); this._controlsTimer = null; }\n if (this._holdTimer) { clearTimeout(this._holdTimer); this._holdTimer = null; }\n if (this._tapTimer) { clearTimeout(this._tapTimer); this._tapTimer = null; }\n if (this._statsInterval) { clearInterval(this._statsInterval); this._statsInterval = null; }\n }\n\n // ── Property proxies ───────────────────────────────────────────────────\n\n get src(): string { return this._video.src ?? \"\"; }\n set src(v: string) { this._video.src = v; }\n\n get source(): unknown { return this._video.source; }\n set source(v: unknown) { (this._video as unknown as { source: unknown }).source = v; }\n\n get currentTime(): number { return this._video.currentTime; }\n set currentTime(v: number) { this._video.currentTime = v; }\n\n get duration(): number { return this._video.duration; }\n get paused(): boolean { return this._video.paused; }\n get ended(): boolean { return this._video.ended; }\n get readyState(): number { return this._video.readyState; }\n\n get volume(): number { return this._video.volume; }\n set volume(v: number) { this._video.volume = v; this._updateVolume(); }\n\n get muted(): boolean { return this._video.muted; }\n set muted(v: boolean) { this._video.muted = v; this._updateVolume(); }\n\n get playbackRate(): number { return this._video.playbackRate; }\n set playbackRate(v: number) { this._video.playbackRate = v; }\n\n get autoplay(): boolean { return this._video.autoplay; }\n set autoplay(v: boolean) { this._video.autoplay = v; }\n\n get loop(): boolean { return this._video.loop; }\n set loop(v: boolean) { this._video.loop = v; }\n\n get videoWidth(): number { return this._video.videoWidth; }\n get videoHeight(): number { return this._video.videoHeight; }\n get buffered(): TimeRanges { return this._video.buffered; }\n get played(): TimeRanges { return this._video.played; }\n get seekable(): TimeRanges { return this._video.seekable; }\n\n get strategy(): string | undefined { return this._video.strategy ?? undefined; }\n get strategyClass(): string | undefined { return this._video.strategyClass ?? undefined; }\n get audioTracks(): unknown[] { return this._video.audioTracks ?? []; }\n get subtitleTracks(): unknown[] { return this._video.subtitleTracks ?? []; }\n get player(): unknown { return this._video.player; }\n get videoElement(): HTMLVideoElement { return this._video.videoElement; }\n\n // ── Method proxies ─────────────────────────────────────────────────────\n\n async play(): Promise<void> { return this._video.play(); }\n pause(): void { this._video.pause(); }\n async load(): Promise<void> { return this._video.load(); }\n async destroy(): Promise<void> {\n this._clearTimers();\n for (const fn of this._eventCleanup) fn();\n this._eventCleanup = [];\n return this._video.destroy();\n }\n async setAudioTrack(id: number): Promise<void> { return this._video.setAudioTrack(id); }\n async setSubtitleTrack(id: number | null): Promise<void> { return this._video.setSubtitleTrack(id); }\n getDiagnostics(): unknown { return this._video.getDiagnostics(); }\n canPlayType(mime: string): string { return this._video.canPlayType(mime); }\n}\n","/**\n * Registration entry point for `<avbridge-player>`.\n *\n * Import `\"avbridge/player\"` to register the element. This also registers\n * `<avbridge-video>` (which `<avbridge-player>` wraps internally).\n *\n * Separate from `\"avbridge/element\"` so consumers who only need the bare\n * `<avbridge-video>` primitive don't pay for the controls CSS/JS.\n */\n\nimport { AvbridgePlayerElement } from \"./element/avbridge-player.js\";\n\nexport { AvbridgePlayerElement } from \"./element/avbridge-player.js\";\nexport type { AvbridgeVideoElement } from \"./element/avbridge-video.js\";\n\nif (!customElements.get(\"avbridge-player\")) {\n customElements.define(\"avbridge-player\", AvbridgePlayerElement);\n}\n"]}
|