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 3
的 Buffer
(宽度乘以高度乘以每个像素的字节数),然后我创建了一个渲染上下文库,最后我逐帧动画并保存了每个在二进制文件中连续帧(使用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的主要内容,如果未能解决你的问题,请参考以下文章