feat: 实现 16:9 9:16 视频宽高比转换功能

主要改进:
- 修复前端模板选择与后端识别不匹配问题
- 解决驼峰命名法与下划线命名法转换问题
- 实现正确的宽高比转换滤镜链 (tvai_up + scale + crop)
- 添加模板名称传递机制避免硬编码推断
- 优化 NVENC 编码器分辨率限制处理
- 支持 16:99:16 和 9:1616:9 双向转换

技术细节:
- 前端: 修复 outSizeMethod 字段为 undefined 的问题
- 后端: 添加 template_name 字段到 WebTopazSettings
- 滤镜: 使用独立的 scale 和 crop 滤镜实现精确转换
- 调试: 增加详细的调试信息便于问题排查
This commit is contained in:
imeepos 2025-08-18 16:46:52 +08:00
parent 44f0b399ec
commit 0a79b24838
3 changed files with 55 additions and 7 deletions

View File

@ -226,6 +226,11 @@ const TopazVideoAIConfigurator: React.FC = () => {
setCurrentTemplate(templateKey);
const template = templates[templateKey];
if (template) {
console.log('Debug: Selected template key:', templateKey);
console.log('Debug: Template name:', template.name);
console.log('Debug: Template description:', template.description);
console.log('Debug: Template settings:', template.settings);
console.log('Debug: Template output settings:', template.settings.output);
setSettings(template.settings as TopazSettings);
}
};
@ -344,7 +349,16 @@ const TopazVideoAIConfigurator: React.FC = () => {
// 转换设置格式为后端期望的格式
const convertSettingsToBackendFormat = (frontendSettings: TopazSettings) => {
console.log('Debug: Converting frontend settings to backend format');
console.log('Debug: frontendSettings.output:', frontendSettings.output);
console.log('Debug: frontendSettings.output.out_size_method:', frontendSettings.output.out_size_method);
// Get template name from current template
const templateName = currentTemplate && templates[currentTemplate] ? templates[currentTemplate].name : undefined;
console.log('Debug: Including template name in conversion:', templateName);
return {
template_name: templateName,
stabilize: {
active: frontendSettings.stabilize.active || false,
smooth: frontendSettings.stabilize.smooth || 50,
@ -385,10 +399,10 @@ const TopazVideoAIConfigurator: React.FC = () => {
},
output: {
active: frontendSettings.output.active || true,
out_size_method: frontendSettings.output.out_size_method || 0,
out_fps: frontendSettings.output.out_fps || 0,
crop_to_fit: frontendSettings.output.crop_to_fit || false,
lock_aspect_ratio: frontendSettings.output.lock_aspect_ratio || false,
out_size_method: (frontendSettings.output as any).outSizeMethod ?? frontendSettings.output.out_size_method ?? 0,
out_fps: (frontendSettings.output as any).outFPS ?? frontendSettings.output.out_fps ?? 0,
crop_to_fit: (frontendSettings.output as any).cropToFit ?? frontendSettings.output.crop_to_fit ?? false,
lock_aspect_ratio: (frontendSettings.output as any).lockAspectRatio ?? frontendSettings.output.lock_aspect_ratio ?? false,
},
hdr: {
active: frontendSettings.hdr?.active || false,

View File

@ -1710,17 +1710,26 @@ impl TopazTemplateManager {
println!("Debug: template.settings.output.out_size_method = {}", template.settings.output.out_size_method);
println!("Debug: template.settings.output.lock_aspect_ratio = {:?}", template.settings.output.lock_aspect_ratio);
// Store aspect ratio conversion info for later use
let mut aspect_ratio_conversion: Option<String> = None;
if template.settings.output.out_size_method == 7 && !template.settings.output.lock_aspect_ratio.unwrap_or(true) {
println!("Debug: Aspect ratio conversion conditions met!");
// For aspect ratio conversion templates, add specific resolution
if template.name.contains("16:9转9:16") {
// Convert 16:9 to 9:16 - typical mobile format
println!("Debug: Adding 16:9 to 9:16 conversion parameters");
tvai_filter.push_str(":w=1080:h=1920");
// Use conservative scale factor to avoid NVENC limits
tvai_filter = tvai_filter.replace(":scale=4", ":scale=2");
// Store aspect ratio conversion filters for later
aspect_ratio_conversion = Some("scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920".to_string());
} else if template.name.contains("9:16转16:9") {
// Convert 9:16 to 16:9 - typical desktop format
println!("Debug: Adding 9:16 to 16:9 conversion parameters");
tvai_filter.push_str(":w=1920:h=1080");
// Use conservative scale factor
tvai_filter = tvai_filter.replace(":scale=4", ":scale=2");
// Store aspect ratio conversion filters for later
aspect_ratio_conversion = Some("scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080".to_string());
} else {
println!("Debug: Template name doesn't match aspect ratio patterns");
}
@ -1762,6 +1771,15 @@ impl TopazTemplateManager {
}
filters.push(tvai_filter);
// Add aspect ratio conversion filters if needed
if let Some(conversion_filters) = aspect_ratio_conversion {
println!("Debug: Adding aspect ratio conversion filters: {}", conversion_filters);
// Split the conversion filters and add them separately
for filter in conversion_filters.split(',') {
filters.push(filter.to_string());
}
}
}
// Apply slow motion/interpolation

View File

@ -37,6 +37,7 @@ pub enum ProcessingMode {
/// Web-friendly TopazSettings structure
#[derive(Debug, Serialize, Deserialize)]
pub struct WebTopazSettings {
pub template_name: Option<String>,
pub stabilize: WebStabilizeSettings,
pub motionblur: WebMotionBlurSettings,
pub slowmo: WebSlowMotionSettings,
@ -412,8 +413,23 @@ impl WebApi {
filter_manager: None,
};
// Use provided template name or determine based on settings
let template_name = web_settings.template_name.clone().unwrap_or_else(|| {
if web_settings.output.out_size_method == 7 && !web_settings.output.lock_aspect_ratio {
// This is likely an aspect ratio conversion template
"16:9转9:16".to_string()
} else {
"Web Generated Template".to_string()
}
});
println!("Debug: Determined template name: '{}'", template_name);
println!("Debug: web_settings.template_name = {:?}", web_settings.template_name);
println!("Debug: web_settings.output.out_size_method = {}", web_settings.output.out_size_method);
println!("Debug: web_settings.output.lock_aspect_ratio = {}", web_settings.output.lock_aspect_ratio);
Ok(TopazTemplate {
name: "Web Generated Template".to_string(),
name: template_name,
description: "Template generated from web interface".to_string(),
author: "Web Interface".to_string(),
save_output_settings: false,