Передача выходного файла ffmpeg в другую программу - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь захватить кадры из живого видеопотока (h.264) и передать полученные изображения JPG в сценарий Node JS вместо сохранения этих отдельных кадров непосредственно в файлы .jpg.

В качестве теста я создал следующий JS-скрипт Node, чтобы просто перехватить входящие данные по каналу и затем вывести их в файл:

// pipe.js - test pipe output
var fs = require('fs');
var data = '';

process.stdin.resume();
process.stdin.setEncoding('utf8');

var filename = process.argv[2];

process.stdin.on('data', (chunk) => {
        console.log('Received data chunk via pipe.');
        data += chunk;
});

process.stdin.on('end', () => {
        console.log('Data ended.');
        fs.writeFile(filename, data, err => {
                if (err) {
                        console.log('Error writing file: error #', err);
                }
        });
        console.log('Saved file.');
});

console.log('Started...  Filename = ' + filename);

Вот команда ffmpeg, которую я использовал:

ffmpeg -vcodec h264_mmal -i "rtsp://[stream url]" -vframes 1 -f image2pipe - | node pipe.js test.jpg

Это сгенерировало следующий вывод, а также создало файл размером 175 КБ, содержащий мусор (в любом случае не читаемый как файл jpg).К вашему сведению, используя ffmpeg для прямого экспорта в файл jpg, создаются файлы размером около 25 КБ.

...
Press [q] to stop, [?] for help
[h264_mmal @ 0x130d3f0] Changing output format.
Input stream #0:0 frame changed from size:1280x720 fmt:yuvj420p to size:1280x720 fmt:yuv420p
[swscaler @ 0x1450ca0] deprecated pixel format used, make sure you did set range correctly
Received data chunk via pipe.
Received data chunk via pipe.
frame=    1 fps=0.0 q=7.7 Lsize=      94kB time=00:00:00.40 bitrate=1929.0kbits/s speed=1.18x
video:94kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
Received data chunk via pipe.
Data ended.
Saved file.

Вы можете видеть, что JS-скрипт Node получает данные по конвейеру (согласно сообщениям «Полученные данные по каналу» выше).Однако, похоже, что он не выводит действительный файл JPG. Я не могу найти способ специально запросить, чтобы ffmpeg выводил формат JPG, так как для JPG нет опции -vcodec. Я попытался использовать -vcodec png и вывести вфайл .png, но размер получаемого файла составлял около 2 МБ и также не читался как файл png.

Это проблема, вызванная использованием кодировки utf8, или я что-то не так делаю?

Спасибо за любой совет.

ОБНОВЛЕНИЕ: ОК, я получил его для правильной отправки одного изображения jpg. Проблема заключалась в том, что Node JS захватывал данные потока. Вот рабочий скрипт:

// pipe.js - capture piped binary input and write to file
var fs = require('fs');
var filename = process.argv[2];

console.log("Opening " + filename + " for binary writing...");

var wstream = fs.createWriteStream(filename);

process.stdin.on('readable', () => {
        var chunk = '';
        while ((chunk = process.stdin.read()) !== null) {
                wstream.write(chunk);   // Write the binary data to file
                console.log("Writing chunk to file...");
        }
});

process.stdin.on('end', () => {
        // Close the file
        wstream.end();
});

Однако теперь проблема заключается в следующем: когда я передаю выходные данные ffmpeg в этот скрипт, как я могу узнать, когда заканчивается один файл JPG, а начинается другой?

ffmpeКоманда g:

 ffmpeg -vcodec h264_mmal -i "[my rtsp stream]" -r 1 -q:v 2 -f singlejpeg - | node pipe.js test_output.jpg

Файл test_output.jpg продолжает расти, пока выполняется скрипт.Как я могу вместо этого знать, когда данные для одного JPG полны и еще один запущен?Согласно this , файлы jpeg всегда начинаются с FF D8 FF и заканчиваются FF D9, так что, я думаю, я могу проверить эту конечную сигнатуру и начать новый файл в этот момент ... какие-либо другие предложения?

...