fix: 修复预览播放器视频无法播放和标题不显示 #1423

Closed
xiaoxia wants to merge 2 commits from fix/preview-player-playback-and-title into develop
Owner

修复内容

问题1:视频无法播放

现象:点播放按钮没反应,视频区域全黑

根因

  • useSegmentScheduler.play()switchToSegment() 后立即调用 video.play()
  • switchToSegment 设置 video.src 后需要等待 loadedmetadata 事件
  • video.play() 在视频未加载完成时调用会失败

修复

  • switchToSegment() 返回 Promise,在 loadedmetadata 后 resolve
  • play() 使用 await switchToSegment(0) 等待加载完成后再调用 video.play()
  • 添加调试日志:打印 videoUrl、加载错误

问题2:标题不显示

现象:选了标题样式预设,预览区看不到标题文字

根因

  • TitleOverlaytitle 为空时返回 null
  • PreviewVideoPanel 的条件 {hasTitle && ...} 导致标题为空时不渲染

修复

  • 标题为空时显示占位文本"标题预览"
  • 始终渲染 TitleOverlay,让用户能看到样式效果

修改的文件

  • useSegmentScheduler.ts:switchToSegment 返回 Promise,添加错误日志
  • PreviewVideoPanel.tsx:标题为空显示占位文本
  • FrontendPreviewPlayer.tsx:添加 videoUrl 调试日志
## 修复内容 ### 问题1:视频无法播放 **现象**:点播放按钮没反应,视频区域全黑 **根因**: - `useSegmentScheduler.play()` 在 `switchToSegment()` 后立即调用 `video.play()` - 但 `switchToSegment` 设置 `video.src` 后需要等待 `loadedmetadata` 事件 - `video.play()` 在视频未加载完成时调用会失败 **修复**: - `switchToSegment()` 返回 Promise,在 `loadedmetadata` 后 resolve - `play()` 使用 `await switchToSegment(0)` 等待加载完成后再调用 `video.play()` - 添加调试日志:打印 videoUrl、加载错误 ### 问题2:标题不显示 **现象**:选了标题样式预设,预览区看不到标题文字 **根因**: - `TitleOverlay` 在 `title` 为空时返回 `null` - `PreviewVideoPanel` 的条件 `{hasTitle && ...}` 导致标题为空时不渲染 **修复**: - 标题为空时显示占位文本"标题预览" - 始终渲染 `TitleOverlay`,让用户能看到样式效果 ## 修改的文件 - `useSegmentScheduler.ts`:switchToSegment 返回 Promise,添加错误日志 - `PreviewVideoPanel.tsx`:标题为空显示占位文本 - `FrontendPreviewPlayer.tsx`:添加 videoUrl 调试日志
xiaoxia added 1 commit 2026-08-18 14:58:08 +08:00
fix: 修复预览播放器视频无法播放和标题不显示
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
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 / 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 38s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m1s
CI/CD Pipeline / PR Build API Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m56s
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m23s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m34s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 3m16s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 2m50s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m30s
AI Code Review / AI Code Review (pull_request) Failing after 4m5s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m29s
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
608a75ea15
问题1:视频无法播放
- useSegmentScheduler.play() 在 switchToSegment 后立即调用 video.play()
- 但 switchToSegment 设置 src 后需要等待 loadedmetadata 事件
- 修复:switchToSegment 返回 Promise,play() 等待加载完成后再播放
- 添加调试日志:打印 videoUrl、加载错误,方便排查 URL 问题

问题2:标题不显示
- TitleOverlay 在 title 为空时返回 null,不渲染任何内容
- PreviewVideoPanel 的条件 {hasTitle && ...} 导致标题为空时不显示
- 修复:标题为空时显示占位文本标题预览
- 始终渲染 TitleOverlay,让用户能看到样式效果

🚀 预览环境已部署

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

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

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

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

🚀 **预览环境已部署** | 项目 | 详情 | |------|------| | PR号 | #1423 | | 预览链接 | [https://pr-1423.preview.xiaoxiajianji.com](https://pr-1423.preview.xiaoxiajianji.com) | | API环境 | staging | > 💡 预览环境使用 staging API 数据,请勿在预览环境中操作重要数据。 > > 🔄 每次提交新代码后预览环境会自动更新。 > > 🗑️ PR 关闭或合并后,预览环境会自动清理。
xiaoxia added 1 commit 2026-08-18 15:04:22 +08:00
style: prettier format
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 44s
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
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m6s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m57s
AI Code Review / AI Code Review (pull_request) Failing after 1m57s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m58s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m5s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m21s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m8s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m57s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m30s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 6m31s
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
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m10s
CI/CD Pipeline / CI Gate (pull_request) Successful in 42s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 2m12s
4456c54f8c
Collaborator

【阻塞级判定】

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

📊 审查概览

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

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

  1. [apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 194] 切换片段时的竞态条件与时间状态冲突

    • 问题类型:逻辑bug
    • 问题描述:在 tick 函数中调用 switchToSegment(nextIndex) 时未使用 await 等待其完成。switchToSegment 内部会在 loadedmetadata 事件中将 video.currentTime 设置为 seg.startTime(片段开始时间),而 tick 函数在调用后会立即计算并设置 setCurrentTime(accumulatedTime)(全局累积时间)。这会导致视频播放时间在“片段开始”和“全局时间”之间反复跳动。此外,由于未等待 Promise 解析,requestAnimationFrame 驱动的 tick 循环可能会在视频加载期间多次触发,导致逻辑混乱。
    • 修改建议:应将 switchToSegment 调用改为 await switchToSegment(nextIndex),并确保 tick 函数正确处理异步状态,或者在切换期间引入 isSwitching 状态锁,防止在加载过程中重复更新时间。
  2. [apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 136] 事件监听器未清理导致内存泄漏与重复执行

    • 问题类型:逻辑bug
    • 问题描述:在 switchToSegment 函数中,每次调用都会向 video 元素添加新的 loadedmetadataerror 事件监听器,但在添加新监听器前未移除旧监听器。如果该函数被快速连续调用(例如用户快速拖动进度条或 tick 函数频繁触发),会导致监听器堆积。当视频最终加载完成或报错时,所有堆积的监听器都会被触发,导致 resolve() 被多次调用,video.currentTime 被多次设置,引发不可预期的行为。
    • 修改建议:在 switchToSegment 开始时,移除之前绑定的监听器(可以使用具名函数并在闭包中保存引用,或者使用 AbortController),确保同一事件只有一个处理逻辑。

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

  1. [apps/web/src/pages/generate/components/FrontendPreviewPlayer.tsx: 57] 生产环境残留调试代码

    • 具体内容:代码中包含 console.log(...) 调试语句,建议在合并到主分支前移除,或使用统一的日志工具进行条件输出。
  2. [apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 119] 空 URL 处理逻辑潜在误导

    • 具体内容:当 videoUrl 为空时,代码执行了 resolve() 并返回。这会让调用方认为切换操作已成功完成,但实际上并未加载视频。建议在 URL 无效时 reject(new Error(...)),以便调用方(如 tickplay)能够捕获错误并停止播放,而不是继续执行后续逻辑。

良好实践

  • switchToSegment 中增加了对 videoUrl 有效性及 URL 格式的校验,有助于早期发现数据问题。
  • switchToSegment 改造为异步 Promise 形式,使得调用方可以更精确地控制加载时序(尽管当前 tick 中的使用方式存在 bug)。

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

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:2 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:2 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 194] 切换片段时的竞态条件与时间状态冲突** - 问题类型:逻辑bug - 问题描述:在 `tick` 函数中调用 `switchToSegment(nextIndex)` 时未使用 `await` 等待其完成。`switchToSegment` 内部会在 `loadedmetadata` 事件中将 `video.currentTime` 设置为 `seg.startTime`(片段开始时间),而 `tick` 函数在调用后会立即计算并设置 `setCurrentTime(accumulatedTime)`(全局累积时间)。这会导致视频播放时间在“片段开始”和“全局时间”之间反复跳动。此外,由于未等待 Promise 解析,`requestAnimationFrame` 驱动的 `tick` 循环可能会在视频加载期间多次触发,导致逻辑混乱。 - 修改建议:应将 `switchToSegment` 调用改为 `await switchToSegment(nextIndex)`,并确保 `tick` 函数正确处理异步状态,或者在切换期间引入 `isSwitching` 状态锁,防止在加载过程中重复更新时间。 2. **[apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 136] 事件监听器未清理导致内存泄漏与重复执行** - 问题类型:逻辑bug - 问题描述:在 `switchToSegment` 函数中,每次调用都会向 `video` 元素添加新的 `loadedmetadata` 和 `error` 事件监听器,但在添加新监听器前未移除旧监听器。如果该函数被快速连续调用(例如用户快速拖动进度条或 `tick` 函数频繁触发),会导致监听器堆积。当视频最终加载完成或报错时,所有堆积的监听器都会被触发,导致 `resolve()` 被多次调用,`video.currentTime` 被多次设置,引发不可预期的行为。 - 修改建议:在 `switchToSegment` 开始时,移除之前绑定的监听器(可以使用具名函数并在闭包中保存引用,或者使用 `AbortController`),确保同一事件只有一个处理逻辑。 ### 💡 改进建议(不阻塞合并) 1. **[apps/web/src/pages/generate/components/FrontendPreviewPlayer.tsx: 57] 生产环境残留调试代码** - 具体内容:代码中包含 `console.log(...)` 调试语句,建议在合并到主分支前移除,或使用统一的日志工具进行条件输出。 2. **[apps/web/src/pages/generate/hooks/useSegmentScheduler.ts: 119] 空 URL 处理逻辑潜在误导** - 具体内容:当 `videoUrl` 为空时,代码执行了 `resolve()` 并返回。这会让调用方认为切换操作已成功完成,但实际上并未加载视频。建议在 URL 无效时 `reject(new Error(...))`,以便调用方(如 `tick` 或 `play`)能够捕获错误并停止播放,而不是继续执行后续逻辑。 ### ✅ 良好实践 - 在 `switchToSegment` 中增加了对 `videoUrl` 有效性及 URL 格式的校验,有助于早期发现数据问题。 - 将 `switchToSegment` 改造为异步 Promise 形式,使得调用方可以更精确地控制加载时序(尽管当前 `tick` 中的使用方式存在 bug)。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-18 07:06:19 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->
auto-approve-bot approved these changes 2026-08-18 15:07:21 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
auto-approve-bot approved these changes 2026-08-18 15:07:21 +08:00
auto-approve-bot left a comment
Collaborator

CI全绿,自动审批通过。

CI全绿,自动审批通过。
xiaoxia closed this pull request 2026-08-18 15:10:32 +08:00

🗑️ 预览环境已清理

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

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

🗑️ **预览环境已清理** PR #1423 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
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 44s
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
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 1m6s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m57s
AI Code Review / AI Code Review (pull_request) Failing after 1m57s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m58s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m5s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m21s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m8s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m57s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 2m30s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 6m31s
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
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 1m10s
CI/CD Pipeline / CI Gate (pull_request) Successful in 42s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 2m12s

Pull request closed

Sign in to join this conversation.