所以基本上我有一个画布,它以 24 的帧率不断更新,我想将它生成的图像序列转换为 H264。最终目标是将它发送到 RTMP 服务器,但现在这将帮助我在管道输出之前检查事情是否正常工作。我正在使用的画布 API(请参阅 node-canvas)允许我在任何给定时刻捕获整个画布表面的 JPEG。不幸的是,输入只会在我结束 STDIN 后提交,这不是我想要的。我不想批量处理所有输入,而是想边走边处理传入的 JPEG,这样一切都可以实时完成。这是我用来实现相关功能的代码片段(不幸的是它不起作用):
// patches/canvas.js
const { Canvas } = require('canvas');
const execa = require('execa');
const $ffmpeg = require('ffmpeg-static');
Canvas.prototype.captureStream = function captureStream(frameRate = 24) {
const refreshRate = 1000 / frameRate;
const encoding = execa($ffmpeg, [
'-f', 'image2pipe',
'-r', frameRate,
'-vcodec', 'mjpeg',
'-s', `${this.width}x${this.height}`,
'-i', '-',
'-vcodec', 'libx264',
'-preset', 'veryfast',
'-crf', '18',
'-pix_fmt', 'yuv420p',
'-b:v', '500k',
'-bufsize', '600k',
'-vprofile', 'baseline',
'-tune', 'zerolatency',
'-g', '60',
'-r', frameRate,
'-s', `${this.width}x${this.height}`,
'-f', 'rawvideo',
'-',
], {
stdio: 'pipe',
});
let lastFeed = Date.now();
const feed = () => {
const jpegStream = this.jpegStream();
jpegStream.on('data', (data) => {
encoding.stdin.push(data);
});
jpegStream.on('end', () => {
const now = Date.now();
const timeSpan = Math.max(refreshRate - (now - lastFeed), 0);
lastFeed = now;
setTimeout(feed, timeSpan);
});
};
feed();
return encoding.stdout;
};
module.exports = require('canvas');
有关如何使其工作的任何建议?