From 709d65ce52ebdd70e5d848357755df63ceb0f785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=AE=8F=E6=9D=B0?= Date: Wed, 19 Aug 2026 22:38:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20VisualSampleEntry=20=E8=B7=B3=E8=BF=8778?= =?UTF-8?q?=E5=AD=97=E8=8A=82=E5=9B=BA=E5=AE=9A=E5=AD=97=E6=AE=B5=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20hvcC=20=E6=8F=90=E5=8F=96=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - findCodecConfigRecursive 区分 VisualSampleEntry 和普通容器 box - avc1/avc3/hvc1/hev1 前 78 字节是固定字段(ISO 14496-12),子 box 从 offset+8+78 开始 - 普通容器 box(moov/trak/mdia/minf/stbl)仍从 offset+8 开始递归 - 修复 HEVC description 提取失败导致的黑屏问题 --- apps/web/src/pages/generate/hooks/useCanvasPlayer.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) 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