feat: 素材分配顺序随机打乱 + MediaKit SceneChange智能选帧 #1618

Merged
xiaoxia merged 1 commits from feat/scene-change-random-shuffle into develop 2026-09-01 21:17:33 +08:00
Owner

变更内容

第一部分:素材分配顺序随机打乱

  • create_clips_from_assets_editor 中 segments 处理顺序通过 random.shuffle 随机化
  • clips_data 最终按原始 segment order 排序后返回
  • 打乱的是「分配顺序」,不是「播放顺序」

第二部分:MediaKit SceneChange 智能选帧

  • mediakit_client.py 新增 detect_scene_changes 方法
    • SceneChange 策略优先
    • 失败自动降级到 TimeInterval(5秒间隔)
    • MediaKit 不可用返回 None
  • _update_mediakit_recommendations_async 后台任务改用 SceneChange
    • 对每个素材检测镜头切换点,构建镜头段
    • 各片段优先从不同镜头段选取起始时间
    • analyze_videos 保留为 fallback
    • 所有方式失败 → 保持随机 start_time

降级策略(全覆盖)

  1. MediaKit 不可用 → 保持现有随机 start_time
  2. SceneChange 失败 → 退回 TimeInterval 策略
  3. TimeInterval 也失败 → 回退 analyze_videos
  4. 所有都失败 → 保持随机 start_time,不影响视频生成

测试

  • 新增 tests/unit/test_scene_change_shuffle.py(12个测试用例)
  • 更新 test_editor_clips_random_start.py 适配 shuffle 逻辑
  • 全部 108 个相关测试通过
  • ruff check 通过
## 变更内容 ### 第一部分:素材分配顺序随机打乱 - `create_clips_from_assets_editor` 中 segments 处理顺序通过 `random.shuffle` 随机化 - `clips_data` 最终按原始 segment order 排序后返回 - 打乱的是「分配顺序」,不是「播放顺序」 ### 第二部分:MediaKit SceneChange 智能选帧 - `mediakit_client.py` 新增 `detect_scene_changes` 方法 - SceneChange 策略优先 - 失败自动降级到 TimeInterval(5秒间隔) - MediaKit 不可用返回 None - `_update_mediakit_recommendations_async` 后台任务改用 SceneChange - 对每个素材检测镜头切换点,构建镜头段 - 各片段优先从不同镜头段选取起始时间 - `analyze_videos` 保留为 fallback - 所有方式失败 → 保持随机 start_time ### 降级策略(全覆盖) 1. MediaKit 不可用 → 保持现有随机 start_time 2. SceneChange 失败 → 退回 TimeInterval 策略 3. TimeInterval 也失败 → 回退 analyze_videos 4. 所有都失败 → 保持随机 start_time,不影响视频生成 ### 测试 - 新增 `tests/unit/test_scene_change_shuffle.py`(12个测试用例) - 更新 `test_editor_clips_random_start.py` 适配 shuffle 逻辑 - 全部 108 个相关测试通过 - ruff check 通过
xiaoxia added 1 commit 2026-09-01 21:17:24 +08:00
feat: 素材分配顺序随机打乱 + MediaKit SceneChange智能选帧
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m26s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Failing after 5m45s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Has been cancelled
CI/CD Pipeline / Check if frontend-only change (push) Has been cancelled
CI/CD Pipeline / Validate - Style (push) Has been cancelled
CI/CD Pipeline / Validate - Security (push) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
CI/CD Pipeline / PR Build API Image (push) Has been cancelled
CI/CD Pipeline / PR Build Web Image (push) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (push) Has been cancelled
CI/CD Pipeline / Check push changed paths (push) Has been cancelled
CI/CD Pipeline / Build Staging API Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
PR Automation / Auto Approve on CI Green (pull_request) Successful in 6m46s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m35s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 3m13s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Waiting to run
CI/CD Pipeline / Integration Tests (pull_request) Successful in 3m53s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 6m0s
CI/CD Pipeline / Validate - Style (pull_request) Failing after 7m27s
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 7m47s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 6m38s
CI/CD Pipeline / Unit Tests (pull_request) Failing after 16m35s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 29m28s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 1s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
827d8aafe5
1. 素材分配顺序随机打乱
   - segments 处理顺序通过 random.shuffle 随机化
   - clips_data 最终按原始 segment order 排序返回
   - 打乱的是分配顺序,不影响播放顺序

2. MediaKit SceneChange 智能选帧
   - mediakit_client.py 新增 detect_scene_changes 方法
   - SceneChange 优先,失败降级到 TimeInterval(5秒间隔)
   - 后台任务 _update_mediakit_recommendations_async 改用 SceneChange
   - 各片段优先从不同镜头段选取起始时间
   - analyze_videos 保留为 fallback
   - 所有降级路径:MediaKit不可用/SceneChange失败 → 保持随机start_time

3. 测试
   - 新增 tests/unit/test_scene_change_shuffle.py (12个测试用例)
   - 更新 test_editor_clips_random_start.py 适配 shuffle 逻辑
   - 全部 108 个相关测试通过
   - ruff check 通过
xiaoxia merged commit 827d8aafe5 into develop 2026-09-01 21:17:33 +08:00
xiaoxia deleted branch feat/scene-change-random-shuffle 2026-09-01 21:17:34 +08:00
Collaborator

【阻塞级判定】

  • 是否存在阻塞级问题:是
  • 阻塞级问题数量:1 个

📊 审查概览

  • 整体评价:需修改
  • 建议级问题数量:1 个

🔴 阻塞级问题(必须修复)

  1. [apps/api/app/api/routes/templates_editor/clips.py: 906-1085] 变量未定义导致运行时崩溃
    • 问题类型:逻辑bug
    • 问题描述:在 _update_mediakit_recommendations_async 函数的重构中,原有的 with SessionLocal() as db: 上下文管理器以及 asset_repoplan_svc 的初始化代码被移除,但函数体中仍然使用了这些未定义的变量(如第 963 行左右的 plan_svc.get_clips 和第 981 行左右的 asset_repo.find_by_ids)。这将导致函数运行时抛出 NameError
    • 修改建议:恢复数据库会话管理代码及服务初始化逻辑,确保在使用 dbasset_repoplan_svc 之前已正确实例化。例如:
      with SessionLocal() as db:
          asset_repo = SQLAlchemyAssetRepository(db)
          plan_svc = EditPlanService(db)
          # ... 原有业务逻辑 ...
      

💡 改进建议(不阻塞合并)

  1. [apps/api/app/api/routes/templates_editor/clips.py: ~1000] 性能优化建议
    • 具体内容:在 _update_mediakit_recommendations_async 函数中,_get_other_segments 函数定义在循环内部,且在遍历 asset_clips 的内层循环中被反复调用。该函数每次调用都会重新遍历 clips_by_asset 并进行集合合并操作,导致时间复杂度接近 O(N^2)。虽然单个视频的片段数通常不多,但建议将历史区间和其他片段的公共部分提取到循环外计算,以提升性能。

良好实践

  • 引入了场景切换检测逻辑,并设计了合理的降级策略(SceneChange -> TimeInterval -> Random),增强了系统的鲁棒性。
  • 新增的 _build_scene_segments_pick_start_in_scene_segment 辅助函数职责单一,逻辑清晰。
  • 单元测试 test_scene_change_shuffle.py 覆盖了新增的随机打乱和场景分配逻辑,测试用例编写较为充分。

🤖 由 AI 代码审查机器人自动生成 | 2026-09-01 13:23:11 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:1 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/api/app/api/routes/templates_editor/clips.py: 906-1085] 变量未定义导致运行时崩溃** - 问题类型:逻辑bug - 问题描述:在 `_update_mediakit_recommendations_async` 函数的重构中,原有的 `with SessionLocal() as db:` 上下文管理器以及 `asset_repo` 和 `plan_svc` 的初始化代码被移除,但函数体中仍然使用了这些未定义的变量(如第 963 行左右的 `plan_svc.get_clips` 和第 981 行左右的 `asset_repo.find_by_ids`)。这将导致函数运行时抛出 `NameError`。 - 修改建议:恢复数据库会话管理代码及服务初始化逻辑,确保在使用 `db`、`asset_repo` 和 `plan_svc` 之前已正确实例化。例如: ```python with SessionLocal() as db: asset_repo = SQLAlchemyAssetRepository(db) plan_svc = EditPlanService(db) # ... 原有业务逻辑 ... ``` ### 💡 改进建议(不阻塞合并) 1. **[apps/api/app/api/routes/templates_editor/clips.py: ~1000] 性能优化建议** - 具体内容:在 `_update_mediakit_recommendations_async` 函数中,`_get_other_segments` 函数定义在循环内部,且在遍历 `asset_clips` 的内层循环中被反复调用。该函数每次调用都会重新遍历 `clips_by_asset` 并进行集合合并操作,导致时间复杂度接近 O(N^2)。虽然单个视频的片段数通常不多,但建议将历史区间和其他片段的公共部分提取到循环外计算,以提升性能。 ### ✅ 良好实践 - 引入了场景切换检测逻辑,并设计了合理的降级策略(SceneChange -> TimeInterval -> Random),增强了系统的鲁棒性。 - 新增的 `_build_scene_segments` 和 `_pick_start_in_scene_segment` 辅助函数职责单一,逻辑清晰。 - 单元测试 `test_scene_change_shuffle.py` 覆盖了新增的随机打乱和场景分配逻辑,测试用例编写较为充分。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-09-01 13:23:11 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->

🚀 预览环境已部署

项目 详情
PR号 #1618
预览链接 https://pr-1618.preview.xiaoxiajianji.com
API环境 staging

💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。

🔄 每次提交新代码后预览环境会自动更新。

🗑️ PR 关闭或合并后,预览环境会自动清理。

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1618 | | 预览链接 | [https://pr-1618.preview.xiaoxiajianji.com](https://pr-1618.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。

🗑️ 预览环境已清理

PR #1618 已关闭或合并,对应的预览环境已被清理。

如有需要,可以重新打开 PR 来重新生成预览环境。

🗑️ **预览环境已清理** PR #1618 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Sign in to join this conversation.