From c6eeca75fbb818dc5f688e63e90e5ad128bdb5b4 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Fri, 21 Aug 2026 21:25:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4=20decodeSegment=20?= =?UTF-8?q?=E7=9A=84=20startFrame=20=E5=8F=82=E6=95=B0=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=85=B3=E9=94=AE=E5=B8=A7=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WebCodecs 解码器要求第一个 chunk 必须是关键帧。续解码从 startFrame=60 开始时,samplesCollected[60] 不是关键帧 → 报错 "A key frame is required"。 修复: - 删除 startFrame 参数,sample 循环永远从 0 开始 - decodeAroundPosition 不再传 startFrame - totalDecoded 计算不再使用 startFrame 偏移 --- .../src/pages/generate/hooks/useCanvasPlayer.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts b/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts index de2448fce..13e91ae93 100644 --- a/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts +++ b/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts @@ -479,12 +479,7 @@ export function useCanvasPlayer( // ── 初始化 VideoDecoder 并解码指定片段 ── const decodeSegment = useCallback( - async ( - _buffer: ArrayBuffer, - meta: SegmentMeta, - maxFrames?: number, - startFrame: number = 0, - ): Promise => { + async (_buffer: ArrayBuffer, meta: SegmentMeta, maxFrames?: number): Promise => { console.log(`[DIAG_v2] >>> decodeSegment ENTER assetId=${meta.assetId}`) if (isDestroyedRef.current) return @@ -580,7 +575,8 @@ export function useCanvasPlayer( let decodedCount = 0 let skippedCount = 0 let decodeErrors = 0 - for (let si = startFrame; si < samplesCollected.length; si++) { + // 永远从 0 开始,确保第一个 sample 是关键帧 + for (let si = 0; si < samplesCollected.length; si++) { const sample = samplesCollected[si] // seek/重播时旧的 decodeSegment 立即退出,不往帧队列推废帧 if (decodeGenerationRef.current !== gen) { @@ -651,7 +647,7 @@ export function useCanvasPlayer( ) // 记录该片段已解码帧数(用于 decodeAroundPosition 续解码) - const totalDecoded = decodedCount + startFrame + const totalDecoded = decodedCount const metaArr = segmentMetaRef.current for (let idx = 0; idx < metaArr.length; idx++) { if (metaArr[idx].assetId === meta.assetId) { @@ -719,7 +715,7 @@ export function useCanvasPlayer( const currentCount = decodedFrameCountsRef.current.get(i) ?? 0 if (currentCount >= totalSamples) continue try { - await decodeSegment(buffer, meta, 300, currentCount) + await decodeSegment(buffer, meta, 300) } catch (e) { console.warn(`[useCanvasPlayer] 续解码片段 ${i} 失败:`, e) } @@ -730,8 +726,7 @@ export function useCanvasPlayer( // 未开始解码的片段:开始解码 decodedSegmentsRef.current.add(i) try { - const startFrame = decodedFrameCountsRef.current.get(i) ?? 0 - await decodeSegment(buffer, meta, 300, startFrame) + await decodeSegment(buffer, meta, 300) } catch (e) { decodedSegmentsRef.current.delete(i) console.warn(`[useCanvasPlayer] 按需解码片段 ${i} 失败:`, e)