diff --git a/cargos/tvai-v2/src/ffmpeg.rs b/cargos/tvai-v2/src/ffmpeg.rs index 796efd4..2ee3eb7 100644 --- a/cargos/tvai-v2/src/ffmpeg.rs +++ b/cargos/tvai-v2/src/ffmpeg.rs @@ -542,23 +542,31 @@ impl FfmpegCommandGenerator { // 使用默认的稳定化模型 params.push("model=ref-2".to_string()); - // 映射方法(0: 自动裁剪, 1: 无裁剪/全帧) - let method = if settings.method == 0 { "auto_crop" } else { "no_crop" }; - params.push(format!("method={}", method)); + // 映射稳定化方法(0: 自动裁剪, 1: 全帧稳定化) + let full_frame = if settings.method == 0 { 0 } else { 1 }; + params.push(format!("full={}", full_frame)); - // 映射平滑度(模板中为 0-100) - params.push(format!("smooth={}", settings.smooth)); + // 映射平滑度(模板中为 0-100,转换为 0-16 范围) + let smoothness = (settings.smooth as f64 / 100.0 * 16.0).min(16.0); + params.push(format!("smoothness={:.1}", smoothness)); // 滚动快门校正 if settings.rsc { - params.push("rsc=1".to_string()); + params.push("roll=1".to_string()); } - // 减少运动 + // 减少运动抖动 if settings.reduce_motion { - params.push(format!("reduce_motion={}", settings.reduce_motion_iteration)); + let reduce_level = settings.reduce_motion_iteration.min(5); + params.push(format!("reduce={}", reduce_level)); } + // 调试信息 + println!("生成 tvai_stb 滤镜参数: {:?}", params); + println!("稳定化设置: smoothness={:.1}, full={}, roll={}, reduce={}", + smoothness, full_frame, settings.rsc, + if settings.reduce_motion { settings.reduce_motion_iteration } else { 0 }); + Ok(format!("tvai_stb={}", params.join(":"))) } @@ -696,10 +704,17 @@ impl FfmpegCommandGenerator { params.push(format!("slowmo={}", slowmo_settings.factor)); } - // 如果指定了输出 FPS,设置参数 + // 设置输出帧率(video_rate 格式) if output_settings.out_fps > 0.0 { - params.push(format!("fps={}", output_settings.out_fps)); + // 将浮点数转换为分数格式,例如 60.0 -> "60/1" + if output_settings.out_fps.fract() == 0.0 { + params.push(format!("fps={}/1", output_settings.out_fps as i32)); + } else { + // 对于非整数帧率,使用更精确的分数表示 + params.push(format!("fps={:.3}", output_settings.out_fps)); + } } + // 注意:当 out_fps 为 0 时,不添加 fps 参数,让 tvai_fi 使用默认的 "0" 值 // 重复帧阈值(rdt 参数) if !slowmo_settings.duplicate { @@ -709,6 +724,10 @@ impl FfmpegCommandGenerator { params.push(format!("rdt={:.3}", threshold)); } + // 调试信息 + println!("生成 tvai_fi 滤镜参数: {:?}", params); + println!("输出 FPS: {}, 慢动作因子: {}", output_settings.out_fps, slowmo_settings.factor); + Ok(format!("tvai_fi={}", params.join(":"))) } diff --git a/cargos/tvai/src/config/topaz_templates.rs b/cargos/tvai/src/config/topaz_templates.rs index 4c8655a..505f418 100644 --- a/cargos/tvai/src/config/topaz_templates.rs +++ b/cargos/tvai/src/config/topaz_templates.rs @@ -1140,10 +1140,10 @@ impl TopazTemplateManager { // Apply stabilization if template.settings.stabilize.active { - let method = if template.settings.stabilize.method == 0 { "auto_crop" } else { "no_crop" }; - let smooth = template.settings.stabilize.smooth; + let full_frame = if template.settings.stabilize.method == 0 { 0 } else { 1 }; + let smoothness = (template.settings.stabilize.smooth as f64 / 100.0 * 16.0).min(16.0); - let stabilize_filter = format!("tvai_stab=method={}:smooth={}", method, smooth); + let stabilize_filter = format!("tvai_stb=model=ref-2:full={}:smoothness={:.1}", full_frame, smoothness); filters.push(stabilize_filter); } @@ -1755,10 +1755,10 @@ impl TopazTemplateManager { // Apply stabilization if template.settings.stabilize.active { - let method = if template.settings.stabilize.method == 0 { "auto_crop" } else { "no_crop" }; - let smooth = template.settings.stabilize.smooth; + let full_frame = if template.settings.stabilize.method == 0 { 0 } else { 1 }; + let smoothness = (template.settings.stabilize.smooth as f64 / 100.0 * 16.0).min(16.0); - let stabilization_filter = format!("tvai_stab=method={}:smooth={}", method, smooth); + let stabilization_filter = format!("tvai_stb=model=ref-2:full={}:smoothness={:.1}", full_frame, smoothness); filters.push(stabilization_filter); } @@ -1824,7 +1824,9 @@ impl TopazTemplateManager { } if let Some(fps) = opts.target_fps { - fi_filter.push_str(&format!(":fps={}", fps)); + if fps > 0 { + fi_filter.push_str(&format!(":fps={}", fps)); + } } fi_filter.push_str(&format!(