From 2a88d0dc297c75facbcc0bb166290ac94c0cbaaf Mon Sep 17 00:00:00 2001 From: imeepos Date: Sun, 13 Jul 2025 22:03:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=86=E9=A2=91=E5=88=87=E5=88=86?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=BE=93=E5=87=BA=E5=88=B0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=BE=85=E5=88=86=E7=B1=BB=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 需求分析: 用户希望二次切片后的视频文件存放到当前项目目录下的'待分类'目录中, 而不是存放在原视频文件旁边,以便更好地组织项目文件结构。 实现方案: 1. 修改输出路径逻辑: - 原路径:原视频文件目录/视频名_segments/ - 新路径:项目目录/待分类/视频名_segments/ 2. 目录结构设计: 项目根目录/ 待分类/ 视频1_segments/ 视频1_001.mp4 视频1_002.mp4 ... 视频2_segments/ 视频2_001.mp4 ... 其他项目文件... 3. 技术实现: - 添加get_project_for_material方法获取项目信息 - 自动创建'待分类'目录 - 路径标准化处理确保跨平台兼容性 - 详细的日志输出便于调试 4. 优势: 统一的项目文件组织结构 便于后续的文件分类和管理 避免原始文件目录混乱 支持多个视频的切分结果集中管理 现在所有切分后的视频片段都会整齐地存放在项目的待分类目录中! --- 0.1.1.md | 3 +- .../src/business/services/material_service.rs | 40 ++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/0.1.1.md b/0.1.1.md index 9e4c32d..07088a4 100644 --- a/0.1.1.md +++ b/0.1.1.md @@ -31,5 +31,4 @@ ### 优化 提交代码 然后优化: -TODO: 需要优化成一刀切 -feature: 在导入时启动异步处理(更好的用户体验) +feature: 在导入时启动异步 后台处理 处理(更好的用户体验) 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 605b7a1..fbc5b96 100644 --- a/apps/desktop/src-tauri/src/business/services/material_service.rs +++ b/apps/desktop/src-tauri/src/business/services/material_service.rs @@ -425,6 +425,8 @@ impl MaterialService { material: &Material, config: &MaterialProcessingConfig, ) -> Result<()> { + // 首先获取项目信息来确定输出路径 + let project = Self::get_project_for_material(&material.project_id)?; // 第一步:根据场景检测结果进行分镜头切分 let primary_segments = if let Some(scene_detection) = &material.scene_detection { // 使用场景检测结果,每个场景作为一个片段 @@ -446,8 +448,21 @@ impl MaterialService { println!("分镜头切分完成:{} 个片段", primary_segments.len()); println!("二次切分后:{} 个片段", final_segments.len()); - // 创建输出目录 - let output_dir = format!("{}_segments", material.original_path.trim_end_matches(".mp4")); + // 创建输出目录:项目目录/待分类/素材名称_segments + let pending_dir = std::path::Path::new(&project.path).join("待分类"); + + // 确保待分类目录存在 + if !pending_dir.exists() { + std::fs::create_dir_all(&pending_dir) + .map_err(|e| anyhow!("创建待分类目录失败: {}", e))?; + println!("创建待分类目录: {:?}", 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); // 根据配置选择切分模式 let output_files = match config.split_mode { @@ -455,7 +470,7 @@ impl MaterialService { println!("使用快速切分模式(可能有前几秒无画面问题)"); FFmpegService::split_video_fast( &material.original_path, - &output_dir, + &output_dir_str, &final_segments, &material.name.replace(".mp4", ""), )? @@ -464,7 +479,7 @@ impl MaterialService { println!("使用精确切分模式(重新编码,确保画面完整)"); FFmpegService::split_video( &material.original_path, - &output_dir, + &output_dir_str, &final_segments, &material.name.replace(".mp4", ""), )? @@ -473,7 +488,7 @@ impl MaterialService { println!("使用智能切分模式(关键帧对齐)"); FFmpegService::split_video_smart( &material.original_path, - &output_dir, + &output_dir_str, &final_segments, &material.name.replace(".mp4", ""), )? @@ -603,4 +618,19 @@ impl MaterialService { Ok(cleaned_count) } + + /// 获取素材对应的项目信息 + fn get_project_for_material(project_id: &str) -> Result { + use crate::infrastructure::database::Database; + use crate::data::repositories::project_repository::ProjectRepository; + use crate::business::services::project_service::ProjectService; + + // 创建数据库连接 + let db = Database::new()?; + let project_repo = ProjectRepository::new(db.get_connection())?; + + // 获取项目信息 + ProjectService::get_project_by_id(&project_repo, project_id)? + .ok_or_else(|| anyhow!("找不到项目: {}", project_id)) + } }