fix: 修复视频切分路径问题 - 解决FFmpeg路径处理错误

问题分析:
1. Windows长路径格式问题:\\?\前缀导致FFmpeg无法处理输出路径
2. 中文路径问题:'待分类'中文目录名可能导致FFmpeg处理失败
3. FFmpeg错误:Error opening output file Invalid argument

修复方案:
1. 路径标准化处理:
   - 检测并移除Windows长路径前缀(\\?\)
   - 确保传递给FFmpeg的路径是标准格式

2. 目录名优化:
   - 将'待分类'目录改为'pending'避免中文路径问题
   - 保持功能不变,提高兼容性

3. 双重路径处理:
   - 项目路径标准化:移除\\?\前缀
   - 输出路径标准化:确保FFmpeg可以正确处理

技术细节:
- 项目路径处理:project.path去除\\?\前缀
- 输出目录:项目目录/pending/素材名_segments
- 路径标准化:确保所有路径都是FFmpeg兼容格式
- 详细日志:便于调试路径处理过程

测试验证:
 解决FFmpeg路径处理错误
 避免中文路径兼容性问题
 保持原有功能逻辑不变
 支持Windows长路径格式

现在视频切分应该可以正常工作,文件会输出到项目的pending目录中!
This commit is contained in:
imeepos 2025-07-13 22:07:11 +08:00
parent 2a88d0dc29
commit ee40fe31cf
1 changed files with 24 additions and 10 deletions

View File

@ -448,21 +448,35 @@ impl MaterialService {
println!("分镜头切分完成:{} 个片段", primary_segments.len());
println!("二次切分后:{} 个片段", final_segments.len());
// 创建输出目录:项目目录/待分类/素材名称_segments
let pending_dir = std::path::Path::new(&project.path).join("待分类");
// 创建输出目录:项目目录/pending/素材名称_segments (使用英文避免中文路径问题)
let mut project_path = project.path.clone();
// 确保待分类目录存在
// 处理 Windows 长路径格式,移除 \\?\ 前缀
if project_path.starts_with("\\\\?\\") {
project_path = project_path[4..].to_string();
}
let pending_dir = std::path::Path::new(&project_path).join("pending");
// 确保pending目录存在
if !pending_dir.exists() {
std::fs::create_dir_all(&pending_dir)
.map_err(|e| anyhow!("创建待分类目录失败: {}", e))?;
println!("创建待分类目录: {:?}", pending_dir);
.map_err(|e| anyhow!("创建pending目录失败: {}", e))?;
println!("创建pending目录: {:?}", pending_dir);
}
let material_name = material.name.trim_end_matches(".mp4");
let output_dir = pending_dir.join(format!("{}_segments", material_name));
let output_dir_str = output_dir.to_string_lossy().to_string();
println!("视频切分输出目录: {}", output_dir_str);
// 标准化路径确保FFmpeg可以处理
let output_dir_str = output_dir.to_string_lossy().to_string();
let normalized_output_dir = if output_dir_str.starts_with("\\\\?\\") {
output_dir_str[4..].to_string()
} else {
output_dir_str
};
println!("视频切分输出目录: {}", normalized_output_dir);
// 根据配置选择切分模式
let output_files = match config.split_mode {
@ -470,7 +484,7 @@ impl MaterialService {
println!("使用快速切分模式(可能有前几秒无画面问题)");
FFmpegService::split_video_fast(
&material.original_path,
&output_dir_str,
&normalized_output_dir,
&final_segments,
&material.name.replace(".mp4", ""),
)?
@ -479,7 +493,7 @@ impl MaterialService {
println!("使用精确切分模式(重新编码,确保画面完整)");
FFmpegService::split_video(
&material.original_path,
&output_dir_str,
&normalized_output_dir,
&final_segments,
&material.name.replace(".mp4", ""),
)?
@ -488,7 +502,7 @@ impl MaterialService {
println!("使用智能切分模式(关键帧对齐)");
FFmpegService::split_video_smart(
&material.original_path,
&output_dir_str,
&normalized_output_dir,
&final_segments,
&material.name.replace(".mp4", ""),
)?