damianociarla/node-ffmpeg
ffmpeg module for nodejs
简介
node-ffmpeg 是一个 JavaScript/TypeScript 库,允许你在代码中控制命令行工具 ffmpeg 和 ffprobe。无需手动输入 shell 命令,只需调用如 setVideoCodec('libx264') 或 save('/output.mp4') 等方法。它封装了旧版广泛使用的 ffmpeg 包的 API 并进行了现代化改造:支持原生 Promises、TypeScript 类型,并同时兼容 ESM 和 CommonJS。
要求
- Node.js 24 或更高版本。
- 系统必须安装
ffmpeg和ffprobe并将其添加到PATH中,或者你必须提供它们的绝对路径。 - 该库有意不下载其自身的 FFmpeg 二进制文件——这保持了包的轻量化,并允许你选择所需的 FFmpeg 构建版本和编解码器。
安装
npm install ffmpeg
快速入门 (TypeScript)
import ffmpeg from 'ffmpeg';
const video = await ffmpeg('/media/input.mp4');
video.on('progress', ({ percent, time }) => {
console.log(percent === undefined ? `${time}s` : `${percent.toFixed(1)}% (${time}s)`);
});
await video
.setVideoCodec('libx264')
.setVideoBitRate(2_000)
.setAudioCodec('aac')
.setAudioBitRate(192)
.setVideoSize('1280x?', true, true, 'black')
.save('/media/output.mp4');
这些方法是链式调用的——你可以依次调用它们。操作仅在调用 save() 等终端方法时开始。它还保留了原始包的回调风格 API,以及支持 timeout 和 overwrite 等选项的命名工厂 create()。
对于处理大量文件的服务,你可以使用 createClient() 创建一个客户端,以复用 FFmpeg 设置。
可执行文件路径
你可以全局设置 ffmpeg 和 ffprobe 的路径(用于旧版应用),也可以按操作设置。如果你提供了绝对的 ffmpegPath 但没有提供 ffprobePath,库会自动推断 ffprobe 位于其同级目录下。
设置 (README 表格)
| 设置 | 默认值 | 含义 |
|---|---|---|
encoding |
utf8 |
处理输出编码 |
timeout |
0 |
最大操作时间(毫秒);0 = 无超时 |
maxBuffer |
16 MiB | 保留多少转换输出;也是探测输出的最大值 |
overwrite |
false |
使用 -y 覆盖;否则 -n 防止交互式提示 |
ffmpegPath |
ffmpeg |
FFmpeg 可执行文件 |
ffprobePath |
ffprobe |
ffprobe 可执行文件 |
signal |
— | 用于取消操作的 AbortSignal |
cwd, env |
继承 | 子进程工作目录和环境变量 |
长时间运行的转换仅保留最后 maxBuffer 字节的输出。探测输出必须完全容纳在 maxBuffer 内,否则操作将失败并报错 119。
API 亮点
- 设置器(均可链式调用):视频设置器如
setDisableVideo、setVideoCodec、setVideoBitRate等;音频设置器如setDisableAudio、setAudioCodec、setAudioBitRate;通用设置器如setMetadata、setThreads、setWatermark、addInput、addCommand、addOutputOption、addFilterComplex和getCommand(返回构建好的命令)。 - 终端方法:
save、fnExtractSoundToMP3、fnExtractFrameToJPG、fnAddWatermark。这些方法会启动实际的进程。 copy被接受为编解码器值,意味着“直接复制流而不重新编码”。- 允许重复的自定义选项(例如多个
-map或-metadata条目)。
终端方法内的验证通过 Promise 拒绝或可选的回调函数返回错误。设置器验证保持同步。对同一个视频对象的并发操作使用隔离的选项快照。
元数据和事件
video.metadata保留了原始结构(duration、video、audio、标签),并在video.metadata.raw中公开了完整的 ffprobe 响应。- 你可以监听生命周期事件:
'start'、'progress'(包含百分比/时间)、'stderr'、'end'和'error'。 'error'监听器是可选的——失败的 Promises 会正常拒绝,无需监听器。
帧提取
const files = await video.fnExtractFrameToJPG('/media/frames', {
start_time: '00:00:10',
every_n_seconds: 5,
number: 10,
size: '640x?',
quality: 2,
file_name: 'preview_%s',
});
every_n_frames、every_n_seconds 或 every_n_percentage 中只能设置一个。返回的路径仅包含匹配提取模式的文件。
自定义 FFmpeg 选项
使用 addCommand 传递原始参数。它们直接传递给 spawn 而不进行 shell 解析,因此不要添加 shell 引号。这些方法是受信任的逃生舱——切勿传递未经校验的用户输入。以 - 开头的输出目标会被拒绝;请改用 ./-name.ext。
从 0.0.4 迁移
- 现在需要 Node.js 24+ 和
ffprobe。 - 原生 Promises 取代了旧的
when库;await的用法与之前相同。 - 错误现在是
FfmpegError实例,包含历史数值code和msg字段。 - 水印罗盘位置现在遵循常规含义(
NE= 右上角,修复了旧版的反转问题)。 - 比特率使用
-b:v/-b:a;数值被视为 kbit/s。 - 现有输出受
-n保护;设置overwrite: true以使用-y。 - 该包现在自带 TypeScript 声明,因此无需安装
@types/ffmpeg。
安全性
FFmpeg 处理不受信任且复杂的媒体。请保持系统 FFmpeg 已打补丁,应用资源限制,并在接受不受信任的输入之前阅读 SECURITY.md。
许可证
MIT © Damiano Ciarla
相关
- 项目
- 项目
- 项目
- 项目