feat(dedup): 动态抽帧 + 滑动窗口时序匹配 (#1659) #1673
Reference in New Issue
Block a user
Delete Branch "feature/1659-dynamic-keyframe-sliding-window"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Issue #1659: 动态抽帧 + 滑动窗口时序匹配
改动概要
1. 动态抽帧策略 —
detect_keyframe_timestamps()2. 滑动窗口时序匹配 —
find_duplicate_segments()DuplicateSegment(query/target 时间范围 + 平均汉明距离)3. 查重算法升级
duplicate_segments字段4. 删除旧代码
compute_chunk_interval()_average_histogram_similarity()5. 测试
test_dedup_v2.py: 34 个测试覆盖全部新功能关键文件
apps/worker/video_processing/dedup.py— 核心改造tests/unit/test_dedup_v2.py— 新增测试tests/unit/test_dedup_engine.py— 更新断言tests/unit/test_dedup_pure.py— 替换直方图测试tests/unit/test_duplicate_rate.py— 更新期望值tests/unit/test_fingerprint_chunks.py— 移除旧常量测试🚀 预览环境已部署
1418e08fa8tofac80b1f77【阻塞级判定】
📊 审查概览
🔴 阻塞级问题(必须修复)
[apps/worker/video_processing/dedup.py: 130-160] 严重的性能回归:全帧扫描
detect_keyframe_timestamps函数中使用了while True: cap.read()逐帧遍历视频,并对每一帧进行resize、cvtColor和diff计算。对于长视频(如1小时视频,约21.6万帧),这将导致极高的CPU消耗和处理时间,极易导致Worker超时或OOM。旧代码采用固定间隔采样,新代码改为全帧扫描未做降采样处理。[apps/worker/video_processing/dedup.py: 130-160] 逻辑错误:遗漏视频首帧
detect_keyframe_timestamps中,prev_gray初始化为None,只有在prev_gray is not None时才计算差异并添加候选关键帧。这意味着视频的第一帧(timestamp=0)永远不会被添加到candidates中。如果视频开头就是重要场景,该场景会被遗漏,除非后续通过min_frames均匀补充逻辑强行加入(但这仅在总数不足时触发)。candidates,或者在循环内部针对第一帧做特殊处理。[apps/worker/video_processing/dedup.py: 360] 逻辑错误:重复片段平均距离计算偏差
find_duplicate_segments函数计算avg_dist时,是对start到end范围内的所有帧(包括不匹配的 gap 帧)的汉明距离求平均。由于不匹配的帧距离通常很大(> threshold),这会显著拉高avg_distance,导致返回的重复片段相似度指标失真,无法反映真正匹配部分的相似度。avg_dist时应只统计is_match为True的帧的距离,或者确保分母只统计匹配帧数。💡 改进建议(不阻塞合并)
[apps/worker/video_processing/dedup.py: 620-621] 魔法数值未使用常量
check_duplicate、check_batch_duplicate和compute_duplicate_rate中计算combined_score时,直接使用了0.7和0.3,而文件顶部已定义了PHASH_WEIGHT和HISTOGRAM_WEIGHT常量。应统一使用常量以保持一致性。[apps/worker/video_processing/dedup.py: 593-640] 代码重复
check_duplicate和check_batch_duplicate方法中存在大量重复的相似度计算逻辑(计算 min_distances、match_ratio、median_distance、hist_similarity、combined_score)。建议提取一个私有方法_calculate_combined_similarity来复用逻辑。[apps/worker/video_processing/dedup.py: 138] 性能优化建议
detect_keyframe_timestamps的while循环中,使用cap.get(cv2.CAP_PROP_POS_MSEC)获取时间戳。频繁调用cap.get在某些后端(如FFmpeg)上开销较大。建议通过帧索引计数器手动计算时间戳:current_timestamp = frame_idx / fps。[apps/worker/video_processing/dedup.py: 630-640] 兼容性数据处理
chunk_data为空(旧数据)时,构造的existing_chunk_objects中start_time_ms和end_time_ms均为 0。这会导致find_duplicate_segments返回的重复片段中目标时间戳为 0,信息不准确。建议在无法获取时间戳时,根据视频总时长进行均匀估算,而非全部置 0。✅ 良好实践
🤖 由 AI 代码审查机器人自动生成 | 2026-09-03 15:12:10 | 模型:
🗑️ 预览环境已清理
PR #1673 已关闭或合并,对应的预览环境已被清理。