如何将连续的图像流实时转换为 h264 流

时间:2021-03-29 09:40:04

标签: javascript node.js canvas ffmpeg webrtc

所以基本上我有一个画布,它以 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');

有关如何使其工作的任何建议?

0 个答案:

没有答案