Skip to main content

oximedia_proxy/
examples.rs

1//! Examples and usage demonstrations for OxiMedia Proxy.
2#![allow(dead_code)]
3use crate::*;
4/// Example: Basic proxy generation.
5///
6/// ```no_run
7/// use oximedia_proxy::{ProxyGenerator, ProxyPreset};
8///
9/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
10/// let generator = ProxyGenerator::new();
11///
12/// // Generate a quarter-resolution proxy
13/// generator
14///     .generate("input.mov", "proxy.mp4", ProxyPreset::QuarterResH264)
15///     .await?;
16/// # Ok(())
17/// # }
18/// ```
19pub mod basic_generation {
20    use super::*;
21    /// Generate a single proxy with default settings.
22    pub async fn generate_simple_proxy(input: &str, output: &str) -> Result<ProxyEncodeResult> {
23        let generator = ProxyGenerator::new();
24        generator
25            .generate(input, output, ProxyPreset::QuarterResH264)
26            .await
27    }
28    /// Generate a proxy with custom settings.
29    pub async fn generate_custom_proxy(
30        input: &str,
31        output: &str,
32        scale_factor: f32,
33        bitrate: u64,
34    ) -> Result<ProxyEncodeResult> {
35        let settings = ProxyGenerationSettings::default()
36            .with_scale_factor(scale_factor)
37            .with_bitrate(bitrate);
38        let generator = ProxyGenerator::new();
39        generator
40            .generate_with_settings(input, output, settings)
41            .await
42    }
43}
44/// Example: Batch proxy generation.
45///
46/// ```no_run
47/// use oximedia_proxy::{BatchProxyGenerator, ProxyGenerationSettings};
48///
49/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
50/// let settings = ProxyGenerationSettings::quarter_res_h264();
51/// let batch_generator = BatchProxyGenerator::new(settings);
52///
53/// let inputs = vec![
54///     (std::path::PathBuf::from("clip1.mov"), std::path::PathBuf::from("proxy1.mp4")),
55///     (std::path::PathBuf::from("clip2.mov"), std::path::PathBuf::from("proxy2.mp4")),
56/// ];
57///
58/// let results = batch_generator.generate_batch(&inputs).await?;
59/// # Ok(())
60/// # }
61/// ```
62pub mod batch_generation {
63    use super::*;
64    use std::path::PathBuf;
65    /// Generate proxies for multiple files in parallel.
66    pub async fn batch_generate(
67        inputs: &[(PathBuf, PathBuf)],
68        preset: ProxyPreset,
69    ) -> Result<Vec<BatchResult>> {
70        let settings = preset.to_settings();
71        let generator = BatchProxyGenerator::new(settings);
72        generator.generate_batch(inputs).await
73    }
74    /// Generate proxies with progress reporting.
75    pub async fn batch_generate_with_progress<F>(
76        inputs: &[(PathBuf, PathBuf)],
77        preset: ProxyPreset,
78        progress_callback: F,
79    ) -> Result<Vec<BatchResult>>
80    where
81        F: FnMut(usize, usize) + Send,
82    {
83        let settings = preset.to_settings();
84        let generator = BatchProxyGenerator::new(settings);
85        generator
86            .generate_batch_with_progress(inputs, progress_callback)
87            .await
88    }
89}
90/// Example: Proxy linking and management.
91///
92/// ```no_run
93/// use oximedia_proxy::ProxyLinkManager;
94///
95/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
96/// let mut manager = ProxyLinkManager::new("links.db").await?;
97///
98/// // Link proxy to original
99/// manager.link_proxy("proxy.mp4", "original.mov").await?;
100///
101/// // Get original path from proxy
102/// let original = manager.get_original("proxy.mp4")?;
103/// println!("Original: {}", original.display());
104/// # Ok(())
105/// # }
106/// ```
107pub mod link_management {
108    use super::*;
109    use std::collections::HashMap;
110    /// Create and manage proxy links.
111    pub async fn create_links(db_path: &str, proxies: &[(String, String)]) -> Result<()> {
112        let mut manager = ProxyLinkManager::new(db_path).await?;
113        for (proxy, original) in proxies {
114            manager
115                .link_proxy_with_metadata(proxy, original, 0.25, "h264", 0.0, None, HashMap::new())
116                .await?;
117        }
118        Ok(())
119    }
120    /// Verify all proxy links.
121    pub fn verify_all_links(manager: &mut ProxyLinkManager) -> Result<usize> {
122        let all_links = manager.all_links();
123        let mut valid_count = 0;
124        for link in &all_links {
125            if manager.verify_link(&link.proxy_path)? {
126                valid_count += 1;
127            }
128        }
129        Ok(valid_count)
130    }
131}
132/// Example: Complete offline editing workflow.
133///
134/// ```no_run
135/// use oximedia_proxy::{OfflineWorkflow, ProxyPreset};
136///
137/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
138/// let mut workflow = OfflineWorkflow::new("project.db").await?;
139///
140/// // Step 1: Ingest and create proxies
141/// workflow.ingest(
142///     "camera/clip001.mov",
143///     "proxies/clip001.mp4",
144///     ProxyPreset::QuarterResH264
145/// ).await?;
146///
147/// // Step 2: Edit with proxies (use your NLE)
148///
149/// // Step 3: Conform to original
150/// workflow.conform("edit.edl", "final.mov").await?;
151/// # Ok(())
152/// # }
153/// ```
154pub mod offline_workflow {
155    use super::*;
156    /// Complete offline-to-online workflow.
157    pub async fn complete_workflow(
158        db_path: &str,
159        camera_files: &[&str],
160        proxy_dir: &str,
161        edl_path: &str,
162        output: &str,
163    ) -> Result<ConformResult> {
164        let mut workflow = OfflineWorkflow::new(db_path).await?;
165        // Phase 1: Ingest
166        for (i, camera_file) in camera_files.iter().enumerate() {
167            let proxy_path = format!("{}/proxy_{:03}.mp4", proxy_dir, i);
168            workflow
169                .ingest(camera_file, &proxy_path, ProxyPreset::QuarterResH264)
170                .await?;
171        }
172        // Phase 2: Edit (external)
173        tracing::info!("Edit your proxies in your NLE");
174        // Phase 3: Conform
175        workflow.conform(edl_path, output).await
176    }
177}
178/// Example: Workflow planning and estimation.
179///
180/// ```no_run
181/// use oximedia_proxy::{WorkflowPlanner, MediaInfo, ProxyGenerationSettings};
182///
183/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
184/// let planner = WorkflowPlanner::new();
185///
186/// let inputs = vec![
187///     MediaInfo::from_path("clip1.mov")?,
188///     MediaInfo::from_path("clip2.mov")?,
189/// ];
190///
191/// let settings = ProxyGenerationSettings::quarter_res_h264();
192/// let plan = planner.plan_generation(&inputs, settings)?;
193///
194/// println!("Estimated encoding time: {:.1} minutes", plan.estimated_encoding_time / 60.0);
195/// println!("Space savings: {:.1}%", (1.0 - plan.compression_ratio) * 100.0);
196/// # Ok(())
197/// # }
198/// ```
199pub mod workflow_planning {
200    use super::*;
201    /// Plan a workflow and get estimates.
202    pub fn plan_workflow(media_files: &[MediaInfo], preset: ProxyPreset) -> Result<WorkflowPlan> {
203        let planner = WorkflowPlanner::new();
204        let settings = preset.to_settings();
205        planner.plan_generation(media_files, settings)
206    }
207    /// Estimate storage requirements.
208    pub fn estimate_storage(
209        media_files: &[MediaInfo],
210        preset: ProxyPreset,
211        keep_originals: bool,
212    ) -> StorageEstimate {
213        let planner = WorkflowPlanner::new();
214        let settings = preset.to_settings();
215        planner.estimate_storage(media_files, &settings, keep_originals)
216    }
217}
218/// Example: Validation and quality assurance.
219///
220/// ```no_run
221/// use oximedia_proxy::{ValidationChecker, ProxyLinkManager};
222///
223/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
224/// let manager = ProxyLinkManager::new("links.db").await?;
225/// let checker = ValidationChecker::new(&manager);
226///
227/// let report = checker.validate()?;
228///
229/// if report.is_valid() {
230///     println!("All proxies are valid!");
231/// } else {
232///     println!("Found {} errors", report.error_count());
233///     for error in &report.errors {
234///         println!("  - {}", error);
235///     }
236/// }
237/// # Ok(())
238/// # }
239/// ```
240pub mod validation {
241    use super::*;
242    /// Validate all proxy links and report issues.
243    pub fn validate_workflow(manager: &ProxyLinkManager) -> Result<ValidationReport> {
244        let checker = ValidationChecker::new(manager);
245        checker.validate()
246    }
247    /// Perform strict validation with comprehensive checks.
248    pub fn strict_validation(manager: &ProxyLinkManager) -> Result<ValidationReport> {
249        let validator = WorkflowValidator::new(manager).strict();
250        validator.validate_all()
251    }
252}
253/// Example: Cache management.
254///
255/// ```no_run
256/// use oximedia_proxy::{CacheManager, CacheStrategy};
257///
258/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
259/// let cache_dir = std::path::PathBuf::from("/var/cache/proxies");
260/// let max_size = 10 * 1024 * 1024 * 1024; // 10 GB
261///
262/// let mut cache = CacheManager::new(cache_dir, max_size);
263/// cache.set_strategy(CacheStrategy::Lru);
264///
265/// // Add proxies to cache
266/// cache.add(std::path::PathBuf::from("proxy1.mp4"), 100_000_000);
267/// cache.add(std::path::PathBuf::from("proxy2.mp4"), 150_000_000);
268///
269/// println!("Cache utilization: {:.1}%", cache.utilization());
270/// # Ok(())
271/// # }
272/// ```
273pub mod cache_management {
274    use super::*;
275    /// Set up and manage proxy cache.
276    pub fn setup_cache(
277        cache_dir: std::path::PathBuf,
278        max_size: u64,
279        strategy: CacheStrategy,
280    ) -> CacheManager {
281        let mut cache = CacheManager::new(cache_dir, max_size);
282        cache.set_strategy(strategy);
283        cache
284    }
285    /// Clean up cache based on policy.
286    pub fn cleanup_cache(cache_dir: std::path::PathBuf, policy: CleanupPolicy) -> Result<()> {
287        let cleanup = CacheCleanup::new(cache_dir);
288        let result = cleanup.cleanup(policy)?;
289        tracing::info!(
290            "Cleaned up {} files, freed {} bytes",
291            result.files_removed,
292            result.bytes_freed
293        );
294        Ok(())
295    }
296}
297/// Example: Multi-resolution proxy management.
298///
299/// ```no_run
300/// use oximedia_proxy::{ResolutionManager, ProxyResolution, ProxyVariant};
301/// use std::path::PathBuf;
302///
303/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
304/// let mut manager = ResolutionManager::new();
305///
306/// let original = PathBuf::from("original.mov");
307///
308/// // Add quarter resolution variant
309/// manager.add_variant(
310///     original.clone(),
311///     ProxyVariant {
312///         resolution: ProxyResolution::Quarter,
313///         path: PathBuf::from("proxy_quarter.mp4"),
314///         file_size: 50_000_000,
315///         codec: "h264".to_string(),
316///     },
317/// );
318///
319/// // Add half resolution variant
320/// manager.add_variant(
321///     original.clone(),
322///     ProxyVariant {
323///         resolution: ProxyResolution::Half,
324///         path: PathBuf::from("proxy_half.mp4"),
325///         file_size: 150_000_000,
326///         codec: "h264".to_string(),
327///     },
328/// );
329///
330/// // Get best variant for target resolution
331/// let variant = manager.get_best_variant(&original, ProxyResolution::Quarter);
332/// # Ok(())
333/// # }
334/// ```
335pub mod resolution_management {
336    use super::*;
337    use std::path::PathBuf;
338    /// Create multi-resolution proxy set.
339    pub fn create_multiresolution_proxies(
340        original: &str,
341        output_dir: &str,
342    ) -> Result<ResolutionManager> {
343        let mut manager = ResolutionManager::new();
344        let original_path = PathBuf::from(original);
345        let resolutions = vec![
346            (ProxyResolution::Quarter, "quarter"),
347            (ProxyResolution::Half, "half"),
348            (ProxyResolution::Full, "full"),
349        ];
350        for (resolution, suffix) in resolutions {
351            let proxy_path = PathBuf::from(format!("{}/proxy_{}.mp4", output_dir, suffix));
352            manager.add_variant(
353                original_path.clone(),
354                ProxyVariant {
355                    resolution,
356                    path: proxy_path,
357                    file_size: 0,
358                    codec: "h264".to_string(),
359                },
360            );
361        }
362        Ok(manager)
363    }
364}
365/// Example: Statistics and analytics.
366///
367/// ```no_run
368/// use oximedia_proxy::{LinkStatistics, LinkDatabase};
369///
370/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
371/// let db = LinkDatabase::new("links.db").await?;
372/// let stats = LinkStatistics::new(&db);
373///
374/// let report = stats.collect();
375///
376/// println!("Total links: {}", report.total_links);
377/// println!("Compression ratio: {:.2}:1", 1.0 / report.compression_ratio);
378/// println!("Space saved: {} bytes", report.space_saved);
379/// println!("\n{}", report.summary());
380/// # Ok(())
381/// # }
382/// ```
383pub mod statistics {
384    use super::*;
385    /// Collect and display comprehensive statistics.
386    pub async fn show_statistics(db_path: &str) -> Result<()> {
387        let db = LinkDatabase::new(db_path).await?;
388        let collector = LinkStatistics::new(&db);
389        let stats = collector.collect();
390        println!("=== Proxy Statistics ===");
391        println!("{}", stats.summary());
392        if let Some(codec) = stats.most_used_codec() {
393            let codec_stats = collector.codec_statistics(&codec);
394            println!("\nMost used codec: {}", codec);
395            println!("  Files: {}", codec_stats.count);
396            println!(
397                "  Avg bitrate: {} Mbps",
398                codec_stats.avg_bitrate / 1_000_000
399            );
400        }
401        Ok(())
402    }
403}
404#[cfg(test)]
405mod tests {
406    #[test]
407    fn test_examples_compile() {
408        // This test just ensures all example modules compile
409        assert!(true);
410    }
411}