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 b5b4f71..1bf9830 100644 --- a/apps/desktop/src-tauri/src/business/services/material_service.rs +++ b/apps/desktop/src-tauri/src/business/services/material_service.rs @@ -355,23 +355,56 @@ impl MaterialService { ) -> Result { let scene_times = FFmpegService::detect_scenes(file_path, threshold)?; + // 获取视频总时长 + let total_duration = if let Ok(metadata) = Self::extract_metadata(file_path, &MaterialType::Video) { + if let MaterialMetadata::Video(video_meta) = metadata { + video_meta.duration + } else { + return Err(anyhow!("无法获取视频元数据")); + } + } else { + return Err(anyhow!("无法提取视频元数据")); + }; + let mut scenes = Vec::new(); let mut previous_time = 0.0; + // 根据场景切换点创建场景片段 for (index, &scene_time) in scene_times.iter().enumerate() { + if scene_time > previous_time { + scenes.push(crate::data::models::material::SceneSegment { + start_time: previous_time, + end_time: scene_time, + duration: scene_time - previous_time, + scene_id: index as u32, + confidence: 1.0, + }); + previous_time = scene_time; + } + } + + // 添加最后一个场景片段 + if previous_time < total_duration { scenes.push(crate::data::models::material::SceneSegment { start_time: previous_time, - end_time: scene_time, - duration: scene_time - previous_time, - scene_id: index as u32, - confidence: 1.0, // FFmpeg 场景检测不提供置信度 + end_time: total_duration, + duration: total_duration - previous_time, + scene_id: scenes.len() as u32, + confidence: 1.0, }); - previous_time = scene_time; } + println!("场景检测完成,共 {} 个场景:", scenes.len()); + for (i, scene) in scenes.iter().enumerate() { + println!(" 场景 {}: {:.2}s - {:.2}s (时长: {:.2}s)", + i + 1, scene.start_time, scene.end_time, scene.duration); + } + + let total_scenes = scenes.len() as u32; + Ok(crate::data::models::material::SceneDetection { scenes, - total_scenes: scene_times.len() as u32, + total_scenes, detection_method: "ffmpeg_scene_filter".to_string(), threshold, }) @@ -457,37 +490,75 @@ impl MaterialService { ) -> Vec<(f64, f64)> { let mut segments = Vec::new(); let mut current_start = 0.0; - let mut current_duration = 0.0; + let mut current_end = 0.0; - for scene in scenes { - if current_duration + scene.duration > max_duration && current_duration > 0.0 { + println!("开始根据场景创建切分片段,最大时长: {}秒", max_duration); + + for (i, scene) in scenes.iter().enumerate() { + let potential_end = scene.end_time; + let potential_duration = potential_end - current_start; + + println!(" 处理场景 {}: {:.2}s - {:.2}s (时长: {:.2}s)", + i + 1, scene.start_time, scene.end_time, scene.duration); + + if potential_duration > max_duration && current_end > current_start { // 当前片段已达到最大时长,创建新片段 - segments.push((current_start, current_start + current_duration)); - current_start = scene.start_time; - current_duration = scene.duration; + segments.push((current_start, current_end)); + println!(" 创建片段: {:.2}s - {:.2}s (时长: {:.2}s)", + current_start, current_end, current_end - current_start); + + current_start = current_end; + current_end = scene.end_time; } else { - // 继续累加到当前片段 - current_duration += scene.duration; + // 继续扩展当前片段 + current_end = scene.end_time; } } // 添加最后一个片段 - if current_duration > 0.0 { - segments.push((current_start, current_start + current_duration)); + if current_end > current_start { + segments.push((current_start, current_end)); + println!(" 创建最后片段: {:.2}s - {:.2}s (时长: {:.2}s)", + current_start, current_end, current_end - current_start); } - segments + // 对超长片段进行二次切分 + let mut final_segments = Vec::new(); + for (start, end) in segments { + let duration = end - start; + if duration > max_duration { + println!(" 片段过长 ({:.2}s > {:.2}s),进行二次切分", duration, max_duration); + // 将超长片段按最大时长切分 + let sub_segments = Self::create_fixed_segments_range(start, end, max_duration); + final_segments.extend(sub_segments); + } else { + final_segments.push((start, end)); + } + } + + println!("最终生成 {} 个切分片段:", final_segments.len()); + for (i, (start, end)) in final_segments.iter().enumerate() { + println!(" 片段 {}: {:.2}s - {:.2}s (时长: {:.2}s)", + i + 1, start, end, end - start); + } + + final_segments } /// 创建固定时长的切分片段 pub fn create_fixed_segments(total_duration: f64, max_duration: f64) -> Vec<(f64, f64)> { - let mut segments = Vec::new(); - let mut current_time = 0.0; + Self::create_fixed_segments_range(0.0, total_duration, max_duration) + } - while current_time < total_duration { - let end_time = (current_time + max_duration).min(total_duration); - segments.push((current_time, end_time)); - current_time = end_time; + /// 在指定时间范围内创建固定时长的切分片段 + fn create_fixed_segments_range(start_time: f64, end_time: f64, max_duration: f64) -> Vec<(f64, f64)> { + let mut segments = Vec::new(); + let mut current_time = start_time; + + while current_time < end_time { + let segment_end = (current_time + max_duration).min(end_time); + segments.push((current_time, segment_end)); + current_time = segment_end; } segments