avbridge 2.1.2 → 2.2.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 +93 -0
- package/dist/{avi-GNTV5ZOH.cjs → avi-6SJLWIWW.cjs} +19 -4
- package/dist/avi-6SJLWIWW.cjs.map +1 -0
- package/dist/{avi-V6HYQVR2.js → avi-GCGM7OJI.js} +18 -3
- package/dist/avi-GCGM7OJI.js.map +1 -0
- package/dist/{chunk-EJH67FXG.js → chunk-5DMTJVIU.js} +99 -3
- package/dist/chunk-5DMTJVIU.js.map +1 -0
- package/dist/{chunk-3AUGRKPY.js → chunk-C5VA5U5O.js} +94 -16
- package/dist/chunk-C5VA5U5O.js.map +1 -0
- package/dist/{chunk-JQH6D4OE.cjs → chunk-G4APZMCP.cjs} +100 -3
- package/dist/chunk-G4APZMCP.cjs.map +1 -0
- package/dist/{chunk-Y5FYF5KG.cjs → chunk-HZLQNKFN.cjs} +5 -2
- package/dist/chunk-HZLQNKFN.cjs.map +1 -0
- package/dist/{chunk-PQTZS7OA.js → chunk-ILKDNBSE.js} +5 -2
- package/dist/chunk-ILKDNBSE.js.map +1 -0
- package/dist/{chunk-DPVIOYGC.cjs → chunk-OE66B34H.cjs} +98 -20
- package/dist/chunk-OE66B34H.cjs.map +1 -0
- package/dist/element-browser.js +210 -10
- 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 +18 -18
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/dist/libav-loader-27RDIN2I.js +3 -0
- package/dist/{libav-loader-XKH2TKUW.js.map → libav-loader-27RDIN2I.js.map} +1 -1
- package/dist/libav-loader-IV4AJ2HW.cjs +12 -0
- package/dist/{libav-loader-6APXVNIV.cjs.map → libav-loader-IV4AJ2HW.cjs.map} +1 -1
- package/dist/{player-BdtUG4rh.d.cts → player-DUyvltvy.d.cts} +3 -3
- package/dist/{player-BdtUG4rh.d.ts → player-DUyvltvy.d.ts} +3 -3
- package/dist/source-CN43EI7Z.cjs +28 -0
- package/dist/{source-SC6ZEQYR.cjs.map → source-CN43EI7Z.cjs.map} +1 -1
- package/dist/source-FFZ7TW2B.js +3 -0
- package/dist/{source-ZFS4H7J3.js.map → source-FFZ7TW2B.js.map} +1 -1
- package/package.json +1 -1
- package/src/classify/rules.ts +9 -2
- package/src/player.ts +22 -1
- package/src/probe/avi.ts +8 -1
- package/src/strategies/fallback/audio-output.ts +25 -3
- package/src/strategies/fallback/decoder.ts +96 -8
- package/src/strategies/fallback/index.ts +90 -6
- package/src/strategies/fallback/libav-loader.ts +12 -0
- package/src/types.ts +10 -1
- package/src/util/debug.ts +131 -0
- package/src/util/source.ts +4 -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-GNTV5ZOH.cjs.map +0 -1
- package/dist/avi-V6HYQVR2.js.map +0 -1
- package/dist/chunk-3AUGRKPY.js.map +0 -1
- package/dist/chunk-DPVIOYGC.cjs.map +0 -1
- package/dist/chunk-EJH67FXG.js.map +0 -1
- package/dist/chunk-JQH6D4OE.cjs.map +0 -1
- package/dist/chunk-PQTZS7OA.js.map +0 -1
- package/dist/chunk-Y5FYF5KG.cjs.map +0 -1
- package/dist/libav-loader-6APXVNIV.cjs +0 -12
- package/dist/libav-loader-XKH2TKUW.js +0 -3
- package/dist/source-SC6ZEQYR.cjs +0 -28
- package/dist/source-ZFS4H7J3.js +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/probe/mediabunny.ts","../src/probe/index.ts","../src/util/codec-strings.ts","../src/classify/rules.ts","../src/subtitles/srt.ts","../src/events.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/hybrid/decoder.ts","../src/strategies/hybrid/index.ts","../src/strategies/fallback/decoder.ts","../src/strategies/fallback/index.ts","../src/plugins/builtin.ts","../src/subtitles/vtt.ts","../src/subtitles/index.ts","../src/player.ts"],"names":["drain","samples","us","normalizeSource","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"],"mappings":"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","file":"chunk-C5VA5U5O.js","sourcesContent":["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 } from \"../types.js\";\nimport { normalizeSource, sniffNormalizedSource } from \"../util/source.js\";\nimport { probeWithMediabunny } from \"./mediabunny.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(source: MediaInput): Promise<MediaContext> {\n const normalized = await normalizeSource(source);\n const sniffed = await sniffNormalizedSource(normalized);\n\n if (MEDIABUNNY_CONTAINERS.has(sniffed)) {\n try {\n return await probeWithMediabunny(normalized, sniffed);\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 Error(\n `failed to probe ${sniffed} file. mediabunny: ${mbMsg}. libav fallback: ${lvMsg}.`,\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 throw new Error(\n sniffed === \"unknown\"\n ? `unable to probe source: container could not be identified, and the libav.js fallback also failed: ${inner || \"(no message — see browser console for the original error)\"}`\n : `${sniffed.toUpperCase()} files require libav.js, which failed to load: ${inner || \"(no message — see browser console for the original error)\"}`,\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 */\nconst NATIVE_VIDEO_CODECS = new Set<VideoCodec>([\"h264\", \"h265\", \"vp8\", \"vp9\", \"av1\"]);\nconst 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 */\nconst FALLBACK_VIDEO_CODECS = new Set<VideoCodec>([\n \"wmv3\", \"vc1\", \"mpeg4\",\n \"rv10\", \"rv20\", \"rv30\", \"rv40\",\n \"mpeg2\", \"mpeg1\", \"theora\",\n]);\nconst FALLBACK_AUDIO_CODECS = new Set<AudioCodec>([\n \"wmav2\", \"wmapro\", \"ac3\", \"eac3\",\n \"cook\", \"ra_144\", \"ra_288\", \"sipr\", \"atrac3\",\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 if (audio && FALLBACK_AUDIO_CODECS.has(audio.codec)) {\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","/**\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","/**\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 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\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 Error(\"MSE not supported in this environment\");\n }\n if (!MediaSource.isTypeSupported(options.mime)) {\n throw new Error(`MSE does not support MIME \"${options.mime}\" — cannot remux`);\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 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 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 await video.play();\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 */\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\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 this.canvas.style.cssText =\n \"position:absolute;left:0;top:0;width:100%;height:100%;background:black;\";\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 // Wall-clock-paced painting with coarse A/V drift correction.\n //\n // Base policy: paint one frame every `paintIntervalMs` of wall time,\n // regardless of the frame's synthetic timestamp. This avoids the old\n // per-frame audio-gate that caused massive overflow during decode bursts.\n //\n // Drift correction (runs every ~1 sec):\n // - Video > 150 ms behind audio → drop one frame (catch up)\n // - Video > 150 ms ahead of audio → skip one paint (let audio catch up)\n //\n // This keeps long-run sync robust even for legacy AVI/DivX with messy\n // timestamps, packed B-frames, and odd frame durations. The correction\n // is deliberately gentle (one frame at a time) so it doesn't cause\n // visible stuttering.\n const wallNow = performance.now();\n if (wallNow - this.lastPaintWall < this.paintIntervalMs - 2) return;\n\n if (this.queue.length === 0) return;\n\n // Coarse drift correction: compare the head frame's timestamp to\n // audio.now() every ~1 sec (every 30 frames at 30fps). The frame ts\n // and audio.now() are both in seconds of media time. Drift beyond\n // 150ms triggers gentle correction — one frame per check, not a burst.\n if (this.framesPainted > 0 && this.framesPainted % 30 === 0) {\n const audioNowUs = this.clock.now() * 1_000_000;\n const headTs = this.queue[0].timestamp ?? 0;\n const driftUs = headTs - audioNowUs;\n\n if (driftUs < -150_000) {\n // Video behind audio by > 150ms — drop one frame to catch up.\n this.queue.shift()?.close();\n this.framesDroppedLate++;\n if (this.queue.length === 0) return;\n } else if (driftUs > 150_000) {\n // Video ahead of audio by > 150ms — skip this paint cycle.\n return;\n }\n }\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 while (this.queue.length > 0) this.queue.shift()?.close();\n this.prerolled = false;\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 constructor() {\n this.ctx = new AudioContext();\n this.gain = this.ctx.createGain();\n this.gain.connect(this.ctx.destination);\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 const ctxStart = this.ctxTimeAtAnchor + (this.mediaTimeOfNext - this.mediaTimeOfAnchor);\n const safeStart = Math.max(ctxStart, this.ctx.currentTime);\n node.start(safeStart);\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\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","/**\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 { 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}\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);\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 // ── 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 // Feed video packets to WebCodecs VideoDecoder\n if (videoDecoder && videoPackets && videoPackets.length > 0) {\n for (const pkt of videoPackets) {\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 // Decode audio with libav software decoder\n if (audioDec && audioPackets && audioPackets.length > 0) {\n await decodeAudioBatch(audioPackets, myToken);\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 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] hybrid audio decode 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 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 (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\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 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\ninterface BridgeModule {\n videoStreamToConfig(libav: unknown, stream: unknown): Promise<VideoDecoderConfig | null>;\n packetToEncodedVideoChunk(pkt: unknown, stream: unknown): EncodedVideoChunk;\n}\n","import type { MediaContext, PlaybackSession } 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): 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 });\n } catch (err) {\n audio.destroy();\n renderer.destroy();\n throw err;\n }\n\n // Patch <video> element for the unified player layer\n Object.defineProperty(target, \"currentTime\", {\n configurable: true,\n get: () => audio.now(),\n set: (v: number) => { void doSeek(v); },\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 }\n },\n\n pause() {\n void audio.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 } 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\";\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}\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);\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 // ── 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.\n let watchdogFirstFrameMs = 0;\n let watchdogSlowSinceMs = 0;\n let watchdogWarned = 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 groups at once).\n //\n // 64 KB ≈ 10-16 video packets at typical RV40/MPEG-4/H.264\n // bitrates — enough to amortize the ff_read_frame_multi +\n // ff_decode_multi crossings over several frames, but still\n // small enough that the renderer can drain via rAF before\n // `queue.length` approaches the 64-frame hard cap. The\n // decoder also checks `queueHighWater (30)` for backpressure\n // so bursts never accumulate.\n [readErr, packets] = await libav.ff_read_frame_multi(fmt_ctx, readPkt, {\n limit: 64 * 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 if (videoDec && videoPackets && videoPackets.length > 0) {\n await decodeVideoBatch(videoPackets, myToken);\n }\n if (myToken !== pumpToken || destroyed) return;\n if (audioDec && audioPackets && audioPackets.length > 0) {\n await decodeAudioBatch(audioPackets, 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 if (elapsedSinceFirst > 1 && !watchdogWarned) {\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 watchdogWarned = 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\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 (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\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 // 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\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 } 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): 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 });\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 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 * If the timeout fires, emits an unconditional diagnostic warning\n * naming the specific underflow — \"we have 12 ms of audio and 0 video\n * frames after 3 s, playback will be degraded\" — so users don't have\n * to root-cause a silent stall themselves.\n */\n async function waitForBuffer(): Promise<void> {\n const start = performance.now();\n dbg.info(\"cold-start\",\n `gate entry: need 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 if (audioReady && hasFrames) {\n dbg.info(\"cold-start\",\n `gate satisfied in ${(performance.now() - start).toFixed(0)}ms ` +\n `(audio=${(audioAhead * 1000).toFixed(0)}ms, frames=${renderer.queueDepth()})`,\n );\n return;\n }\n if ((performance.now() - start) / 1000 > READY_TIMEOUT_SECONDS) {\n // Give up waiting; play whatever we have. Flag loudly — this\n // means the decoder can't keep up with realtime for this\n // source, not that our code hung.\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 `Software decoder is producing output slower than realtime — ` +\n `playback will stutter. Check getDiagnostics().runtime for the decode rate.`,\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 }\n },\n\n pause() {\n void audio.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 } 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) => createHybridSession(ctx, video),\n};\n\nconst fallbackPlugin: Plugin = {\n name: \"fallback\",\n canHandle: () => true,\n execute: (ctx, video) => createFallbackSession(ctx, video),\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","/** 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 } from \"../types.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): Promise<void> {\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 fetch(t.sidecarUrl);\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 fetch(t.sidecarUrl);\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 Listener,\n} from \"./types.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 // 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 /**\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\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));\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. Awaited so fetch/parse\n // failures surface deterministically — but per-track failures are\n // caught inside attachSubtitleTracks and logged via console.warn so\n // a single bad sidecar doesn't break bootstrap. Subtitles are not\n // load-bearing for playback. (Promoting this to a typed `subtitleerror`\n // event is a nice-to-have follow-up.)\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 );\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.options.target.addEventListener(\"ended\", () => this.emitter.emit(\"ended\", undefined));\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);\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);\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 Error(\n `all fallback strategies failed: ${errors.join(\"; \")}`,\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 Error(\"player not ready\");\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);\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 Error(\"player not ready\");\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.session?.pause();\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 Error(\"player not ready\");\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 Error(\"player not ready\");\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 Error(\"player not ready\");\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.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 * Build a synthetic classification when the consumer asked for a specific\n * initial strategy. We ask `classify()` for the natural decision so we can\n * inherit the correct fallback chain, then override the strategy + class.\n *\n * Why this matters: hard-coding `class: \"NATIVE\"` (the old behavior) made\n * diagnostics lie for every initialStrategy that wasn't actually native, and\n * any downstream logic that trusted `strategyClass` could make the wrong\n * decision. We now derive the class from the picked strategy.\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 return {\n class: cls,\n strategy: initial,\n reason: `initial strategy \"${initial}\" requested via options.initialStrategy`,\n fallbackChain: natural.fallbackChain ?? defaultFallbackChain(initial),\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"]}
|