bilibili / WebAV

WebAV is an SDK built on WebCodecs, designed for creating and editing video files on the web platform. WebAV 是基于 WebCodecs 构建的 SDK,用于在 Web 平台上创建/编辑视频文件。
https://bilibili.github.io/WebAV/
MIT License
985 stars 112 forks source link

mp4素材播放报错 Failed to execute 'decode' on 'VideoDecoder': A key frame is required after configure() or flush() #206

Closed 23233 closed 2 months ago

23233 commented 2 months ago

复现步骤

错误提示

image

awakeyue commented 2 months ago

我也遇到了

Yukiniro commented 2 months ago

WebAV 的解封装依赖于 mp4box.js,这个素材在 mp4box.js 中获取的关键帧索引跟 ffmpeg 获取的关键帧索引数据不一致 mp4box.js 的关键帧索引数据(前 3 个关键帧)为:0, 51, 102 ffmpeg 的关键帧索引数据(前 5 个关键帧)为:0, 1, 25, 52, 103 所以在播放过程中使用 51 进行 dec.decode(chunks[i]); 时会抛出异常:Failed to execute 'decode' on 'VideoDecoder': A key frame is required after configure() or flush().

hughfenghen commented 2 months ago

我之前修复过这种错误,已知的 case 有:

  1. 第一帧非关键帧,比如从 HLS 加载 m4s,截取的视频片段中,第一个 m4s 片段非关键帧
  2. 第一个关键帧包含了 SEI 信息,在 mp4 中被标记为 is_sync,但 WebCodecs 去解码的时候识别不出来;WebAV 当前版本会移除 SEI 信息再解码,兼容了这个问题

这可能是未知的 case,我还没有分析该视频数据。

@23233 @awakeyue 如果有条件的话,可以尝试先用 ffmpeg 转码一次,再给 Web 端处理。

WebCodecs 的兼容性比 ffmpeg 会差一些。

hughfenghen commented 2 months ago

原因是该视频中标记为 is_sync 的很多 sample 是普通 I 帧,非 IDR 帧; 当前解码策略是按 GoP 分组(以 I 帧分割组)解码,每次解码后会 flush; 而 WebCodecs 要求 flush 后的第一帧必须为 IDR 帧,所以会报错。

修改解码策略,以 IDR 帧分组, 且移除 IDR 帧前面的 SEI 信息,解决报错。

hughfenghen commented 2 months ago

另外,视频文件的音频编码(ec-3)是 WebCodecs 不支持的格式,所以播放不会有声音。