refactor(player): delete the webview video path; mpv selects its own tracks
DR-235 phase 3. Every video renderer is native now: mpv on Linux and Windows, ExoPlayer on Android, all drawing behind the transparent webview. The HTML5 <video> path is gone, not bypassed: - Frontend: hls.js, Html5PlayerAdapter and its compatibility shim, the createAdapter factory, streamTransport, hlsRecovery, timeTracking, videoFit, the <video>/<track> markup and every element handler in VideoPlayer (3277 -> 2144 lines), the experimentalNativeVideo store and its Settings toggle, webviewVideoFallback/supportsNativeVideo, and the setHtml5VideoState PiP bridge call. NativePlayerAdapter is the one video adapter; webview audio gets its own adapter kind. - Rust: use_html5 dropped from player_seek_video, player_switch_audio_track and player_set_stream_quality with the Html5* strategies and ReloadStream responses; use_html5_element and VideoBackend dropped from PlayerStatus; player_play_item always loads the backend (set_current_item removed); Capabilities::webview removed; the WebKitGTK GStreamer/VAAPI setup (and its gst-inspect spawn) removed. - Android: the HTML5 video state in PictureInPictureManager and ScreenWakeManager, and the bridge method feeding it. - CSP: connect-src loses http:/https: and worker-src loses blob: - both existed for hls.js; with it gone they were only an exfiltration channel and a blob worker for injected script. A test now keeps them out. mpv takes over what the <video> element did (mpv_tracks, UT-275): subtitles are the WebVTT list the play request carries, queued on sub-files and selected by position in that list, starting off; audio tracks are selected by position in the file; sid/aid are reset before each load. Without this, Linux video had no subtitle selection and a direct-play audio switch failed since mpv became its renderer. Verified: Rust 948 passing, and the same 948 cross-compiled for Windows under wine against the shipped DLL (track tests included); frontend 1111 passing; aarch64 debug APK builds. Lint warnings 158 -> 146, CI ratchet tightened to match. Not yet seen on Windows hardware.
This commit is contained in:
@@ -384,8 +384,8 @@ impl MpvBackend {
|
||||
// StateChanged rather than tracking playback itself, per the
|
||||
// one-directional state rule. Unobserved, the event never came and
|
||||
// the button never moved. Invisible until native video shipped,
|
||||
// because the webview <video> element's own DOM events drove that
|
||||
// control on Linux.
|
||||
// because the (since deleted) webview <video> element's own DOM
|
||||
// events drove that control on Linux.
|
||||
//
|
||||
// TRACES: UR-005 | DR-239
|
||||
ev_ctx
|
||||
@@ -696,6 +696,15 @@ impl PlayerBackend for MpvBackend {
|
||||
// TRACES: UR-040, UR-005 | DR-253
|
||||
*self.pending_seek.lock_safe() = None;
|
||||
|
||||
// The item's own sideloaded subtitles, none shown, and its default audio
|
||||
// track — whatever the previous item had chosen. Only video carries
|
||||
// subtitles; for audio this just clears the last item's.
|
||||
// TRACES: UR-020, UR-021 | DR-023, DR-024, DR-235
|
||||
let subtitle_urls: Vec<&str> = media.subtitles.iter().map(|t| t.url.as_str()).collect();
|
||||
super::mpv_tracks::prepare_load(&self.mpv, &subtitle_urls).map_err(|e| PlayerError {
|
||||
message: format!("Failed to prepare tracks: {e}"),
|
||||
})?;
|
||||
|
||||
// Load the media file. Through `mpv_command::command`, never
|
||||
// `Mpv::command`: the URL carries server-controlled text.
|
||||
// TRACES: UR-003, UR-004 | DR-298
|
||||
@@ -858,6 +867,36 @@ impl PlayerBackend for MpvBackend {
|
||||
state.volume
|
||||
}
|
||||
|
||||
/// `stream_index` is a *position*: the n-th audio track of the file, the
|
||||
/// same meaning ExoPlayer gives it (`player_switch_audio_track` passes the
|
||||
/// array index). Only reached for a direct play/stream — a transcode carries
|
||||
/// one track and is re-opened instead.
|
||||
///
|
||||
/// TRACES: UR-021 | IR-019, DR-024, DR-235
|
||||
fn set_audio_track(&mut self, stream_index: i32) -> Result<(), PlayerError> {
|
||||
let position = usize::try_from(stream_index).map_err(|_| PlayerError {
|
||||
message: format!("Invalid audio track position {stream_index}"),
|
||||
})?;
|
||||
super::mpv_tracks::select_audio(&self.mpv, position)
|
||||
.map_err(|message| PlayerError { message })
|
||||
}
|
||||
|
||||
/// `stream_index` is the position in the sideloaded subtitle list the play
|
||||
/// request carried (`nativeSubtitleArrayIndex`), `None` to hide subtitles.
|
||||
///
|
||||
/// TRACES: UR-020 | IR-018, DR-023, DR-235
|
||||
fn set_subtitle_track(&mut self, stream_index: Option<i32>) -> Result<(), PlayerError> {
|
||||
let position = stream_index
|
||||
.map(|i| {
|
||||
usize::try_from(i).map_err(|_| PlayerError {
|
||||
message: format!("Invalid subtitle position {i}"),
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
super::mpv_tracks::select_subtitle(&self.mpv, position)
|
||||
.map_err(|message| PlayerError { message })
|
||||
}
|
||||
|
||||
fn set_audio_settings(&mut self, settings: &AudioSettings) -> Result<(), PlayerError> {
|
||||
info!("[MpvBackend] Applying audio settings");
|
||||
self.audio_settings = settings.clone();
|
||||
|
||||
Reference in New Issue
Block a user