将ffmpeg thumbail输出管道到另一个程序

时间:2018-09-21 15:24:43

标签: node.js ffmpeg pipe jpeg

我正在尝试从实时视频流(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结尾,所以我想我可以检查该结尾签名并在那时候开始一个新文件...还有其他建议吗?

0 个答案:

没有答案