Skip to main content

oximedia_proxy/generate/
mod.rs

1//! Proxy generation module.
2
3pub mod batch;
4pub mod encoder;
5pub mod optimizer;
6pub mod presets;
7pub mod settings;
8
9pub use batch::{BatchProxyGenerator, BatchResult};
10pub use encoder::{ProxyEncodeResult, ProxyEncoder};
11pub use optimizer::ProxyOptimizer;
12pub use presets::{PresetInfo, ProxyPresets};
13pub use settings::ProxyGenerationSettings;
14
15use crate::Result;
16use std::path::Path;
17
18/// High-level proxy generator interface.
19pub struct ProxyGenerator {
20    #[allow(dead_code)]
21    settings: ProxyGenerationSettings,
22}
23
24impl ProxyGenerator {
25    /// Create a new proxy generator with default settings.
26    #[must_use]
27    pub fn new() -> Self {
28        Self {
29            settings: ProxyGenerationSettings::default(),
30        }
31    }
32
33    /// Create a proxy generator with custom settings.
34    #[must_use]
35    pub fn with_settings(settings: ProxyGenerationSettings) -> Self {
36        Self { settings }
37    }
38
39    /// Generate a proxy file from an input file.
40    ///
41    /// # Errors
42    ///
43    /// Returns an error if generation fails.
44    pub async fn generate(
45        &self,
46        input: impl AsRef<Path>,
47        output: impl AsRef<Path>,
48        preset: ProxyPreset,
49    ) -> Result<ProxyEncodeResult> {
50        let settings = preset.to_settings();
51        let encoder = ProxyEncoder::new(settings)?;
52        encoder.encode(input.as_ref(), output.as_ref()).await
53    }
54
55    /// Generate a proxy with custom settings.
56    pub async fn generate_with_settings(
57        &self,
58        input: impl AsRef<Path>,
59        output: impl AsRef<Path>,
60        settings: ProxyGenerationSettings,
61    ) -> Result<ProxyEncodeResult> {
62        let encoder = ProxyEncoder::new(settings)?;
63        encoder.encode(input.as_ref(), output.as_ref()).await
64    }
65}
66
67impl Default for ProxyGenerator {
68    fn default() -> Self {
69        Self::new()
70    }
71}
72
73/// Proxy preset for quick setup.
74#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75pub enum ProxyPreset {
76    /// Quarter resolution H.264 proxy (25% scale, low bitrate).
77    QuarterResH264,
78    /// Half resolution H.264 proxy (50% scale, medium bitrate).
79    HalfResH264,
80    /// Full resolution H.264 proxy (100% scale, high bitrate).
81    FullResH264,
82    /// Quarter resolution VP9 proxy (25% scale, very efficient).
83    QuarterResVP9,
84    /// Half resolution VP9 proxy (50% scale, efficient).
85    HalfResVP9,
86}
87
88impl ProxyPreset {
89    /// Convert preset to generation settings.
90    #[must_use]
91    pub fn to_settings(self) -> ProxyGenerationSettings {
92        match self {
93            Self::QuarterResH264 => ProxyGenerationSettings::quarter_res_h264(),
94            Self::HalfResH264 => ProxyGenerationSettings::half_res_h264(),
95            Self::FullResH264 => ProxyGenerationSettings::full_res_h264(),
96            Self::QuarterResVP9 => ProxyGenerationSettings::quarter_res_vp9(),
97            Self::HalfResVP9 => ProxyGenerationSettings::default()
98                .with_scale_factor(0.5)
99                .with_codec("vp9")
100                .with_bitrate(3_000_000),
101        }
102    }
103
104    /// Get the name of this preset.
105    #[must_use]
106    pub const fn name(&self) -> &'static str {
107        match self {
108            Self::QuarterResH264 => "Quarter Res H.264",
109            Self::HalfResH264 => "Half Res H.264",
110            Self::FullResH264 => "Full Res H.264",
111            Self::QuarterResVP9 => "Quarter Res VP9",
112            Self::HalfResVP9 => "Half Res VP9",
113        }
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn test_proxy_generator_creation() {
123        let generator = ProxyGenerator::new();
124        assert_eq!(generator.settings.scale_factor, 0.25);
125    }
126
127    #[test]
128    fn test_proxy_presets() {
129        let settings = ProxyPreset::QuarterResH264.to_settings();
130        assert_eq!(settings.scale_factor, 0.25);
131        assert_eq!(settings.codec, "h264");
132
133        let settings = ProxyPreset::HalfResH264.to_settings();
134        assert_eq!(settings.scale_factor, 0.5);
135
136        let settings = ProxyPreset::QuarterResVP9.to_settings();
137        assert_eq!(settings.codec, "vp9");
138    }
139
140    #[test]
141    fn test_preset_names() {
142        assert_eq!(ProxyPreset::QuarterResH264.name(), "Quarter Res H.264");
143        assert_eq!(ProxyPreset::HalfResVP9.name(), "Half Res VP9");
144    }
145}