265 lines
9.6 KiB
Rust
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(())
|
|
}
|