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

相关

  • 项目
  • 项目
  • 项目
  • 项目