diff --git a/src-tauri/src/conformance_runner.rs b/src-tauri/src/conformance_runner.rs index 985bf5e9..44724218 100644 --- a/src-tauri/src/conformance_runner.rs +++ b/src-tauri/src/conformance_runner.rs @@ -152,7 +152,7 @@ pub fn run_engine(url: &str, engine: Engine) -> u32 { std::sync::Arc::new(crate::playback_reporting::throttle::EventThrottler::new()), ) .expect("could not create the legacy backend"), - crate::player::media_player::Capabilities::native(), + crate::player::media_player::Capabilities::mpv(), )); } } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index fc87d201..7d624e98 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -738,6 +738,27 @@ fn create_player_backend( /// Construct the tauri-specta command builder. Shared by `run()` and the /// bindings-export test so the TypeScript bindings always match the handler. +/// What the engine built for this platform can do. +/// +/// Declared per engine, not per category. ExoPlayer speaks HLS and can seek a +/// server-side transcode in place; mpv cannot, because its HLS demuxer will not +/// make the server produce segments from a new offset. Grouping them as "native +/// engines" gets that backwards — being native is not the property that +/// matters, speaking HLS is — and treating a category as a proxy for an ability +/// is exactly the inference DR-246 removed. +/// +/// TRACES: UR-081 | DR-246 +fn engine_capabilities() -> crate::player::media_player::Capabilities { + #[cfg(target_os = "android")] + { + crate::player::media_player::Capabilities::exoplayer() + } + #[cfg(not(target_os = "android"))] + { + crate::player::media_player::Capabilities::mpv() + } +} + fn specta_builder() -> Builder { Builder::::new() // Throw on error so generated `commands.*` return Promise and throw, @@ -1416,10 +1437,7 @@ pub fn run() { let player_controller = PlayerController::new( Box::new(crate::player::LegacyPlayer::new( backend, - // Both native engines decode the stream themselves; the - // webview path declares its own abilities when it becomes - // an engine (DR-248). - crate::player::media_player::Capabilities::native(), + engine_capabilities(), )), playback_reporter.clone(), position_throttler.clone(), diff --git a/src-tauri/src/player/media_player.rs b/src-tauri/src/player/media_player.rs index e379e85b..89ac6c6d 100644 --- a/src-tauri/src/player/media_player.rs +++ b/src-tauri/src/player/media_player.rs @@ -139,12 +139,12 @@ pub struct Capabilities { } impl Capabilities { - /// What a native engine of this project's kind can do. + /// mpv. /// - /// `seeks_transcoded_in_place` is false: both native engines decode the - /// stream themselves and neither can make the server transcode from a new - /// offset. hls.js is the exception, and says so for itself. - pub fn native() -> Self { + /// Cannot seek a server-side transcode in place: its HLS demuxer will not + /// make the server produce segments from a new offset, so the stream has to + /// be re-opened. + pub fn mpv() -> Self { Self { video: true, audio_settings: true, @@ -154,6 +154,24 @@ impl Capabilities { } } + /// ExoPlayer. + /// + /// **Can** seek a transcode in place. It is a full HLS client, so like + /// hls.js it seeks within the VOD playlist it was handed and lets the + /// server catch up. Grouping it with mpv as "a native engine" gets this + /// exactly backwards — being native is not the property that matters here, + /// speaking HLS is, and that is the whole reason this is declared per + /// engine rather than inferred from a category. + pub fn exoplayer() -> Self { + Self { + video: true, + audio_settings: true, + subtitle_switching: true, + audio_track_switching: true, + seeks_transcoded_in_place: true, + } + } + /// An engine that renders through the webview element, where hls.js seeks /// within the playlist it was handed. pub fn webview() -> Self { diff --git a/src-tauri/src/player/mod.rs b/src-tauri/src/player/mod.rs index 210d2a9f..cbca0101 100644 --- a/src-tauri/src/player/mod.rs +++ b/src-tauri/src/player/mod.rs @@ -2253,7 +2253,7 @@ impl Default for PlayerController { Self::new( Box::new(LegacyPlayer::new( NullBackend::new(), - crate::player::media_player::Capabilities::native(), + crate::player::media_player::Capabilities::mpv(), )), playback_reporter, position_throttler,