Install
openclaw skills install ffmpeg-staticFFmpeg operations via the ffmpeg-static npm package (bundled binary) with automatic fallback to a native system FFmpeg installation. Use for: video/audio tra...
openclaw skills install ffmpeg-staticThis skill wires ffmpeg-static — a self-contained FFmpeg binary distributed as an npm package — into every assistant interaction. When a native system FFmpeg is also installed, the skill prefers the system binary (usually newer and GPU-capable); otherwise it falls back to the bundled one. All FFmpeg capabilities are available in both paths.
No PATH manipulation needed.
require('ffmpeg-static')returns the absolute path to the binary; scripts pass it directly tochild_process.spawn.
ffmpeg-static downloads pre-built binaries from GitHub Releases during npm install. Verify the package on npmjs.com/package/ffmpeg-static.npm install ffmpeg-static
npm install ffmpeg-static ffprobe-static
node -e "console.log(require('ffmpeg-static'))"
# e.g. /path/to/node_modules/ffmpeg-static/ffmpeg
node scripts/resolve_ffmpeg.js
The skill resolves the FFmpeg binary in this priority order:
FFMPEG_PATH env var — explicit override, always winsPATH directories with fs.accessSync; preferred when present (newer codecs, hardware acceleration)require('ffmpeg-static') absolute path; guaranteed to exist after npm install// Canonical resolution — use this pattern in all scripts
const { resolveFfmpeg } = require('./scripts/resolve_ffmpeg');
const ffmpegPath = resolveFfmpeg(); // throws if none found
$(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
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 format:
file '/abs/path/clip1.mp4'
file '/abs/path/clip2.mp4'
ffmpeg -i input.mp4 -vf "scale=1280:-2" -c:a copy scaled.mp4
ffmpeg -i input.mp4 -vf "fps=10,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif
ffmpeg -i input.mp4 -codec: copy -start_number 0 \
-hls_time 10 -hls_list_size 0 -f hls output.m3u8
Copy-paste patterns are in templates/node_patterns.txt. Key steps:
scripts/resolve_ffmpeg.js (pure fs, no shell calls)child_process.spawnfluent-ffmpeg — pass the resolved path via ffmpeg.setFfmpegPath()// In YOUR project (not inside the skill)
const { resolveFfmpeg } = require('ffmpeg-static-skill/scripts/resolve_ffmpeg');
const ffmpegBin = resolveFfmpeg(); // absolute path, ready to pass to spawn or fluent-ffmpeg
See templates/node_patterns.txt for ready-to-copy spawn, progress, ffprobe, and fluent-ffmpeg snippets.
| Variable | Effect |
|---|---|
FFMPEG_PATH | Override binary path; takes precedence over system and bundled |
FFPROBE_PATH | Override ffprobe binary path |
FFMPEG_STATIC_SKIP_BINARY_DOWNLOAD | Set to 1 to skip download during npm install (use with system FFmpeg) |
Call resolveFfmpeg() once and cache the result — don't call require('ffmpeg-static') inline in hot paths.
-c copy when no re-encoding is neededStream copy (-c copy) is instantaneous and lossless. Only decode/encode when you actually need to change the codec or apply filters.
-ss before -i for fast seeking-ss 00:01:00 -i input.mp4 (before -i) uses keyframe seeking (fast). -i input.mp4 -ss 00:01:00 (after -i) decodes from the start (accurate but slow for large files).
-y in non-interactive scripts-y overwrites output without prompting. Without it, FFmpeg hangs waiting for stdin in CI or background processes.
Never interpolate user-supplied strings directly into FFmpeg args. Always validate paths exist and are the expected media type using ffprobe first.
Check ffmpeg -hwaccels at startup and gate hardware-accelerated paths on the system binary being active.
-loglevel error in productionReduces stderr noise. Re-enable verbose logging (-loglevel verbose) when debugging a failed transcode.
The bundled ffmpeg-static binary is compiled with a broad but fixed set of codecs. Key inclusions:
Video: H.264 (libx264), H.265 (libx265), VP8/VP9 (libvpx), AV1 (libaom-av1), MPEG-2/4, ProRes, DNxHD, Theora
Audio: AAC (native + libfdk-aac where licensed), MP3 (libmp3lame), Opus (libopus), Vorbis, FLAC, PCM
Containers: MP4, MKV, MOV, WebM, AVI, TS, HLS (m3u8), DASH, FLV, GIF, APNG
Images: MJPEG, PNG, WebP (via lavf)
Hardware encoders (nvenc, qsv, vaapi, videotoolbox) are not in the bundled binary. Use the system FFmpeg for GPU acceleration.
| Symptom | Fix |
|---|---|
Cannot find module 'ffmpeg-static' | Run npm install ffmpeg-static in the project root |
| Binary not executable on Linux/macOS | Run chmod +x $(node -e "process.stdout.write(require('ffmpeg-static'))") |
Encoder libx264 not found | Bundled binary may lack the codec; install system FFmpeg (apt install ffmpeg / brew install ffmpeg) |
No such file or directory on output | Ensure the output directory exists before running FFmpeg |
| Transcode hangs in CI | Add -y flag to overwrite without prompting |
| Progress not reported | Use -progress pipe:1 to write progress data to stdout |
| Slow GIF generation | Use the two-pass palettegen approach (see example above) |
FFMPEG_STATIC_SKIP_BINARY_DOWNLOAD ignored | Set the env var before running npm install, not after |