From ee40fe31cf13b5853e0519d950ef9fd2728e9c8d Mon Sep 17 00:00:00 2001 From: imeepos Date: Sun, 13 Jul 2025 22:07:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E5=88=87=E5=88=86=E8=B7=AF=E5=BE=84=E9=97=AE=E9=A2=98=20-=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3FFmpeg=E8=B7=AF=E5=BE=84=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题分析: 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目录中! --- .../src/business/services/material_service.rs | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/apps/desktop/src-tauri/src/business/services/material_service.rs b/apps/desktop/src-tauri/src/business/services/material_service.rs index fbc5b96..bda742c 100644 --- a/apps/desktop/src-tauri/src/business/services/material_service.rs +++ b/apps/desktop/src-tauri/src/business/services/material_service.rs @@ -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", ""), )?