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}