mixvideo-v2/cargos/tvai/examples/video_processing_workflow.rs

265 lines
9.6 KiB
Rust

//! Video Processing Workflow Example
//!
//! This example demonstrates a complete video processing workflow
//! using the template system for different types of video content.
use tvai::*;
use std::path::Path;
use std::time::Instant;
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Video Processing Workflow Demo ===\n");
// Check if Topaz Video AI is available
match detect_topaz_installation() {
Some(path) => {
println!("✓ Topaz Video AI found at: {:?}", path);
}
None => {
println!("⚠ Topaz Video AI not found. This demo will show the workflow without actual processing.");
println!(" Install Topaz Video AI to run actual video processing.\n");
}
}
// List available templates
println!("Available processing templates:");
let templates = list_available_templates();
for (i, template_name) in templates.iter().enumerate() {
if let Some((name, description)) = get_template_info(template_name) {
println!(" {}. {} ({})", i + 1, name, template_name);
println!(" {}", description);
}
}
println!();
// Demonstrate different workflow scenarios
demonstrate_upscaling_workflow().await?;
demonstrate_frame_rate_workflow().await?;
demonstrate_restoration_workflow().await?;
demonstrate_creative_workflow().await?;
demonstrate_batch_processing().await?;
println!("=== Workflow Demo Complete ===");
Ok(())
}
/// Demonstrate video upscaling workflow
async fn demonstrate_upscaling_workflow() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Upscaling Workflow ===");
let input_path = Path::new("examples/sample_video.mp4");
let output_path = Path::new("output/upscaled_4k.mp4");
println!("Scenario: Upscaling a low-resolution video to 4K");
println!("Input: {:?}", input_path);
println!("Output: {:?}", output_path);
println!("Template: upscale_to_4k");
// Show what the template would do
let manager = global_topaz_templates().lock().unwrap();
if let Ok(applied) = manager.apply_template("upscale_to_4k") {
println!("Processing parameters:");
if let Some(upscale) = &applied.enhance_params.upscale {
println!(" • Scale factor: {}x", upscale.scale_factor);
println!(" • AI Model: {:?}", upscale.model);
println!(" • Quality preset: {:?}", upscale.quality_preset);
println!(" • Compression: {}", upscale.compression);
}
}
drop(manager);
// Simulate processing (would actually process if files exist)
if input_path.exists() {
println!("Processing...");
let start = Instant::now();
match upscale_to_4k(input_path, output_path).await {
Ok(result) => {
println!("✓ Processing completed successfully!");
println!(" Processing time: {:?}", result.processing_time);
println!(" Output file: {:?}", result.output_path);
}
Err(e) => {
println!("✗ Processing failed: {}", e);
println!(" Suggestion: {}", e.user_friendly_message());
}
}
} else {
println!("⚠ Input file not found - showing workflow only");
println!(" Would process: {:?} -> {:?}", input_path, output_path);
}
println!();
Ok(())
}
/// Demonstrate frame rate conversion workflow
async fn demonstrate_frame_rate_workflow() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Frame Rate Conversion Workflow ===");
let input_path = Path::new("examples/low_fps_video.mp4");
let output_path = Path::new("output/smooth_60fps.mp4");
println!("Scenario: Converting 24fps video to smooth 60fps");
println!("Input: {:?}", input_path);
println!("Output: {:?}", output_path);
println!("Template: convert_to_60fps");
// Show template parameters
let manager = global_topaz_templates().lock().unwrap();
if let Ok(applied) = manager.apply_template("convert_to_60fps") {
println!("Processing parameters:");
if let Some(interpolation) = &applied.enhance_params.interpolation {
println!(" • Interpolation model: {:?}", interpolation.model);
println!(" • Multiplier: {}x", interpolation.multiplier);
println!(" • Target FPS: {:?}", interpolation.target_fps);
}
if let Some(fps) = applied.output_fps {
println!(" • Output frame rate: {} fps", fps);
}
}
drop(manager);
if input_path.exists() {
println!("Processing...");
match convert_to_60fps(input_path, output_path).await {
Ok(result) => {
println!("✓ Frame rate conversion completed!");
println!(" Processing time: {:?}", result.processing_time);
}
Err(e) => {
println!("✗ Processing failed: {}", e);
}
}
} else {
println!("⚠ Input file not found - showing workflow only");
}
println!();
Ok(())
}
/// Demonstrate video restoration workflow
async fn demonstrate_restoration_workflow() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Video Restoration Workflow ===");
let input_path = Path::new("examples/noisy_old_video.mp4");
let output_path = Path::new("output/restored_clean.mp4");
println!("Scenario: Restoring old, noisy video footage");
println!("Input: {:?}", input_path);
println!("Output: {:?}", output_path);
println!("Template: remove_noise");
// Show restoration parameters
let manager = global_topaz_templates().lock().unwrap();
if let Ok(applied) = manager.apply_template("remove_noise") {
println!("Processing parameters:");
if let Some(upscale) = &applied.enhance_params.upscale {
println!(" • AI Model: {:?} (specialized for noise reduction)", upscale.model);
println!(" • Noise reduction: {}", upscale.noise);
println!(" • Detail preservation: {}", upscale.details);
}
}
drop(manager);
if input_path.exists() {
println!("Processing...");
match remove_noise(input_path, output_path).await {
Ok(result) => {
println!("✓ Video restoration completed!");
println!(" Processing time: {:?}", result.processing_time);
}
Err(e) => {
println!("✗ Processing failed: {}", e);
}
}
} else {
println!("⚠ Input file not found - showing workflow only");
}
println!();
Ok(())
}
/// Demonstrate creative effects workflow
async fn demonstrate_creative_workflow() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Creative Effects Workflow ===");
let input_path = Path::new("examples/action_video.mp4");
let output_path = Path::new("output/epic_slow_motion.mp4");
println!("Scenario: Creating cinematic slow motion effect");
println!("Input: {:?}", input_path);
println!("Output: {:?}", output_path);
println!("Template: 4x_slow_motion");
// Show creative parameters
let manager = global_topaz_templates().lock().unwrap();
if let Ok(applied) = manager.apply_template("4x_slow_motion") {
println!("Processing parameters:");
if let Some(interpolation) = &applied.enhance_params.interpolation {
println!(" • Slow motion factor: {}x", interpolation.multiplier);
println!(" • Interpolation model: {:?}", interpolation.model);
println!(" • Input FPS: {}", interpolation.input_fps);
}
}
drop(manager);
if input_path.exists() {
println!("Processing...");
match slow_motion_4x(input_path, output_path).await {
Ok(result) => {
println!("✓ Slow motion effect created!");
println!(" Processing time: {:?}", result.processing_time);
}
Err(e) => {
println!("✗ Processing failed: {}", e);
}
}
} else {
println!("⚠ Input file not found - showing workflow only");
}
println!();
Ok(())
}
/// Demonstrate batch processing workflow
async fn demonstrate_batch_processing() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("=== Batch Processing Workflow ===");
let input_files = vec![
("examples/video1.mp4", "output/video1_enhanced.mp4", "upscale_to_4k"),
("examples/video2.mp4", "output/video2_smooth.mp4", "convert_to_60fps"),
("examples/video3.mp4", "output/video3_clean.mp4", "remove_noise"),
];
println!("Scenario: Processing multiple videos with different templates");
for (input, output, template) in &input_files {
println!("\nProcessing: {} -> {} (template: {})", input, output, template);
let input_path = Path::new(input);
let output_path = Path::new(output);
if input_path.exists() {
match process_with_template(input_path, output_path, template).await {
Ok(result) => {
println!(" ✓ Completed in {:?}", result.processing_time);
}
Err(e) => {
println!(" ✗ Failed: {}", e);
}
}
} else {
println!(" ⚠ Input file not found - would process with template '{}'", template);
}
}
println!("\nBatch processing workflow complete!");
println!();
Ok(())
}