ffmpeg-static

基于 npm 包的 FFmpeg 静态二进制,支持视频音频转码与格式转换。

已扫描
适合谁
开发者、自动化脚本编写者
不适合谁
无编程基础的普通用户、需要 GPU 加速编码的高级用户
国内可用性
需网络配置。可能需要网络配置或第三方服务可访问。
安装难度
新手友好(★☆☆)。基于终端操作、依赖、API Key 和本地环境要求的初步判断。

安装与下载

openclaw skills install @fantox/ffmpeg-static

Skill 说明

命令、参数、文件名以原文为准

FFmpeg 静态技能

此技能将 [ffmpeg-static](https://github.com/eugeneware/ffmpeg-static) — 一个作为 npm 包分发的自包含 FFmpeg 二进制文件 — 无缝集成到每个助手交互中。当系统中也安装了原生 FFmpeg 时,该技能会优先使用系统二进制文件(通常版本更新,支持 GPU 加速);否则将回退到捆绑的版本。所有 FFmpeg 功能在两条路径中均可使用。

无需修改 PATH 环境变量。 require('ffmpeg-static') 返回二进制文件的绝对路径;脚本可直接将其传递给 child_process.spawn


安全提示

  • ffmpeg-staticnpm install 期间会从 GitHub Releases 下载预构建的二进制文件。请在 [npmjs.com/package/ffmpeg-static](https://www.npmjs.com/package/ffmpeg-static) 上验证该包。
  • 未经验证前,切勿将不可信的文件名或 URL 传入 FFmpeg 命令 —— FFmpeg 可以读取 URL 和任意协议。
  • 捆绑的二进制文件 不包含 GPU 加速编码器(如 nvenc、vaapi、videotoolbox)。如需硬件加速,请使用系统 FFmpeg。

安装

最小安装(仅捆绑 FFmpeg 二进制文件)

npm install ffmpeg-static

项目安装(推荐,包含 ffprobe)

npm install ffmpeg-static ffprobe-static

验证二进制路径

node -e "console.log(require('ffmpeg-static'))"
# 例如:/path/to/node_modules/ffmpeg-static/ffmpeg

检查解析后的二进制文件(捆绑版 vs. 系统版)

node scripts/resolve_ffmpeg.js

二进制解析逻辑

该技能按以下优先级顺序解析 FFmpeg 二进制文件:

  1. **FFMPEG_PATH 环境变量** — 显式覆盖,始终优先
  2. 系统 FFmpeg — 通过遍历 PATH 目录并使用 fs.accessSync 查找;若存在则优先使用(支持更新的编解码器和硬件加速)
  3. 捆绑的二进制文件require('ffmpeg-static') 返回的绝对路径;在 npm install 后保证存在
// 标准解析方式 —— 所有脚本应使用此模式
const { resolveFfmpeg } = require('./scripts/resolve_ffmpeg');
const ffmpegPath = resolveFfmpeg(); // 若未找到则抛出异常

常用操作

将视频转码为 H.264/AAC MP4

$(node -e "process.stdout.write(require('ffmpeg-static'))") \
  -i input.mkv -c:v libx264 -crf 23 -preset fast \
  -c:a aac -b:a 128k output.mp4

在指定时间点提取缩略图

ffmpeg -ss 00:01:30 -i input.mp4 -frames:v 1 -q:v 2 thumb.jpg

将音频转换为 MP3

ffmpeg -i input.flac -q:a 2 output.mp3

仅提取音频流

ffmpeg -i input.mp4 -vn -c:a copy audio.aac

无重新编码剪辑

ffmpeg -ss 00:00:10 -to 00:01:00 -i input.mp4 -c copy trimmed.mp4

拼接多个文件

ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4

filelist.txt 格式:

file '/abs/path/clip1.mp4'
file '/abs/path/clip2.mp4'

缩放视频(保持宽高比)

ffmpeg -i input.mp4 -vf "scale=1280:-2" -c:a copy scaled.mp4

生成动态 GIF

ffmpeg -i input.mp4 -vf "fps=10,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif

HLS 流打包

ffmpeg -i input.mp4 -codec: copy -start_number 0 \
  -hls_time 10 -hls_list_size 0 -f hls output.m3u8

在 Node.js 中使用

基础 spawn 模式

const { spawn } = require('child_process');
const { resolveFfmpeg } = require('./scripts/resolve_ffmpeg');

function runFfmpeg(args) {
  return new Promise((resolve, reject) => {
    const proc = spawn(resolveFfmpeg(), args, { stdio: ['ignore', 'pipe', 'pipe'] });
    let stderr = '';
    proc.stderr.on('data', d => { stderr += d; });
    proc.on('close', code => code === 0 ? resolve() : reject(new Error(stderr)));
  });
}

// 示例:转码
await runFfmpeg([
  '-i', 'input.mp4',
  '-c:v', 'libx264', '-crf', '23',
  '-c:a', 'aac', '-b:a', '128k',
  'output.mp4'
]);

进度解析

FFmpeg 将进度信息输出到 stderr。可通过匹配 frame= 行,或使用 -progress pipe:1 参数进行解析:

proc.stderr.on('data', d => {
  const match = d.toString().match(/time=(\d{2}:\d{2}:\d{2})/);
  if (match) console.log('时间:', match[1]);
});

使用 fluent-ffmpeg(高级封装)

const ffmpeg = require('fluent-ffmpeg');
const ffmpegPath = require('./scripts/resolve_ffmpeg').resolveFfmpeg();
ffmpeg.setFfmpegPath(ffmpegPath);

ffmpeg('input.mp4')
  .output('output.mp4')
  .videoCodec('libx264')
  .audioCodec('aac')
  .on('end', () => console.log('完成'))
  .on('error', err => console.error(err))
  .run();

环境变量

变量作用
FFMPEG_PATH覆盖二进制路径;优先级高于系统和捆绑版本
FFPROBE_PATH覆盖 ffprobe 二进制路径
FFMPEG_STATIC_SKIP_BINARY_DOWNLOAD设置为 1 可跳过 npm install 期间的下载(适用于已有系统 FFmpeg 的场景)

最佳实践

1. 启动时仅解析一次二进制路径

在程序启动时调用一次 resolveFfmpeg() 并缓存结果 —— 不要在高频路径中重复调用 require('ffmpeg-static')

2. 无需重新编码时优先使用 -c copy

流复制(-c copy)速度极快且无损。仅在需要更改编解码器或应用滤镜时才进行解码与编码。

3. 使用 -ss 时置于 -i 之前以实现快速定位

-ss 00:01:00 -i input.mp4-i 之前)使用关键帧定位(快速)。而 -i input.mp4 -ss 00:01:00-i 之后)需从头解码(准确但对大文件较慢)。

4. 非交互式脚本中始终添加 -y

-y 参数可自动覆盖输出文件,无需用户确认。若不加此参数,FFmpeg 在 CI 或后台任务中会因等待 stdin 输入而挂起。

5. 构建命令数组前验证输入

切勿直接将用户提供的字符串插入 FFmpeg 参数。务必先通过 ffprobe 验证路径是否存在,并确认其为预期的媒体类型。

6. 硬件编码需依赖系统 FFmpeg

在启动时检查 ffmpeg -hwaccels,仅当系统 FFmpeg 二进制文件激活时才启用硬件加速相关路径。

7. 生产环境设置 -loglevel error

减少标准错误输出的噪音。调试失败的转码任务时,可重新启用详细日志(-loglevel verbose)。


支持的格式(内置二进制)

内置的 ffmpeg-static 二进制文件编译时包含广泛但固定的编码器集合。主要支持:

视频: H.264 (libx264)、H.265 (libx265)、VP8/VP9 (libvpx)、AV1 (libaom-av1)、MPEG-2/4、ProRes、DNxHD、Theora

音频: AAC(原生 + libfdk-aac,需授权)、MP3(libmp3lame)、Opus(libopus)、Vorbis、FLAC、PCM

容器格式: MP4、MKV、MOV、WebM、AVI、TS、HLS(m3u8)、DASH、FLV、GIF、APNG

图像格式: MJPEG、PNG、WebP(通过 lavf 支持)

硬件编码器(nvenc、qsv、vaapi、videotoolbox)不包含在内置二进制中。如需 GPU 加速,请使用系统安装的 FFmpeg。


故障排除

问题现象解决方法
Cannot find module 'ffmpeg-static'在项目根目录运行 npm install ffmpeg-static
Linux/macOS 上二进制文件不可执行执行 chmod +x $(node -e "process.stdout.write(require('ffmpeg-static'))")
Encoder libx264 not found内置二进制可能缺少该编码器;请安装系统 FFmpeg(apt install ffmpeg / brew install ffmpeg
输出路径不存在导致 No such file or directory运行 FFmpeg 前确保输出目录已存在
CI 环境中转码卡住添加 -y 参数以自动覆盖无需提示
无进度信息输出使用 -progress pipe:1 将进度数据写入 stdout
GIF 生成速度慢使用两阶段调色板生成方案(参见上方示例)
FFMPEG_STATIC_SKIP_BINARY_DOWNLOAD 环境变量被忽略请在运行 npm install 之前设置该环境变量,而非之后
F
@fantox

已收录 1 个 Skill

相关推荐