Files
mixvideo-v2/cargos/tvai/examples/advanced_usage.rs
imeepos 42e3e923f9 feat: 完成 tvai 库核心处理引擎 (阶段二)
临时文件管理系统
- 实现 TempFileManager 完整功能
- 支持操作级别的文件跟踪和清理
- 自动清理机制和手动控制选项
- UUID 生成和唯一文件路径创建
- 支持文件和目录的创建与管理

 处理器核心逻辑增强
- 集成 TempFileManager 到 TvaiProcessor
- 添加进度回调支持 (ProgressCallback)
- 实现 ProcessingOptions 配置结构
- 添加文件验证功能 (输入/输出路径)
- FFmpeg 命令执行与进度跟踪

 核心处理方法
- execute_ffmpeg_command() 带进度回调
- validate_input_file() 输入文件验证
- validate_output_path() 输出路径验证
- create_metadata() 处理元数据生成
- get_ffmpeg_version() 版本信息获取

 API 增强
- 添加 create_temp_path() 临时文件创建
- 添加 create_unique_temp_path() 唯一路径生成
- 添加 create_temp_dir() 临时目录创建
- 添加 cleanup_temp_files() 操作清理
- 添加 cleanup_all_temp_files() 全量清理

 高级示例和测试
- 创建 advanced_usage.rs 展示所有新功能
- 临时文件管理演示
- 进度回调演示
- 文件验证演示
- 系统信息获取演示

 单元测试覆盖
- TempFileManager 完整测试套件
- TvaiProcessor 核心功能测试
- 配置构建器测试
- 进度回调类型测试

 测试结果
-  所有单元测试通过 (6/6)
-  文档测试通过 (1/1)
-  高级示例运行成功
-  临时文件管理功能验证
-  进度回调机制验证

 代码质量
- 完整的错误处理
- 内存安全的资源管理
- 异步友好的 API 设计
- 全面的类型安全

下一步: 开始阶段三 - 视频处理功能实现
2025-08-11 15:33:14 +08:00

146 lines
5.3 KiB
Rust

//! Advanced usage example showing temporary file management and progress tracking
use std::path::Path;
use tvai::*;
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("Topaz Video AI Library - Advanced Usage Example");
// Detect Topaz installation
if let Some(topaz_path) = detect_topaz_installation() {
println!("Found Topaz Video AI at: {}", topaz_path.display());
// Create configuration with custom temp directory
let config = TvaiConfig::builder()
.topaz_path(topaz_path)
.use_gpu(true)
.temp_dir(std::env::temp_dir().join("tvai_advanced_example"))
.build()?;
// Create processor
let mut processor = TvaiProcessor::new(config)?;
println!("Processor created successfully");
// Demonstrate temporary file management
demonstrate_temp_file_management(&mut processor)?;
// Demonstrate progress callback
demonstrate_progress_callback(&processor).await?;
// Demonstrate validation
demonstrate_validation(&processor)?;
// Get system information
demonstrate_system_info(&processor).await?;
println!("Advanced example completed successfully!");
} else {
println!("Topaz Video AI not found. Please install it first.");
}
Ok(())
}
fn demonstrate_temp_file_management(processor: &mut TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== Temporary File Management Demo ===");
let operation_id = processor.generate_operation_id();
println!("Generated operation ID: {}", operation_id);
// Create some temporary files
let temp_video = processor.create_temp_path(&operation_id, "input.mp4");
let temp_output = processor.create_temp_path(&operation_id, "output.mp4");
let temp_dir = processor.create_temp_dir(&operation_id)?;
println!("Created temp files:");
println!(" Video: {}", temp_video.display());
println!(" Output: {}", temp_output.display());
println!(" Directory: {}", temp_dir.display());
// Create a unique temp file
let unique_temp = processor.create_unique_temp_path("unique.tmp");
println!(" Unique: {}", unique_temp.display());
// Get temp manager info
println!("Temp manager tracking {} files", processor.temp_manager().file_count());
// Clean up operation files
processor.cleanup_temp_files(&operation_id)?;
println!("Cleaned up operation files");
Ok(())
}
async fn demonstrate_progress_callback(processor: &TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== Progress Callback Demo ===");
// Create a progress callback
let progress_callback: ProgressCallback = Box::new(|progress| {
let percentage = (progress * 100.0) as u32;
println!("Progress: {}%", percentage);
});
// Simulate FFmpeg command execution with progress
let args = ["-version"];
let _output = processor.execute_ffmpeg_command(&args, false, Some(&progress_callback)).await?;
println!("Command executed with progress tracking");
Ok(())
}
fn demonstrate_validation(processor: &TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== Validation Demo ===");
// Test input file validation (this will fail since file doesn't exist)
let test_input = Path::new("nonexistent_input.mp4");
match processor.validate_input_file(test_input) {
Ok(_) => println!("Input file validation passed"),
Err(e) => println!("Input file validation failed (expected): {}", e),
}
// Test output path validation
let test_output = processor.temp_dir().join("test_output.mp4");
match processor.validate_output_path(&test_output) {
Ok(_) => println!("Output path validation passed"),
Err(e) => println!("Output path validation failed: {}", e),
}
Ok(())
}
async fn demonstrate_system_info(processor: &TvaiProcessor) -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("\n=== System Information Demo ===");
// Get FFmpeg versions
if let Ok(system_version) = processor.get_ffmpeg_version(false).await {
println!("System FFmpeg: {}", system_version.lines().next().unwrap_or("Unknown"));
}
if let Ok(topaz_version) = processor.get_ffmpeg_version(true).await {
println!("Topaz FFmpeg: {}", topaz_version.lines().next().unwrap_or("Unknown"));
}
// Check GPU availability
println!("GPU enabled: {}", processor.is_gpu_enabled());
println!("GPU available: {}", processor.is_gpu_available());
// Get system detection info
let gpu_info = detect_gpu_support();
println!("GPU Info: CUDA={}, OpenCL={}", gpu_info.cuda_available, gpu_info.opencl_available);
let ffmpeg_info = detect_ffmpeg();
println!("FFmpeg Info: System={}, Topaz={}", ffmpeg_info.system_available, ffmpeg_info.topaz_available);
// Create sample metadata
let metadata = processor.create_metadata(
"sample_operation".to_string(),
Path::new("sample_input.mp4"),
"scale=2.0,model=iris-3".to_string(),
);
println!("Sample metadata: operation_id={}, used_gpu={}", metadata.operation_id, metadata.used_gpu);
Ok(())
}