Я пытаюсь захватить кадры из живого видеопотока (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, так что, я думаю, я могу проверить эту конечную сигнатуру и начать новый файл в этот момент ... какие-либо другие предложения?