/** * Player adapter factory + public exports. * * `createAdapter` selects the concrete PlayerAdapter for the current platform. * Rust decides *which backend this platform has* (`useHtml5Element` from * `player_play_item`); this factory consumes that decision rather than * re-deriving it. * * The `experimentalNativeVideo` flag is a **suppressor, never a promoter**: it * can force the HTML5 path when Rust says native (so an in-progress spike cannot * ship as a regression), but it can never select native on a platform whose Rust * backend reported HTML5 — Linux has no way to composite a surface behind a * WebKitGTK webview, so promoting there would produce a black screen. * * The previous unconditional HTML5 override cited tauri#10152 as an upstream * blocker. That was stale: #10152 is a dormant *feature request*, the capability * shipped in tauri 27d01834, and the black-screen bug (tauri#8381, #9408) was a * broken `setBackgroundColor` JNI signature fixed in wry 0.39.4 — we ship 0.53.x. * * TRACES: UR-003, UR-004 | DR-004, DR-150 | UT-149 */ import { Html5PlayerAdapter, type Html5ElementBridge } from "./html5Adapter"; import { NativePlayerAdapter } from "./nativeAdapter"; import type { AdapterHost, PlayerAdapter } from "./types"; export type { PlayerAdapter, AdapterHost, PlayerLoadOptions, SubtitleTrackInput } from "./types"; export type { Html5ElementBridge } from "./html5Adapter"; export { Html5PlayerAdapter } from "./html5Adapter"; export { NativePlayerAdapter } from "./nativeAdapter"; /** What the Rust `player_play_item` response says it chose. */ export type BackendKind = "html5" | "native"; export interface CreateAdapterArgs { /** Backend kind reported by `player_play_item` (`useHtml5Element`). */ backendKind: BackendKind; host: AdapterHost; /** Required for the HTML5 adapter; ignored by the native adapter. */ bridge?: Html5ElementBridge; /** * User opt-in for the native video path. Defaults to **off**, so omitting it * yields today's behaviour (HTML5 everywhere) rather than silently enabling * the spike. */ experimentalNativeVideo?: boolean; } /** * Build the adapter for this platform/stream. * * Native is chosen only when Rust reports a native backend AND the user has * opted in. Every other combination is HTML5. */ export function createAdapter({ backendKind, host, bridge, experimentalNativeVideo = false, }: CreateAdapterArgs): PlayerAdapter { const effectiveKind: BackendKind = backendKind === "native" && experimentalNativeVideo ? "native" : "html5"; if (effectiveKind === "native") { // The native surface is owned by the backend — no DOM element, no bridge. return new NativePlayerAdapter(host); } if (!bridge) { throw new Error("createAdapter: Html5ElementBridge is required for the HTML5 adapter"); } return new Html5PlayerAdapter(host, bridge); }