我使用 Node.js 和 Ffmpeg 来创建动画。因为我试图避免第三方 avi/mp4 解析器,所以我决定将动画输出为原始 rgb24 数据文件,然后使用一些程序将其转换为 mp4 文件。
我发现 Ffmpeg 是免费和开源的,完全可以做到这一点。因此,我制作了一个 Node.js 应用程序,它分配了一个大小为 1920 x 1080 x 3
(宽度乘以高度乘以每个像素的字节数)的 Buffer
,然后我创建了一个渲染上下文库,最后我逐帧动画并将每一帧连续保存在二进制文件中(使用 fs
模块)。
然后我调用 Ffmpeg 将其转换为 mp4 文件,效果非常好。动画非常容易制作,Ffmpeg 可以正确地完成它的工作。
然而,唯一的问题是因为它非常慢并且占用硬盘空间。我想制作很长的动画(一个多小时)。最终的 mp4 文件相对较小,但原始视频文件非常大。每帧大约百分之九十是黑色像素,所以 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
)?
提前致谢。请放轻松,这是我的第一个问题! :)
最佳答案
正如@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);
它产生这个图像:
它也适用于动画。
谢谢大家的帮助!
关于javascript - Node.js - 将数据缓冲到 Ffmpeg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46073876/