我正在尝试将ffmpeg编译为JavaScript,以便使用node解码H.264视频流。这些流是打包到RTP NALU中的H.264帧,因此任何解决方案都必须能够接受H.264帧而不是整个文件名。这些帧不能在像MP4或AVI这样的容器中,因为解复用器需要在解复用之前需要每个帧的时间戳,但我正在处理实时流,没有容器。
我找到了Broadway.js库,但是无法让它工作并且它不处理我需要的P-frames。我也找到了ffmpeg.js,但无法使用它并且它需要整个文件而不是流。同样,fluent-ffmpeg似乎不支持文件流;所有的示例都展示了将文件名传递给构造函数。因此,我决定编写自己的API。
通过RTP流式传输H.264
以下是我使用的基本代码来监听udp套接字。在“message”回调中,数据包是一个RTP数据报。数据报的数据部分是一个H.264帧(P帧和I帧)。
var PORT = 33333;
var HOST = '127.0.0.1';
var dgram = require('dgram');
var server = dgram.createSocket('udp4');
server.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
server.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port +' - ' + message);
frame = parse_rtp(message);
rgb_frame = some_library.decode_h264(frame); // This is what I need.
});
server.bind(PORT, HOST);
我找到了Broadway.js库,但是无法让它工作并且它不处理我需要的P-frames。我也找到了ffmpeg.js,但无法使用它并且它需要整个文件而不是流。同样,fluent-ffmpeg似乎不支持文件流;所有的示例都展示了将文件名传递给构造函数。因此,我决定编写自己的API。
我的当前解决方案尝试
我已经能够将ffmpeg编译成一个大的js文件,但我不能像那样使用它。我想围绕ffmpeg编写一个API,然后将这些函数暴露给JS。所以我觉得我需要做以下事情:
- 将ffmpeg组件(avcodec、avutil等)编译为llvm位代码。
- 编写一个C包装器来公开解码功能并使用EMSCRIPTEN_KEEPALIVE。
- 使用emcc编译包装器并将其链接到步骤1中创建的位代码。
emcc web.c process.c ../lib/libavformat.bc ../lib/libavcodec.bc ../lib/libswscale.bc ../lib/libswresample.bc ../lib/libavutil.bc \
:( 我卡住了
我不理解所有的ffmpeg组件是如何编译成单独的*.bc文件的。我按照那篇文章中的emmake命令进行操作,但最终只得到一个大的.bc文件。
2个问题
1. 有人知道使用emscripten编译ffmpeg的步骤,以便我可以将一些API暴露给JavaScript吗?
2. 是否有更好的方法(带有良好的文档/示例)来使用node解码h264视频流?