diff --git a/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts b/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts index c08ce1aa4..f2280c305 100644 --- a/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts +++ b/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts @@ -14,8 +14,8 @@ import type { Movie, Sample } from "mp4box" * 递归搜索 box 树,找到 hvcC 或 avcC box 并返回其配置数据(不含 8 字节 box header) * * MP4 box 嵌套结构:moov → trak → mdia → minf → stbl → stsd → hev1 → hvcC - * 此函数不区分 fullbox / 普通 box,统一从 offset+8 开始递归搜索子 box - * 因为所有 container box(moov/trak/mdia/minf/stbl)的 content 都从 offset+8 开始 + * 普通容器 box 从 offset+8 开始递归;VisualSampleEntry (avc1/avc3/hvc1/hev1) 前 78 字节 + * 是固定字段(ISO 14496-12),子 box 从 offset+8+78 开始 */ function findCodecConfigRecursive( buffer: ArrayBuffer, @@ -42,8 +42,11 @@ function findCodecConfigRecursive( return buffer.slice(offset + 8, offset + size) } - // 递归搜索子 box(所有 box 的子 box 都从 offset+8 开始) - const childResult = findCodecConfigRecursive(buffer, offset + 8, offset + size) + // VisualSampleEntry (avc1/avc3/hvc1/hev1) 前 78 字节是固定字段,子 box 在 78 字节之后 + // 普通容器 box (moov/trak/mdia/minf/stbl/stsd) 从 offset+8 开始递归 + const visualSampleEntryTypes = ["avc1", "avc3", "hvc1", "hev1"] + const childStart = visualSampleEntryTypes.includes(type) ? offset + 8 + 78 : offset + 8 + const childResult = findCodecConfigRecursive(buffer, childStart, offset + size) if (childResult) return childResult offset += size