Skip to main content

lingxia_platform/traits/
media_runtime.rs

1use std::path::{Path, PathBuf};
2
3use crate::error::PlatformError;
4
5use super::media_interaction::MediaKind;
6
7#[derive(Debug, Clone)]
8pub struct ImageInfo {
9    pub width: u32,
10    pub height: u32,
11    pub mime_type: Option<String>,
12}
13
14#[derive(Debug, Clone)]
15pub struct CompressImageRequest {
16    pub source_uri: String,
17    pub quality: u8,
18    pub max_width: Option<u32>,
19    pub max_height: Option<u32>,
20    pub output_path: PathBuf,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum VideoCompressQuality {
25    Low,
26    Medium,
27    High,
28}
29
30#[derive(Debug, Clone)]
31pub struct CompressVideoRequest {
32    pub source_uri: String,
33    pub quality: Option<VideoCompressQuality>,
34    /// Target average bitrate in kbps.
35    pub bitrate_kbps: Option<u32>,
36    /// Target frame rate in fps.
37    pub fps: Option<u32>,
38    /// Scale ratio relative to source resolution in (0, 1].
39    pub resolution_ratio: Option<f32>,
40    pub output_path: PathBuf,
41    /// Stream callback fired with `{"progress": N}` (N = 0..100) while the
42    /// transcode runs. Native may fire at any cadence; consecutive
43    /// duplicates are fine (the JS side dedupes).
44    pub progress_callback_id: u64,
45    /// Oneshot callback fired when the transcode finishes:
46    /// `{"success":true,"path":...,"width":...,"height":...,"durationMs":...,
47    /// "size":...,"mimeType":...}` or `{"success":false,"error":"..."}`.
48    pub callback_id: u64,
49}
50
51#[derive(Debug, Clone)]
52pub struct CompressedVideo {
53    pub path: PathBuf,
54    pub width: u32,
55    pub height: u32,
56    pub duration_ms: u64,
57    pub size: u64,
58    pub mime_type: Option<String>,
59}
60
61#[derive(Debug, Clone)]
62pub struct VideoInfo {
63    pub width: u32,
64    pub height: u32,
65    pub duration_ms: u64,
66    pub size: u64,
67    pub rotation: Option<u16>,
68    pub bitrate: Option<u64>,
69    pub fps: Option<f32>,
70    pub mime_type: Option<String>,
71    pub video_codec: Option<String>,
72    pub has_audio: Option<bool>,
73    pub audio_codec: Option<String>,
74}
75
76#[derive(Debug, Clone)]
77pub struct ExtractVideoThumbnailRequest {
78    pub source_uri: String,
79    pub output_path: PathBuf,
80    pub max_width: Option<u32>,
81    pub max_height: Option<u32>,
82    pub time_ms: Option<u64>,
83    pub quality: u8,
84}
85
86#[derive(Debug, Clone)]
87pub struct VideoThumbnail {
88    pub path: PathBuf,
89    pub width: u32,
90    pub height: u32,
91    pub mime_type: Option<String>,
92}
93
94pub trait MediaRuntime: Send + Sync + 'static {
95    /// Copy a picked/album media asset identified by `uri` into a local file at `dest_path`.
96    ///
97    /// Notes:
98    /// - `uri` is an opaque platform media reference coming from platform pickers and may not be a
99    ///   directly readable filesystem path.
100    /// - Implementations should support platform-specific schemes as applicable, for example:
101    ///   - Android: `content://...`
102    ///   - iOS: `ph://...` (or other Photos identifiers)
103    ///   - Harmony: picker URIs such as `file://media/...`
104    ///   - Some platforms may also provide `file:///absolute/path` (or an absolute path string).
105    /// - Implementations should create parent directories for `dest_path` if needed and write the
106    ///   file content so that `dest_path` exists on success.
107    fn copy_album_media_to_file(
108        &self,
109        uri: &str,
110        dest_path: &Path,
111        kind: MediaKind,
112    ) -> Result<(), PlatformError>;
113
114    fn get_image_info(&self, uri: &str) -> Result<ImageInfo, PlatformError>;
115
116    fn compress_image(&self, request: &CompressImageRequest) -> Result<PathBuf, PlatformError>;
117
118    /// Start a video transcode. Returns as soon as the job is accepted;
119    /// progress and the final result arrive on the request's callbacks.
120    fn compress_video(&self, request: &CompressVideoRequest) -> Result<(), PlatformError>;
121
122    /// Cancel a running transcode by its completion `callback_id`. Native
123    /// stops the job and SHOULD delete any partial output; it MUST NOT fire
124    /// the completion callback afterwards (the caller already removed it).
125    fn cancel_compress_video(&self, callback_id: u64) -> Result<(), PlatformError>;
126
127    fn get_video_info(&self, uri: &str) -> Result<VideoInfo, PlatformError>;
128
129    fn extract_video_thumbnail(
130        &self,
131        request: &ExtractVideoThumbnailRequest,
132    ) -> Result<VideoThumbnail, PlatformError>;
133}