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

时间:2016-06-01 16:45:16

标签: javascript video browser ffmpeg h.264

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

avcodec_encode_video2(c, &packet, frame, &got_output)

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

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

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

if (data != null) player.decode(new Uint8Array(data));

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

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

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

1 个答案:

答案 0 :(得分:2)

请记住,百老汇仅处理使用CAVLC(霍夫曼编码)编码的基准配置文件,而忽略主配置文件或使用CABAC(算术编码)编码的任何内容。换句话说,百老汇只接受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-ebmlthis gist来取消装箱。每个data块包含一个或多个完整的NALU,您可以将其传递给decode()

如果它是video/mp4; codecs="avc1.42E01E"个片段化的MP4,则可以在avcC框内然后在mdat框内将sps和pps项取消装箱。这些项目中的每一项都是一个或多个完整的NALU。

如果要从服务器获取原始H.264数据流,则必须以某种方式自己将其解析为NALU。 Yumi Chan wrote a helpful article about NALUs.请记住,有两种方法可以分离NALU:数据包传输和字节流。 decode()接受其中任何一个,但您的解析器也必须接受。

相关问题