使用 Broadway.js 解码原始 h.264

cru*_*eon 5 javascript browser video ffmpeg h.264

我正在开发一个应用程序,它使用 ffmpeg 为我提供编码的 h.264 帧:

avcodec_encode_video2(c, &packet, frame, &got_output)
Run Code Online (Sandbox Code Playgroud)

如果我将所有内容保存packet.data到文件out.h264 中,它会使用.h264显示所需的输出ffplay

现在,我的目标是在收到每个数据包时发送它并在网页上显示它(实时流)。为此,我正在使用Broadway.js

我可以确认我从应用程序发送的数据在浏览器中被正确接收。但是,我无法使用 Broadway ( Player.js, Decoder.js, YUVCanvas.js)在 webGL 画布上显示相同的内容:

if (data != null) player.decode(new Uint8Array(data));
Run Code Online (Sandbox Code Playgroud)

我得到的输出是一张空白的白色画布。dataArrayBuffer包含来自从 接收的数据包的 h.264 比特流的avcodec_encode_video2。难道我做错了什么?数据是否应该采用特定格式?

旁注:
我的视频文件out.h264使用此处提供的示例正确播放: BroadwayStream

它似乎使用命令行 ffmpeg 接口并处理收到的每个数据包。我的程序使用 ffmpeg 库来获取我需要渲染的相同数据包。有人可以帮忙吗?

O. *_*nes 3

请记住,Broadway 仅处理使用 CAVLC(霍夫曼编码)编码的基线配置文件,而忽略主配置文件或使用 CABAC(算术编码)编码的任何内容。换句话说,Broadway 只接受最容易解码的 H.264 流类型。当您的视频编码不正确时,可能会令人沮丧,因为您会遇到可怕的黑屏综合症。

BroadwayStream 在服务器端使用 ffmpeg 对 mp4 文件进行解箱,将其转换为原始 H.264 数据流。也就是说,它生成一系列 H.264 网络访问层单元 (NALU)。

然后浏览器端获取整个数据流并将其传递给 Broadway 的decode()方法。因此,decode()始终获得完整的 NALU 序列,在任何特定方法调用中都不会传递部分 NALU。

decode()不采用部分 NALU。(BroadwayStream 通过提供整个流巧妙地避开了这一点。)并且它不采用 mp4 或 webm 数据流,只采用拆箱的 H.264。如果你向它传递部分 NALU,它就不起作用——它只是忽略你给它的数据。因此,接受数据流的客户端 js 必须以某种方式将流分成 NALU,然后再将它们传递给decode().

如果您的 js 接受 MIME 类型的混合文件,video/webm; codecs="avc1.42E01E"您可以查看https://github.com/themasch/node-ebml此要点以了解对它们进行拆箱的方法。每个data块包含一个或多个完整的 NALU,您可以将其传递给decode().

如果是video/mp4; codecs="avc1.42E01E"碎片MP4,您可以将盒子中的sps和pps项目拆箱avcC,然后再mdat拆箱。其中每一项都是一个或多个完整的 NALU。

如果您从服务器获取原始 H.264 流,则必须以某种方式自行将其解析为 NALU。Yumi Chan 写了一篇关于 NALU 的有用文章。请记住,有两种分离 NALU 的方法:数据包传输和字节流。decode()接受其中之一,但你的解析器也必须接受。