ffmpeg-static
v1.0.2FFmpeg operations via the ffmpeg-static npm package (bundled binary) with automatic fallback to a native system FFmpeg installation. Use for: video/audio tra...
Like a lobster shell, security has layers — review code before you run it.
Runtime requirements
FFmpeg Static Skill
This 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.
Security Notice
ffmpeg-staticdownloads pre-built binaries from GitHub Releases duringnpm install. Verify the package on npmjs.com/package/ffmpeg-static.- Never pipe untrusted filenames or URLs into FFmpeg commands without validation — FFmpeg can read from URLs and arbitrary protocols.
- The bundled binary does not include GPU-accelerated encoders (nvenc, vaapi, videotoolbox). For hardware acceleration, use the system FFmpeg.
Installation
Minimum install (bundled FFmpeg binary only)
npm install ffmpeg-static
Project install with ffprobe (recommended)
npm install ffmpeg-static ffprobe-static
Verify the binary path
node -e "console.log(require('ffmpeg-static'))"
# e.g. /path/to/node_modules/ffmpeg-static/ffmpeg
Check resolved binary (bundled vs. system)
node scripts/resolve_ffmpeg.js
Binary Resolution Logic
The skill resolves the FFmpeg binary in this priority order:
FFMPEG_PATHenv var — explicit override, always wins- System FFmpeg — found by walking
PATHdirectories withfs.accessSync; preferred when present (newer codecs, hardware acceleration) - Bundled binary —
require('ffmpeg-static')absolute path; guaranteed to exist afternpm install
// Canonical resolution — use this pattern in all scripts
const { resolveFfmpeg } = require('./scripts/resolve_ffmpeg');
const ffmpegPath = resolveFfmpeg(); // throws if none found
Common Operations
Transcode video to 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
Extract thumbnail at timestamp
ffmpeg -ss 00:01:30 -i input.mp4 -frames:v 1 -q:v 2 thumb.jpg
Convert audio to MP3
ffmpeg -i input.flac -q:a 2 output.mp3
Extract audio stream only
ffmpeg -i input.mp4 -vn -c:a copy audio.aac
Trim without re-encoding
ffmpeg -ss 00:00:10 -to 00:01:00 -i input.mp4 -c copy trimmed.mp4
Concatenate files
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'
Scale video (maintain aspect ratio)
ffmpeg -i input.mp4 -vf "scale=1280:-2" -c:a copy scaled.mp4
Generate animated 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 stream packaging
ffmpeg -i input.mp4 -codec: copy -start_number 0 \
-hls_time 10 -hls_list_size 0 -f hls output.m3u8
Using From Node.js
Copy-paste patterns are in templates/node_patterns.txt. Key steps:
- Resolve the binary using
scripts/resolve_ffmpeg.js(purefs, no shell calls) - Spawn FFmpeg in your own project code using Node's
child_process.spawn - Or use
fluent-ffmpeg— pass the resolved path viaffmpeg.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.
Environment Variables
| 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) |
Best Practices
1. Always resolve the binary once at startup
Call resolveFfmpeg() once and cache the result — don't call require('ffmpeg-static') inline in hot paths.
2. Prefer -c copy when no re-encoding is needed
Stream copy (-c copy) is instantaneous and lossless. Only decode/encode when you actually need to change the codec or apply filters.
3. Use -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).
4. Always pass -y in non-interactive scripts
-y overwrites output without prompting. Without it, FFmpeg hangs waiting for stdin in CI or background processes.
5. Validate inputs before building command arrays
Never interpolate user-supplied strings directly into FFmpeg args. Always validate paths exist and are the expected media type using ffprobe first.
6. For hardware encoding, require system FFmpeg
Check ffmpeg -hwaccels at startup and gate hardware-accelerated paths on the system binary being active.
7. Set -loglevel error in production
Reduces stderr noise. Re-enable verbose logging (-loglevel verbose) when debugging a failed transcode.
Supported Formats (Bundled Binary)
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.
Troubleshooting
| 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 |
Comments
Loading comments...
