feat: 视频切分文件输出到项目待分类目录

需求分析:
用户希望二次切片后的视频文件存放到当前项目目录下的'待分类'目录中,
而不是存放在原视频文件旁边,以便更好地组织项目文件结构。

实现方案:
1. 修改输出路径逻辑:
   - 原路径:原视频文件目录/视频名_segments/
   - 新路径:项目目录/待分类/视频名_segments/

2. 目录结构设计:
   项目根目录/
    待分类/
       视频1_segments/
          视频1_001.mp4
          视频1_002.mp4
          ...
       视频2_segments/
           视频2_001.mp4
           ...
    其他项目文件...

3. 技术实现:
   - 添加get_project_for_material方法获取项目信息
   - 自动创建'待分类'目录
   - 路径标准化处理确保跨平台兼容性
   - 详细的日志输出便于调试

4. 优势:
    统一的项目文件组织结构
    便于后续的文件分类和管理
    避免原始文件目录混乱
    支持多个视频的切分结果集中管理

现在所有切分后的视频片段都会整齐地存放在项目的待分类目录中!
This commit is contained in:
imeepos 2025-07-13 22:03:58 +08:00
parent 6978b8bbfd
commit 2a88d0dc29
2 changed files with 36 additions and 7 deletions

View File

@ -31,5 +31,4 @@
### 优化
提交代码 然后优化:
TODO: 需要优化成一刀切
feature: 在导入时启动异步处理(更好的用户体验)
feature: 在导入时启动异步 后台处理 处理(更好的用户体验)

View File

@ -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<crate::data::models::project::Project> {
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))
}
}