fix: Canvas description缓存+关键帧容错+data字段修正 #1443

Closed
xiaoxia wants to merge 1 commits from fix/canvas-description-cache-and-keyframe into develop
Owner

修复内容

Fix 1:description 缓存

  • 添加 descriptionCache ref(Map<string, ArrayBuffer>
  • demuxSegment 中,如果当前分片提取不到 description,从缓存中获取(后续分片可能不含 moov box)
  • 提取到 description 后缓存起来供后续分片使用

Fix 2:调试日志

  • decodeSegmentconfigure 调用前添加日志,输出 codec、description 是否有值、byteLength 等

Fix 3:EncodedVideoChunk data 字段

  • sample.data.buffer as ArrayBuffersample.data
  • Uint8Array.buffer 可能包含额外的 ArrayBuffer 视图偏移,直接传 sample.data 更安全

Fix 4:关键帧容错

  • 跳过第一个 sync sample 之前的所有非关键帧
  • 避免 A key frame is required after configure() 错误

验证标准

  1. 控制台 [useCanvasPlayer] configure: 日志显示 description 有值
  2. HEVC/H.265 素材 Canvas 播放画面正常(不再黑屏)
  3. 控制台无 [useCanvasPlayer] Decode chunk error 报错
  4. npm run build 无 TS 报错
## 修复内容 ### Fix 1:description 缓存 - 添加 `descriptionCache` ref(`Map<string, ArrayBuffer>`) - `demuxSegment` 中,如果当前分片提取不到 description,从缓存中获取(后续分片可能不含 moov box) - 提取到 description 后缓存起来供后续分片使用 ### Fix 2:调试日志 - `decodeSegment` 的 `configure` 调用前添加日志,输出 codec、description 是否有值、byteLength 等 ### Fix 3:EncodedVideoChunk data 字段 - `sample.data.buffer as ArrayBuffer` → `sample.data` - `Uint8Array.buffer` 可能包含额外的 ArrayBuffer 视图偏移,直接传 `sample.data` 更安全 ### Fix 4:关键帧容错 - 跳过第一个 sync sample 之前的所有非关键帧 - 避免 `A key frame is required after configure()` 错误 ## 验证标准 1. 控制台 `[useCanvasPlayer] configure:` 日志显示 description 有值 2. HEVC/H.265 素材 Canvas 播放画面正常(不再黑屏) 3. 控制台无 `[useCanvasPlayer] Decode chunk error` 报错 4. `npm run build` 无 TS 报错
xiaoxia added 1 commit 2026-08-19 18:06:48 +08:00
fix: Canvas description缓存+关键帧容错+data字段修正
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 / Build Staging API 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 40s
AI Code Review / AI Code Review (pull_request) Failing after 1m58s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m58s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m14s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m17s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 20s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m55s
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 Approve on CI Green (pull_request) Successful in 3m26s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 58s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m48s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 2m48s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 4m34s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 9m57s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (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
94ea579df3
- 添加 descriptionCache ref,从第一个分片提取后缓存供后续分片使用
- configure 前添加调试日志确认 description 是否正确传递
- EncodedVideoChunk data 字段:sample.data.buffer → sample.data
- 添加关键帧容错:跳过第一个 sync 之前的非关键帧
- destroy 时清理 descriptionCache
xiaoxia closed this pull request 2026-08-19 18:07:10 +08:00
Collaborator

【阻塞级判定】

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

📊 审查概览

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

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

  1. [apps/web/src/pages/generate/hooks/useCanvasPlayer.ts: 281-285] 编解码器描述缓存逻辑存在严重隐患

    • 问题类型:逻辑bug / 数据损坏风险
    • 问题描述:当提取不到 description 时,代码遍历 descriptionCache 的所有 values 并取第一个。这意味着如果当前 segment.assetId 对应的视频流没有 description,它会复用缓存中其他 assetId 的 description。如果不同的视频流具有不同的分辨率或编解码器参数,这将导致解码器配置错误,引发解码崩溃或画面花屏。
    • 修改建议:应改为 description = descriptionCache.current.get(segment.assetId),确保只复用当前视频流的缓存数据,避免跨流数据污染。
  2. [apps/web/src/pages/generate/hooks/useCanvasPlayer.ts: 413-419] 关键帧过滤逻辑会导致连续播放丢帧

    • 问题类型:逻辑bug
    • 问题描述:hasKeyFrame 变量在每次处理 samplesCollected 循环时都被重置为 false。在连续播放场景下(解码器未重新配置),如果后续分片的数据以非关键帧(P帧)开头(这在流式传输中很常见),由于 hasKeyFrame 为 false,这些帧会被错误地跳过,导致视频卡顿或画面缺失。
    • 修改建议:仅在解码器重新配置(即 decoderConfigured 为 false)时才强制要求首个样本为关键帧;或者在解码器已配置的情况下,允许接受非关键帧。

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

  1. [apps/web/src/pages/generate/hooks/useCanvasPlayer.ts: 355] 生产环境应移除调试日志
    • 具体内容:代码中包含了 console.logconsole.warn,建议在生产构建中移除或替换为可配置的日志工具,避免污染控制台或泄露敏感信息。

良好实践

  • useEffect 清理函数中添加了 descriptionCache.current.clear(),有效避免了内存泄漏。
  • 使用 ArrayBufferArrayBufferView 直接传递给 EncodedVideoChunk,避免了不必要的数据拷贝。

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

### 【阻塞级判定】 - 是否存在阻塞级问题:是 - 阻塞级问题数量:2 个 ### 📊 审查概览 - 整体评价:需修改 - 建议级问题数量:1 个 ### 🔴 阻塞级问题(必须修复) 1. **[apps/web/src/pages/generate/hooks/useCanvasPlayer.ts: 281-285] 编解码器描述缓存逻辑存在严重隐患** - 问题类型:逻辑bug / 数据损坏风险 - 问题描述:当提取不到 description 时,代码遍历 `descriptionCache` 的所有 `values` 并取第一个。这意味着如果当前 `segment.assetId` 对应的视频流没有 description,它会复用缓存中*其他* assetId 的 description。如果不同的视频流具有不同的分辨率或编解码器参数,这将导致解码器配置错误,引发解码崩溃或画面花屏。 - 修改建议:应改为 `description = descriptionCache.current.get(segment.assetId)`,确保只复用当前视频流的缓存数据,避免跨流数据污染。 2. **[apps/web/src/pages/generate/hooks/useCanvasPlayer.ts: 413-419] 关键帧过滤逻辑会导致连续播放丢帧** - 问题类型:逻辑bug - 问题描述:`hasKeyFrame` 变量在每次处理 `samplesCollected` 循环时都被重置为 `false`。在连续播放场景下(解码器未重新配置),如果后续分片的数据以非关键帧(P帧)开头(这在流式传输中很常见),由于 `hasKeyFrame` 为 false,这些帧会被错误地跳过,导致视频卡顿或画面缺失。 - 修改建议:仅在解码器重新配置(即 `decoderConfigured` 为 false)时才强制要求首个样本为关键帧;或者在解码器已配置的情况下,允许接受非关键帧。 ### 💡 改进建议(不阻塞合并) 1. **[apps/web/src/pages/generate/hooks/useCanvasPlayer.ts: 355] 生产环境应移除调试日志** - 具体内容:代码中包含了 `console.log` 和 `console.warn`,建议在生产构建中移除或替换为可配置的日志工具,避免污染控制台或泄露敏感信息。 ### ✅ 良好实践 - 在 `useEffect` 清理函数中添加了 `descriptionCache.current.clear()`,有效避免了内存泄漏。 - 使用 `ArrayBuffer` 或 `ArrayBufferView` 直接传递给 `EncodedVideoChunk`,避免了不必要的数据拷贝。 --- <sub>🤖 由 AI 代码审查机器人自动生成 | 2026-08-19 10:08:41 | 模型: </sub> <!-- AI_CODE_REVIEW_AUTO_COMMENT -->

🚀 预览环境已部署

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

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

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

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

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

🗑️ 预览环境已清理

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

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

🗑️ **预览环境已清理** PR #1443 已关闭或合并,对应的预览环境已被清理。 > 如有需要,可以重新打开 PR 来重新生成预览环境。
Some checks are pending
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 / Build Staging API 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 40s
AI Code Review / AI Code Review (pull_request) Failing after 1m58s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m58s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m14s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m17s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 20s
CI/CD Pipeline / Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m55s
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 Approve on CI Green (pull_request) Successful in 3m26s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 58s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 2m48s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Successful in 2m48s
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 4m34s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 9m57s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (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

Pull request closed

Sign in to join this conversation.