Node.js - 将数据缓冲到 Ffmpeg

Posted

技术标签:

【中文标题】Node.js - 将数据缓冲到 Ffmpeg【英文标题】:Node.js - Buffer Data to Ffmpeg 【发布时间】:2018-02-14 20:46:15 【问题描述】:

我使用 Node.js 和 Ffmpeg 来创建动画。因为我试图避免使用第三方 avi/mp4 解析器,所以我决定将动画输出为原始 rgb24 数据文件,然后使用一些程序将其转换为 mp4 文件。

我发现 Ffmpeg 是免费且开源的,完全可以做到这一点。因此,我创建了一个 Node.js 应用程序,它分配了一个大小为 1920 x 1080 x 3Buffer(宽度乘以高度乘以每个像素的字节数),然后我创建了一个渲染上下文库,最后我逐帧动画并保存了每个在二进制文件中连续帧(使用fs 模块)。

然后我调用 Ffmpeg 将其转换为 mp4 文件,效果非常好。动画很容易制作,而且 Ffmpeg 做得很好。

但是,唯一的问题是因为它非常慢并且占用了硬盘空间。我想制作很长的动画(超过一个小时)。最终的 mp4 文件相对较小,但原始视频文件非常大。每帧大约 90% 是黑色像素,所以 Ffmpeg 压缩它非常好,但原始文件无法压缩,有时需要超过 100 GB。此外,有非常不必要的双重处理相同的数据。首先我在 Node.js 中处理它以将数据保存到文件中,然后 Ffmpeg 读取它以将其转换为 mp4。有很多不必要的工作。

所以,我正在寻找一种将原始视频数据(一次一帧)输出到 Ffmpeg 的方法(我很确定这是可能的,但我还没有找到方法)进程(不保存任何内容到硬盘)。

我的目标是做到以下几点:

    打开 Ffmpeg 进程 在 Node.js 中渲染一个框架 将原始字节流输出到 Ffmpeg 等待 Ffmpeg 对其进行编码并附加到 mp4 文件中 让 Ffmpeg 等待我的 Node.js 进程渲染下一帧

有没有办法实现它? 我真的看不出发布代码的理由,因为我当前的代码与我在这里提出的问题无关。 我不会为语法错误或实现问题而烦恼。不,相反,我只是不知道将哪些参数传递给 Ffmpeg 进程以实现我已经解释过的内容。

我在文档中搜索了哪些参数需要传递给 Ffmpeg 进程,以便让它从标准输入而不是从文件中读取原始数据,并等到我的 Node.js 进程渲染下一帧(所以禁用时间限制),因为渲染一帧可能需要超过 24 小时。因此,Ffmpeg 进程应该无时间限制地等待。但是,我在文档中没有找到任何关于它的信息。

我知道如何从 Node.js 和类似的技术资料写入标准输入,所以无需解释。这里唯一的问题:

    将哪些参数传递给 Ffmpeg? 我是否需要创建带有一些特殊选项的 Ffmpeg 进程(使用 child_process)?

提前谢谢你。请放轻松,这是我的第一个问题! :)

【问题讨论】:

它将沿用ffmpeg -f rawvideo -s 1920x1080 -framerate R -pixel_format rgb24 -i - output.mp4 @Mulvya。那么,-i - 是答案吗?只是想知道为什么我没有在文档中找到它。谢谢 @estus。也谢谢。 如上所述,从标准输入读取是ffmpeg ... -i - ...。是的,您需要创建一个进程,child_process 默认为流的管道,例如let ffmpegProcess = child_process.spawn(...); ffmpegProcess.stdin(...).pipe(...)。如果您对这种方法有疑问,我建议提供***.com/help/mcve(回购或其他东西),这会增加获得正确答案的机会。 希望这会有所帮助。现在无法检查流式处理是否适用于 Node 中的 ffmpeg 【参考方案1】:

正如@Mulvya 和@estus 所建议的,正确的参数是-i -(启用来自标准输入的输入):

'use strict';

var cp = require('child_process');

var proc = cp.spawn('ffmpeg', [
  '-hide_banner',
  '-f', 'rawvideo',
  '-pix_fmt', 'rgb24',
  '-s', '2x2',
  '-i', '-',
  '1.png'
]);

proc.stdin.write(Buffer.from([
  255, 0, 0,
  0, 255, 0,
  0, 255, 255,
  255, 0, 255
]));

proc.stdin.end();

proc.stderr.pipe(process.stdout);

它会生成这个图像: 它也适用于动画。

感谢大家的帮助!

【讨论】:

以上是关于Node.js - 将数据缓冲到 Ffmpeg的主要内容,如果未能解决你的问题,请参考以下文章

如何使用sharp.js将图像从缓冲区存储到node.js中的文件系统

Node.js处理I/O数据之Buffer模块缓冲数据

Node.js Buffer(缓冲区)

Node.js Buffer(缓冲区)

Node.js:Buffer(缓冲区)介绍及常用方法

如何将二进制缓冲区解码为 node.js 中的图像?