fix: Canvas 播放黑屏二次修复 — FrameQueue 扩容到 600 + 按需解码限制 300 帧
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m4s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 2m52s
CI/CD Pipeline / Build Staging API Image (push) Successful in 3m6s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 3m12s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 6m2s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 6m8s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m3s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 51s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 1m17s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 9m40s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m6s
CI/CD Pipeline / Integration Tests (push) Successful in 4m6s
CI/CD Pipeline / Unit Tests (push) Successful in 13m54s
CI/CD Pipeline / Production Browser E2E (push) Failing after 638h25m31s
CI/CD Pipeline / Deploy Production (push) Failing after 638h25m33s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 638h25m35s
CI/CD Pipeline / Build Production API Image (push) Failing after 638h25m35s
CI/CD Pipeline / CI Gate (push) Failing after 638h25m35s
CI/CD Pipeline / PR Build API Image (push) Failing after 638h39m31s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 638h39m29s
CI/CD Pipeline / Frontend Lint (push) Failing after 638h39m31s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 638h39m34s
CI/CD Pipeline / Canary Release to Production (push) Failing after 638h59m20s
CI/CD Pipeline / Build Production Web Image (push) Failing after 638h59m22s
CI/CD Pipeline / PR Build Web Image (push) Failing after 639h13m17s

根因:按需解码 decodeAroundPosition 调用 decodeSegment 时未传 maxFrames,
导致一次解码整个片段(~300帧)全部 push 进 maxSize=60 的队列,前 240 帧被淘汰,
只剩末尾帧(pts≈8~10s),getCurrentFrame(0) 找不到帧 → 黑屏 3~4 秒。

修复:
- FrameQueue maxSize: 60 → 600(覆盖约 20 秒 @30fps)
- decodeAroundPosition 中 decodeSegment 传入 maxFrames=300,
  限制单次按需解码帧数,避免远超队列容量的帧挤兑
This commit is contained in:
xiaoxia
2026-08-21 00:46:41 +08:00
parent b7be479ae7
commit 3441b3fece
@@ -221,7 +221,7 @@ export function useCanvasPlayer(
// ── 内部引用 ──
const decoderRef = useRef<VideoDecoder | null>(null)
const frameQueueRef = useRef(new FrameQueue(60))
const frameQueueRef = useRef(new FrameQueue(600))
/** 已解码的片段索引集合,用于按需解码(先标记防重入,失败时移除允许重试) */
const decodedSegmentsRef = useRef(new Set<number>())
/** 解码代数计数器,seek 时递增以作废正在进行的异步解码 */
@@ -609,7 +609,7 @@ export function useCanvasPlayer(
// 先标记为解码中,防止下一帧渲染时重复发起解码
decodedSegmentsRef.current.add(i)
try {
await decodeSegment(buffer, meta)
await decodeSegment(buffer, meta, 300)
} catch (e) {
// 解码失败则移除标记,允许后续重试
decodedSegmentsRef.current.delete(i)