Как использовать ffmpeg в JavaScript для декодирования кадров H.264 в кадры RGB - PullRequest
0 голосов
/ 18 сентября 2018

Я пытаюсь скомпилировать ffmpeg в javascript, чтобы я мог декодировать видеопотоки H.264 с помощью узла.Потоки представляют собой кадры H.264, упакованные в NALU RTP, поэтому любое решение должно иметь возможность принимать кадры H.264, а не полное имя файла.Эти кадры не могут находиться в контейнере, таком как MP4 или AVI, потому что тогда демультиплексору требуется временная метка каждого кадра, прежде чем может произойти демультиплексирование, но я имею дело с потоком в реальном времени, без контейнеров.

Потоковая передача H.264 через RTP

Ниже приведен базовый код, который я использую для прослушивания сокета 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-кадры, которые мне нужны.Я также нашел ffmpeg.js , но мог заставить это работать, и ему нужен целый файл, а не поток.Аналогично, fluent-ffmpeg не поддерживает файловые потоки;Во всех примерах показано имя файла, передаваемого в конструктор.Поэтому я решил написать свой собственный API.

Моя текущая попытка решения

Мне удалось скомпилировать ffmpeg в один большой js-файл, но я не могу так его использовать.Я хочу написать API вокруг ffmpeg, а затем представить эти функции JS.Поэтому мне кажется, что мне нужно сделать следующее:

  1. Компилировать компоненты ffmpeg (avcodec, avutil и т. Д.) В битовый код llvm.
  2. Написать оболочку C, которая предоставляетФункция декодирования и использует EMSCRIPTEN_KEEPALIVE.
  3. Используйте emcc для компиляции оболочки и связывания ее с битовым кодом, созданным на шаге 1.

Я обнаружил WASM + ffmpeg ,но это на китайском и некоторые шаги не ясны.В частности, есть этот шаг:

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. Кто-нибудь знает шаги дляскомпилировать ffmpeg, используя emscripten, чтобы я мог представить некоторые API для javascript?
2. Есть ли лучший способ (с приличной документацией / примерами) декодировать видеопотоки h264 с помощью узла

1 Ответ

0 голосов
/ 30 ноября 2018

На вопрос 1: Просто следуйте официальным документ

Рассмотрим случай, когда вы обычно строите со следующим команды:

./configure
make

Для сборки с помощью Emscripten вы должны использовать следующее команды:

# Run emconfigure with the normal configure command as an argument.
./emconfigure ./configure

# Run emmake with the normal make to generate linked LLVM bitcode.
./emmake make

# Compile the linked bitcode generated by make (project.bc) to JavaScript.
# 'project.bc' should be replaced with the make output for your project (e.g. 'yourproject.so')
#  [-Ox] represents build optimisations (discussed in the next section).
./emcc [-Ox] project.bc -o project.js

К вопросу 2: библиотеки c / c ++ можно вызывать в среде узлов. Вы можете написать некоторый клейкий код на c / c ++ или использовать модуль прокси-узла, такой как node-ffi .

Использование node-ffi для вызова существующих библиотек может быть проще. Может ли это помочь:)

...