fix: 视频预加载优化+配音时长校验提醒 (#1435) #1435

Merged
auto-approve-bot merged 2 commits from fix/preview-player-v9 into develop 2026-08-19 11:36:02 +08:00
Owner

修复内容

1. 视频播放流畅性优化

  • 强制预加载:所有 video 元素挂载后调用 video.load() 确保浏览器真正开始加载数据
  • canplay 等待机制:片段切换后先检查 readyState >= 3,否则监听 canplay 事件 + 300ms 超时兜底
  • opacity 替代 display:移除 display: none/block 切换,改用 opacity: 0 + pointer-events: none + z-index,保持所有 video 在 DOM 渲染树中,避免浏览器中断预加载

2. 配音时长校验提醒

  • GeneratePage:根据已选素材和模板计算 totalVideoDuration
  • Step5VoiceSelect
    • 配音时长 < 视频总时长时,卡片上显示红色「⚠ 时长不足」标签
    • 选中时长不足的配音时弹出 Modal 确认:「仍要使用」/「重新选择」
    • totalVideoDuration 未传入或为 0 时不做校验

涉及文件

  • useSegmentScheduler.ts
  • FrontendPreviewPlayer.tsx
  • GeneratePage.tsx
  • GenerateStepContent.tsx
  • Step5VoiceSelect.tsx
## 修复内容 ### 1. 视频播放流畅性优化 - **强制预加载**:所有 video 元素挂载后调用 `video.load()` 确保浏览器真正开始加载数据 - **canplay 等待机制**:片段切换后先检查 `readyState >= 3`,否则监听 `canplay` 事件 + 300ms 超时兜底 - **opacity 替代 display**:移除 `display: none/block` 切换,改用 `opacity: 0 + pointer-events: none + z-index`,保持所有 video 在 DOM 渲染树中,避免浏览器中断预加载 ### 2. 配音时长校验提醒 - **GeneratePage**:根据已选素材和模板计算 `totalVideoDuration` - **Step5VoiceSelect**: - 配音时长 < 视频总时长时,卡片上显示红色「⚠ 时长不足」标签 - 选中时长不足的配音时弹出 Modal 确认:「仍要使用」/「重新选择」 - `totalVideoDuration` 未传入或为 0 时不做校验 ### 涉及文件 - `useSegmentScheduler.ts` - `FrontendPreviewPlayer.tsx` - `GeneratePage.tsx` - `GenerateStepContent.tsx` - `Step5VoiceSelect.tsx`
xiaoxia added 1 commit 2026-08-19 11:18:41 +08:00
fix: 视频预加载优化+配音时长校验提醒
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
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 / Check if frontend-only change (pull_request) Successful in 52s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m33s
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Failing after 1m43s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 50s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m55s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 1m5s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m9s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m10s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m12s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m28s
CI/CD Pipeline / Validate - Code Quality (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
2c03ff05f2
1. useSegmentScheduler: 挂载后强制调用 video.load() 预加载所有片段
2. useSegmentScheduler: 片段切换时先检查 readyState>=3 再 play(),否则监听 canplay + 300ms 超时兜底
3. FrontendPreviewPlayer: display:none/block 改为 opacity:0/1 + pointer-events + z-index,保持所有 video 在渲染树中
4. GeneratePage: 计算 totalVideoDuration 传给配音选择组件
5. Step5VoiceSelect: 新增 totalVideoDuration prop,配音时长不足时显示红色警告标签,选中时弹出 Modal 确认

🚀 预览环境已部署

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

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

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

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

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

【阻塞级判定】

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

📊 审查概览

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

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

  1. [apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 193-204] 严重资源泄漏与逻辑错误
    • 问题类型:逻辑bug / 性能问题
    • 问题描述:在 tick 函数(由 requestAnimationFrame 驱动)中,当切换到下一个视频片段时,如果 nextVideo.readyState < 3,代码会添加 setTimeoutaddEventListener。由于 tick 会在动画帧中持续调用,在视频加载完成前的每一帧都会重复执行这段代码,导致向同一个 video 元素绑定数十甚至上百个相同的 canplay 监听器和定时器。这不仅会造成严重的内存泄漏和性能下降,还会导致视频加载后触发多次 play() 调用。
    • 修改建议:必须增加状态标记(例如使用 SetRef 记录正在等待加载的 video 索引),确保对同一个 video 的 canplay 监听器和超时逻辑只注册一次。或者仅在片段切换的瞬间执行一次等待逻辑,而不是在 RAF 循环中反复判断。

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

  1. [apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 316-323] 强制全量加载可能影响性能

    • 具体内容:在 useEffect 中遍历所有 video 元素并调用 .load()。如果 segments 数量较多(例如长视频包含几十个片段),这将同时发起大量网络请求,导致带宽拥塞和页面卡顿。建议改为仅预加载当前片段及后续的 1-2 个片段(懒加载策略),或者仅在视频元素首次挂载时加载。
  2. [apps/web/src/pages/generate/GeneratePage.tsx: 115] 魔法数字缺乏解释

    • 具体内容:代码中存在硬编码的魔法数字 30(默认时长)和 10(兜底时长)。建议将其提取为常量并添加注释,说明这些数值的业务含义(例如:DEFAULT_ASSET_DURATION = 30),以提高代码可读性和可维护性。

良好实践

  • Step5VoiceSelect.tsx 中增加了配音时长与视频时长的校验逻辑,并通过 Modal 给用户明确的提示,有效提升了用户体验,避免了因时长不匹配导致的播放事故。
  • GeneratePage.tsx 中使用 useMemo 计算 totalVideoDuration,依赖项准确,避免了不必要的重复计算。

🤖 由 AI 代码审查机器人自动生成 | 2026-08-19 03:20:20 | 模型:

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:1 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:2 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 193-204] 严重资源泄漏与逻辑错误** - 问题类型:逻辑bug / 性能问题 - 问题描述:在 `tick` 函数(由 `requestAnimationFrame` 驱动)中,当切换到下一个视频片段时,如果 `nextVideo.readyState < 3`,代码会添加 `setTimeout` 和 `addEventListener`。由于 `tick` 会在动画帧中持续调用,在视频加载完成前的每一帧都会重复执行这段代码,导致向同一个 video 元素绑定数十甚至上百个相同的 `canplay` 监听器和定时器。这不仅会造成严重的内存泄漏和性能下降,还会导致视频加载后触发多次 `play()` 调用。 - 修改建议:必须增加状态标记(例如使用 `Set` 或 `Ref` 记录正在等待加载的 video 索引),确保对同一个 video 的 `canplay` 监听器和超时逻辑只注册一次。或者仅在片段切换的瞬间执行一次等待逻辑,而不是在 RAF 循环中反复判断。 ### 💡 改进建议(不阻塞合并) 1. **[apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 316-323] 强制全量加载可能影响性能** - 具体内容:在 `useEffect` 中遍历所有 video 元素并调用 `.load()`。如果 `segments` 数量较多(例如长视频包含几十个片段),这将同时发起大量网络请求,导致带宽拥塞和页面卡顿。建议改为仅预加载当前片段及后续的 1-2 个片段(懒加载策略),或者仅在视频元素首次挂载时加载。 2. **[apps/web/src/pages/generate/GeneratePage.tsx: 115] 魔法数字缺乏解释** - 具体内容:代码中存在硬编码的魔法数字 `30`(默认时长)和 `10`(兜底时长)。建议将其提取为常量并添加注释,说明这些数值的业务含义(例如:`DEFAULT_ASSET_DURATION = 30`),以提高代码可读性和可维护性。 ### ✅ 良好实践 - `Step5VoiceSelect.tsx` 中增加了配音时长与视频时长的校验逻辑,并通过 Modal 给用户明确的提示,有效提升了用户体验,避免了因时长不匹配导致的播放事故。 - `GeneratePage.tsx` 中使用 `useMemo` 计算 `totalVideoDuration`,依赖项准确,避免了不必要的重复计算。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-19 03:20:20 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
xiaoxia added 1 commit 2026-08-19 11:24:41 +08:00
fix: 修复 ESLint 警告 (react-hooks/exhaustive-deps)
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 / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
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 / Check if frontend-only change (pull_request) Successful in 33s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m51s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m20s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m12s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m20s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m24s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m20s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m4s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m50s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 6m36s
CI/CD Pipeline / Integration Tests (pull_request) Has been skipped
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 / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 6s
AI Code Review / AI Code Review (pull_request) Successful in 7m3s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 57s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m19s
bd1baaaee3
auto-approve-bot approved these changes 2026-08-19 11:27:44 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-08-19 11:27:45 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot merged commit 938b9d3529 into develop 2026-08-19 11:36:02 +08:00
auto-approve-bot deleted branch fix/preview-player-v9 2026-08-19 11:36:02 +08:00

🗑️ 预览环境已清理

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

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

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