我正在尝试从实时视频流(h.264)捕获帧并将生成的JPG图像通过管道传输到Node JS脚本,而不是将这些单独的帧直接保存到.jpg文件中。
作为测试,我创建了以下Node JS脚本,以简单地捕获传入的管道数据,然后将其转储到文件中:
// 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
这生成了以下输出,并且还生成了一个175kB的文件,其中包含垃圾(无论如何都无法读取为jpg文件)。仅供参考,使用ffmpeg直接将其导出为jpg文件,生成的文件大小约为25kB。
...
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.
您可以看到Node JS脚本正在接收管道数据(根据上面的“通过管道接收的数据”消息)。但是,它似乎没有输出有效的JPG文件。我找不到找到方法明确要求ffmpeg输出JPG格式,因为JPG没有-vcodec选项。我尝试使用-vcodec png并输出到.png文件,但是结果文件的大小约为2MB,也不能作为png文件读取。 / p>
这是使用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文件何时结束而另一个开始?
ffmpeg命令:
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的数据何时完成而另一幅已开始? 根据{{3}},jpeg文件始终以FF D8 FF开头并以FF D9结尾,所以我想我可以检查该结尾签名并在那时候开始一个新文件...还有其他建议吗?