lingxia_platform/traits/video_player.rs
1use crate::error::PlatformError;
2
3#[derive(Debug, Clone, PartialEq)]
4pub enum VideoPlayerCommand {
5 Play,
6 Pause,
7 /// Stop playback and release decoder resources immediately if possible.
8 Stop,
9 /// Notify the native player that the current media/segment has ended.
10 ///
11 /// This is used by stream providers (Rust-side) to surface an authoritative end-of-stream
12 /// signal to the native player/controls, even when the decoder pipeline has no reliable
13 /// duration-based ended detection.
14 NotifyEnded,
15
16 /// Seek to a specific time in seconds.
17 Seek {
18 position: f64,
19 },
20
21 /// Provide an external duration for stream/piped playback (seconds).
22 /// Use `0` to clear.
23 SetDuration {
24 duration: f64,
25 },
26
27 EnterFullscreen,
28
29 ExitFullscreen,
30}
31
32/// Handle to a native component video player instance.
33/// Commands go through this handle without needing to re-specify the component ID.
34/// Note: Native component lifecycle is owned by the UI layer, not Rust.
35pub trait VideoPlayerHandle: Send + Sync {
36 /// Dispatch a control command to this player.
37 fn dispatch(&self, command: VideoPlayerCommand) -> Result<(), PlatformError>;
38}
39
40/// Generic video player handle implementation.
41/// Platform implementations provide a dispatch callback.
42pub struct VideoPlayerHandleImpl<D>
43where
44 D: Fn(VideoPlayerCommand) -> Result<(), PlatformError> + Send + Sync,
45{
46 dispatch_fn: D,
47}
48
49impl<D> VideoPlayerHandleImpl<D>
50where
51 D: Fn(VideoPlayerCommand) -> Result<(), PlatformError> + Send + Sync,
52{
53 pub fn new(dispatch_fn: D) -> Self {
54 Self { dispatch_fn }
55 }
56}
57
58impl<D> VideoPlayerHandle for VideoPlayerHandleImpl<D>
59where
60 D: Fn(VideoPlayerCommand) -> Result<(), PlatformError> + Send + Sync,
61{
62 fn dispatch(&self, command: VideoPlayerCommand) -> Result<(), PlatformError> {
63 (self.dispatch_fn)(command)
64 }
65}
66
67/// Platform-facing API for binding to native component video instances.
68/// Note: Native player creation is handled by the UI layer, not Rust.
69pub trait VideoPlayerManager: Send + Sync + 'static {
70 /// Bind to an existing native player.
71 ///
72 /// Returns a handle for dispatching commands to the player.
73 /// The native player must already be created by the UI layer (native component).
74 fn bind_player(&self, component_id: &str) -> Result<Box<dyn VideoPlayerHandle>, PlatformError>;
75
76 /// Set (or update) the callback ID for video player events for a component.
77 ///
78 /// Default implementation is a no-op for platforms that don't support callbacks.
79 fn set_player_callback(
80 &self,
81 _component_id: &str,
82 _callback_id: u64,
83 ) -> Result<(), PlatformError> {
84 Ok(())
85 }
86}