diff --git a/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts b/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts index cdd8f0314..a859f61a9 100644 --- a/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts +++ b/apps/web/src/pages/generate/hooks/useCanvasPlayer.ts @@ -260,8 +260,11 @@ export function useCanvasPlayer( // ── 解封装单个片段,提取轨道元数据 + 按时间范围过滤样本 ── const demuxSegment = useCallback( (buffer: ArrayBuffer, segIndex: number): SegmentMeta | null => { - const segment = segments[segIndex] - if (!segment) return null + const segment = segments?.[segIndex] + if (!segment) { + console.warn("[useCanvasPlayer] No segment at index", segIndex) + return null + } // 计算全局偏移 let globalStart = 0 @@ -273,9 +276,9 @@ export function useCanvasPlayer( let meta: SegmentMeta | null = null mp4File.onReady = (info: Movie) => { - const videoTrack = info.videoTracks[0] + const videoTrack = info?.videoTracks?.[0] if (!videoTrack) { - console.error("[useCanvasPlayer] No video track found for segment", segIndex) + console.warn("[useCanvasPlayer] No video track found for segment", segIndex) return } @@ -300,9 +303,9 @@ export function useCanvasPlayer( videoUrl: segment.videoUrl, globalStartTime: globalStart, globalEndTime: globalStart + (segment.endTime - segment.startTime), - trackId: videoTrack.id, - timescale: videoTrack.timescale, - codec: videoTrack.codec, + trackId: videoTrack.id ?? 1, + timescale: videoTrack.timescale ?? 90000, + codec: videoTrack.codec ?? "avc1.42E01E", videoWidth: videoTrack.track_width || 1280, videoHeight: videoTrack.track_height || 720, description, @@ -310,8 +313,8 @@ export function useCanvasPlayer( } // 提取所有 samples - mp4File.setExtractionOptions(videoTrack.id, null, { - nbSamples: videoTrack.nb_samples, + mp4File.setExtractionOptions(videoTrack.id ?? 1, null, { + nbSamples: videoTrack.nb_samples ?? 0, }) mp4File.start() } @@ -325,7 +328,7 @@ export function useCanvasPlayer( const endCts = segment.endTime * timescale // 过滤出时间范围内的样本 - let filtered = samples.filter((s) => s.cts >= startCts && s.cts < endCts) + let filtered = samples.filter((s) => (s?.cts ?? 0) >= startCts && (s?.cts ?? 0) < endCts) // 确保从关键帧开始(跳过第一个 sync 之前的非关键帧) let foundSync = false @@ -436,10 +439,11 @@ export function useCanvasPlayer( if (!sample.data || isDestroyedRef.current) continue if (decoder.state === "closed") break + if (!sample.data) continue const chunk = new EncodedVideoChunk({ type: sample.is_sync ? "key" : "delta", - timestamp: (sample.cts / meta.timescale) * 1_000_000, - duration: (sample.duration / meta.timescale) * 1_000_000, + timestamp: ((sample.cts ?? 0) / (meta.timescale || 90000)) * 1_000_000, + duration: ((sample.duration ?? 0) / (meta.timescale || 90000)) * 1_000_000, data: sample.data, })