javascript - 从 Node 产生时ffmpeg缓冲标准输入

标签 javascript node.js ffmpeg stdin

我正在尝试使用 node.js 将 png 数据写入 ffmpeg 以创建视频。我已验证以下代码有效:

let ffmpeg = spawn(
  "ffmpeg",
  [
    "-y",
    "-loglevel", "info",
    "-f", "image2pipe",
    "-c:v", "png",
    "-r", `${this.fps}`,
    "-i", "-",

    "-an",
    "-vcodec", "libx264",
    "-pix_fmt", "yuv420p",
    "output.mp4",
  ],
);
ffmpeg.stdout.on('data', data => {
  console.log(`ffmpeg stdout: ${data}`);
});
ffmpeg.stderr.on('data', data => {
  console.log(`ffmpeg stderr: ${data}`);
});

let bufs = [];
let p = Promise.resolve();
for (let i = 0; i < this.frameData.length; i++) {
  p = p.then(_ => new Promise(resolve => {
    this.renderFrame(i);
    this.renderer.domElement.toBlob(blob => {
      blob.arrayBuffer().then(arr => {
        console.log('writing...');
        let uInt8Arr = new Uint8Array(arr);
        // ffmpeg.stdin.write(uInt8Arr);
        bufs.push(uInt8Arr);
        resolve();
      });
    });
  }));
}
p = p.then(_ => {
  for (let buf of bufs) {
    ffmpeg.stdin.write(buf);
  }
  ffmpeg.stdin.end();
});


抱歉,如果它看起来很复杂,promise 被用作 toBlob() 的解决方法。异步运行,但帧必须按顺序写入。

该代码在编写时可以正常工作,但它不必要地低效,因为它将帧数据写入数组只是为了稍后将其写入ffmpeg。但是,如果我取消注释 ffmpeg.stdin.write(uInt8Arr);并注释将数组数据复制到ffmpeg的循环,ffmpeg将简单地卡在最后而不生成任何视频。如果我随后执行“足够大”的操作,例如保存文件或生成新进程,ffmpeg 将正确生成视频。

我怀疑是某种缓冲问题导致了这种情况,但我不完全理解或不知道如何解决它。我已经尝试使用 ffmpeg.kill() 向 ffmpeg 发送各种信号并通过 stdbuf 运行它根据建议 here无济于事。有什么解决方法吗?

最佳答案

对于偶然发现此问题的任何人,解决方案是将调用替换为 ffmpeg.stdin.close()。与 ffmpeg.stdin.destroy() .

关于javascript - 从 Node 产生时ffmpeg缓冲标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61541133/

相关文章:

javascript - 我怎样才能重用功能而不是不断重复它?

javascript - Plotly.js 自动缩放

node.js - 使用 Atom Shell/Electron 的上下文菜单单击/打开事件?

node.js - 限制 Node.js 中的连接数

ffmpeg - ffplay.c 中的默认音频可视化在哪里?

javascript - 如何使用 React.js 调用从 Grid 读取的 kendo ui 数据源

javascript - 为什么我的鼠标坐标出现在鼠标以外的其他位置?

angularjs - Passport.js、Express.js 和 Angular.js 路由 : how can they coexist?

c++ - 是否可以在使用基于元数据信息的 ffmpeg c++ api 解码视频时旋转帧?

video - FFMPEG 安装在服务器上