FFmpeg
CLI skill for local audio/video inspection and transformation via ffmpeg and ffprobe. Invoke as /ffmpeg.
Scope: Probe metadata, trim clips, transcode containers/codecs, concatenate segments, extract audio, capture thumbnails, and build GIF previews from files on disk. NOT for AI image or video generation (draw-thing), UI or layout design (design), networked downloads (yt-dlp), or broadcast/streaming pipelines.
Canonical Vocabulary
| Term |
Meaning |
NOT |
| probe |
Read-only ffprobe inspection |
transcode |
| trim |
Shorten by time range |
crop UI mockup |
| transcode |
Re-mux or re-encode to new container/codec |
generate new imagery |
| concat |
Join multiple inputs sequentially |
merge git branches |
| extract-audio |
Strip video, keep audio track |
speech-to-text |
| thumbnail |
Single still frame from video |
design a poster layout |
| gif |
Animated GIF preview from video clip |
CSS animation |
| stream copy |
-c copy without re-encode |
always safe for all trims |
| recipe |
Approved command template from references/ |
ad-hoc filter graph |
Dispatch
$ARGUMENTS |
Mode |
Action |
doctor / check / preflight |
Doctor |
Run PATH doctor; stop if ffmpeg/ffprobe missing |
probe <path> / info <path> / metadata <path> |
Probe |
Run probe helper; summarize streams and duration |
trim <path> <start> <end> / clip <path> ... |
Trim |
Probe, pick copy vs re-encode recipe, new output path |
transcode <path> / convert <path> to mp4 |
Transcode |
Probe codecs; apply H.264/AAC or copy recipe |
concat <file1> <file2> [...] / join ... |
Concat |
Verify probes; concat demuxer recipe + new output |
extract-audio <path> / audio <path> |
Extract audio |
Probe audio stream; MP3/M4A/copy recipe |
thumbnail <path> / thumb <path> [timestamp] |
Thumbnail |
Seek frame; write JPG/PNG to new path |
gif <path> / animate <path> [start] [duration] |
GIF |
Palette GIF recipe with duration cap |
| Path to media + natural language edit intent |
Auto |
Classify trim/transcode/thumbnail/gif from intent |
| (empty) |
Help |
Show modes, critical rules, script commands, references |
Auto-Detection Heuristic
- Install/tooling doubt → Doctor.
- "metadata", "codec", "duration", "how long", "what format" → Probe.
- "cut", "clip", "from ... to ...", time range → Trim.
- "mp4", "webm", "h264", "aac", "smaller", "compress" → Transcode.
- "join", "merge clips", "append videos" → Concat.
- "mp3", "wav", "m4a", "strip video", "audio only" → Extract audio.
- "poster frame", "screenshot", "still", "thumbnail" → Thumbnail.
- "gif", "animated preview" → GIF.
- Generative image/video language → refuse; redirect to
draw-thing.
- UI/page/layout design → refuse; redirect to
design.
- Ambiguous → ask which mode and state copy vs re-encode tradeoff.
Critical Rules
- Probe before mutate — run
probe_media.py on every source file before trim, transcode, concat, extract-audio, thumbnail, or gif. Use probe fields to choose maps, codecs, and duration bounds. See references/probe-fields.md.
- Never overwrite in-place (default) — always write to a new output path. In-place replace requires explicit user approval plus backup/temp-file replace. See
references/safety.md.
- Recipe-only mutations — build ffmpeg commands only from
references/recipes-trim-transcode.md and references/recipes-thumbnail-gif.md. No improvised filter chains or destructive batch jobs without approval.
Prerequisite Protocol
Run before any mutation:
uv run python scripts/doctor.py --format json
Stop when JSON ok is false. Install guidance:
brew install ffmpeg
For each input file:
uv run python scripts/probe_media.py /absolute/path/to/input.mp4
Parse summary.duration_seconds, summary.stream_counts, and codec fields before selecting a recipe.
Mode Protocols
Doctor
- Run
uv run python scripts/doctor.py --format json.
- Report
checks statuses and remediation for any fail.
- Do not run ffmpeg mutations when
ffmpeg-binary or ffprobe-binary fails.
Probe
- Require a readable local file path.
- Run
uv run python scripts/probe_media.py <path>.
- Summarize: container, duration, video/audio codecs, resolution, stream counts.
- Load
references/probe-fields.md when interpreting rotation, multi-track audio, or subtitle streams.
Trim
- Probe source; validate
start/end against duration_seconds.
- Prefer stream copy when keyframe alignment is acceptable; otherwise use re-encode trim recipe.
- Output to
basename.trim.ext or user-provided new path.
- Load
references/recipes-trim-transcode.md.
Transcode
- Probe source; decide copy vs H.264/AAC re-encode.
- Map explicit streams when multiple tracks exist.
- Include
-movflags +faststart for MP4 web delivery unless user forbids.
- Load
references/recipes-trim-transcode.md.
Concat
- Probe every segment; confirm compatible codecs/resolution for copy concat.
- Build concat list file with absolute paths; never concat unrelated codecs with copy without warning.
- Output to a new
*.concat.mp4 path.
- Load
references/recipes-trim-transcode.md.
Extract audio
- Probe source; fail gracefully when
stream_counts.audio is zero.
- Choose MP3, M4A, or copy recipe based on target format.
- Write
basename.audio.ext as a new file.
- Load
references/recipes-trim-transcode.md.
Thumbnail
- Probe source; require at least one video stream.
- Pick timestamp (user value, or 10% duration clamped 1–10s).
- Write JPG/PNG under
OUTPUT/ or sibling path — never overwrite source.
- Load
references/recipes-thumbnail-gif.md.
GIF
- Probe source; cap duration (default max 5s unless user expands).
- Use two-pass palette recipe for quality; single-pass only for quick previews.
- Write
clip.gif and optional palette.png as new files.
- Load
references/recipes-thumbnail-gif.md.
Help (empty)
Show dispatch table, critical rules, doctor/probe commands, reference index, and the gallery below.
Gallery (Empty Arguments)
Present common local media tasks when $ARGUMENTS is empty:
| # |
Task |
Example |
| 1 |
Preflight tooling |
/ffmpeg doctor |
| 2 |
Inspect metadata |
/ffmpeg probe ~/Movies/clip.mp4 |
| 3 |
Trim a clip |
/ffmpeg trim ~/Movies/clip.mp4 00:00:05 00:00:15 |
| 4 |
Transcode container |
/ffmpeg transcode ~/Movies/clip.mov |
| 5 |
Join segments |
/ffmpeg concat part1.mp4 part2.mp4 |
| 6 |
Extract audio |
/ffmpeg extract-audio ~/Movies/clip.mp4 |
| 7 |
Poster frame |
/ffmpeg thumbnail ~/Movies/clip.mp4 00:00:03 |
| 8 |
GIF preview |
/ffmpeg gif ~/Movies/clip.mp4 00:00:02 4 |
Pick a number, a mode from the dispatch table, or paste a file path and describe the edit.
Skill Awareness
| Signal |
Redirect |
| "generate an image", "txt2img", "AI video", local Draw Things |
draw-thing |
| "design a landing page", "Figma", "React layout" |
design |
| "download from YouTube/URL" |
yt-dlp |
| Live streaming, RTMP, OBS wiring |
out of scope — suggest streaming docs |
Reference Files
| File |
Load when |
references/safety.md |
Any mutation; in-place overwrite questions |
references/probe-fields.md |
Interpreting probe JSON |
references/recipes-trim-transcode.md |
trim, transcode, concat, extract-audio |
references/recipes-thumbnail-gif.md |
thumbnail, gif |
Scripts
| Script |
Purpose |
scripts/doctor.py |
Verify ffmpeg/ffprobe on PATH (--format json) |
scripts/probe_media.py |
ffprobe wrapper with summary (--raw for full payload) |
scripts/check.py |
Validate SKILL.md, evals, package dry-run, audit |
Validation:
uv run python scripts/check.py
Reporting Template
After any mutation, report:
- Doctor status (if run this session)
- Probe summary (duration, codecs, streams)
- Recipe name (copy vs re-encode)
- Exact ffmpeg command(s) executed
- Output path(s) and size change
- Caveats (keyframe trim, missing audio, GIF duration cap)
1---2name: ffmpeg3description: Probe, trim, transcode, concat, and extract local A/V with ffmpeg/ffprobe. Use when converting or inspecting media files. NOT for AI image generation (draw-thing) or UI design (design).4license: MIT5---67# FFmpeg89CLI skill for **local** audio/video inspection and transformation via `ffmpeg` and `ffprobe`. Invoke as `/ffmpeg`.1011**Scope:** Probe metadata, trim clips, transcode containers/codecs, concatenate segments, extract audio, capture thumbnails, and build GIF previews from files on disk. NOT for AI image or video generation (`draw-thing`), UI or layout design (`design`), networked downloads (`yt-dlp`), or broadcast/streaming pipelines.1213---1415## Canonical Vocabulary1617| Term | Meaning | NOT |18| --- | --- | --- |19| **probe** | Read-only ffprobe inspection | transcode |20| **trim** | Shorten by time range | crop UI mockup |21| **transcode** | Re-mux or re-encode to new container/codec | generate new imagery |22| **concat** | Join multiple inputs sequentially | merge git branches |23| **extract-audio** | Strip video, keep audio track | speech-to-text |24| **thumbnail** | Single still frame from video | design a poster layout |25| **gif** | Animated GIF preview from video clip | CSS animation |26| **stream copy** | `-c copy` without re-encode | always safe for all trims |27| **recipe** | Approved command template from `references/` | ad-hoc filter graph |2829---3031## Dispatch3233| `$ARGUMENTS` | Mode | Action |34| --- | --- | --- |35| `doctor` / `check` / `preflight` | **Doctor** | Run PATH doctor; stop if ffmpeg/ffprobe missing |36| `probe <path>` / `info <path>` / `metadata <path>` | **Probe** | Run probe helper; summarize streams and duration |37| `trim <path> <start> <end>` / `clip <path> ...` | **Trim** | Probe, pick copy vs re-encode recipe, new output path |38| `transcode <path>` / `convert <path> to mp4` | **Transcode** | Probe codecs; apply H.264/AAC or copy recipe |39| `concat <file1> <file2> [...]` / `join ...` | **Concat** | Verify probes; concat demuxer recipe + new output |40| `extract-audio <path>` / `audio <path>` | **Extract audio** | Probe audio stream; MP3/M4A/copy recipe |41| `thumbnail <path>` / `thumb <path> [timestamp]` | **Thumbnail** | Seek frame; write JPG/PNG to new path |42| `gif <path>` / `animate <path> [start] [duration]` | **GIF** | Palette GIF recipe with duration cap |43| Path to media + natural language edit intent | **Auto** | Classify trim/transcode/thumbnail/gif from intent |44| _(empty)_ | **Help** | Show modes, critical rules, script commands, references |4546### Auto-Detection Heuristic47481. Install/tooling doubt → **Doctor**.492. "metadata", "codec", "duration", "how long", "what format" → **Probe**.503. "cut", "clip", "from ... to ...", time range → **Trim**.514. "mp4", "webm", "h264", "aac", "smaller", "compress" → **Transcode**.525. "join", "merge clips", "append videos" → **Concat**.536. "mp3", "wav", "m4a", "strip video", "audio only" → **Extract audio**.547. "poster frame", "screenshot", "still", "thumbnail" → **Thumbnail**.558. "gif", "animated preview" → **GIF**.569. Generative image/video language → refuse; redirect to `draw-thing`.5710. UI/page/layout design → refuse; redirect to `design`.5811. Ambiguous → ask which mode and state copy vs re-encode tradeoff.5960---6162## Critical Rules63641. **Probe before mutate** — run `probe_media.py` on every source file before trim, transcode, concat, extract-audio, thumbnail, or gif. Use probe fields to choose maps, codecs, and duration bounds. See `references/probe-fields.md`.652. **Never overwrite in-place (default)** — always write to a new output path. In-place replace requires explicit user approval plus backup/temp-file replace. See `references/safety.md`.663. **Recipe-only mutations** — build ffmpeg commands only from `references/recipes-trim-transcode.md` and `references/recipes-thumbnail-gif.md`. No improvised filter chains or destructive batch jobs without approval.6768---6970## Prerequisite Protocol7172Run before any mutation:7374```bash75uv run python scripts/doctor.py --format json76```7778Stop when JSON `ok` is false. Install guidance:7980```bash81brew install ffmpeg82```8384For each input file:8586```bash87uv run python scripts/probe_media.py /absolute/path/to/input.mp488```8990Parse `summary.duration_seconds`, `summary.stream_counts`, and codec fields before selecting a recipe.9192---9394## Mode Protocols9596### Doctor97981. Run `uv run python scripts/doctor.py --format json`.992. Report `checks` statuses and remediation for any `fail`.1003. Do not run ffmpeg mutations when `ffmpeg-binary` or `ffprobe-binary` fails.101102### Probe1031041. Require a readable local file path.1052. Run `uv run python scripts/probe_media.py <path>`.1063. Summarize: container, duration, video/audio codecs, resolution, stream counts.1074. Load `references/probe-fields.md` when interpreting rotation, multi-track audio, or subtitle streams.108109### Trim1101111. Probe source; validate `start`/`end` against `duration_seconds`.1122. Prefer stream copy when keyframe alignment is acceptable; otherwise use re-encode trim recipe.1133. Output to `basename.trim.ext` or user-provided **new** path.1144. Load `references/recipes-trim-transcode.md`.115116### Transcode1171181. Probe source; decide copy vs H.264/AAC re-encode.1192. Map explicit streams when multiple tracks exist.1203. Include `-movflags +faststart` for MP4 web delivery unless user forbids.1214. Load `references/recipes-trim-transcode.md`.122123### Concat1241251. Probe every segment; confirm compatible codecs/resolution for copy concat.1262. Build concat list file with absolute paths; never concat unrelated codecs with copy without warning.1273. Output to a new `*.concat.mp4` path.1284. Load `references/recipes-trim-transcode.md`.129130### Extract audio1311321. Probe source; fail gracefully when `stream_counts.audio` is zero.1332. Choose MP3, M4A, or copy recipe based on target format.1343. Write `basename.audio.ext` as a new file.1354. Load `references/recipes-trim-transcode.md`.136137### Thumbnail1381391. Probe source; require at least one video stream.1402. Pick timestamp (user value, or 10% duration clamped 1–10s).1413. Write JPG/PNG under `OUTPUT/` or sibling path — never overwrite source.1424. Load `references/recipes-thumbnail-gif.md`.143144### GIF1451461. Probe source; cap duration (default max 5s unless user expands).1472. Use two-pass palette recipe for quality; single-pass only for quick previews.1483. Write `clip.gif` and optional `palette.png` as new files.1494. Load `references/recipes-thumbnail-gif.md`.150151### Help _(empty)_152153Show dispatch table, critical rules, doctor/probe commands, reference index, and the gallery below.154155### Gallery (Empty Arguments)156157Present common local media tasks when `$ARGUMENTS` is empty:158159| # | Task | Example |160| --- | --- | --- |161| 1 | Preflight tooling | `/ffmpeg doctor` |162| 2 | Inspect metadata | `/ffmpeg probe ~/Movies/clip.mp4` |163| 3 | Trim a clip | `/ffmpeg trim ~/Movies/clip.mp4 00:00:05 00:00:15` |164| 4 | Transcode container | `/ffmpeg transcode ~/Movies/clip.mov` |165| 5 | Join segments | `/ffmpeg concat part1.mp4 part2.mp4` |166| 6 | Extract audio | `/ffmpeg extract-audio ~/Movies/clip.mp4` |167| 7 | Poster frame | `/ffmpeg thumbnail ~/Movies/clip.mp4 00:00:03` |168| 8 | GIF preview | `/ffmpeg gif ~/Movies/clip.mp4 00:00:02 4` |169170> Pick a number, a mode from the dispatch table, or paste a file path and describe the edit.171172---173174## Skill Awareness175176| Signal | Redirect |177| --- | --- |178| "generate an image", "txt2img", "AI video", local Draw Things | `draw-thing` |179| "design a landing page", "Figma", "React layout" | `design` |180| "download from YouTube/URL" | `yt-dlp` |181| Live streaming, RTMP, OBS wiring | out of scope — suggest streaming docs |182183---184185## Reference Files186187| File | Load when |188| --- | --- |189| `references/safety.md` | Any mutation; in-place overwrite questions |190| `references/probe-fields.md` | Interpreting probe JSON |191| `references/recipes-trim-transcode.md` | trim, transcode, concat, extract-audio |192| `references/recipes-thumbnail-gif.md` | thumbnail, gif |193194---195196## Scripts197198| Script | Purpose |199| --- | --- |200| `scripts/doctor.py` | Verify ffmpeg/ffprobe on PATH (`--format json`) |201| `scripts/probe_media.py` | ffprobe wrapper with summary (`--raw` for full payload) |202| `scripts/check.py` | Validate SKILL.md, evals, package dry-run, audit |203204Validation:205206```bash207uv run python scripts/check.py208```209210---211212## Reporting Template213214After any mutation, report:2152161. Doctor status (if run this session)2172. Probe summary (duration, codecs, streams)2183. Recipe name (copy vs re-encode)2194. Exact ffmpeg command(s) executed2205. Output path(s) and size change2216. Caveats (keyframe trim, missing audio, GIF duration cap)