ffmpeg
Transform audio and video files with ffmpeg and inspect
them with ffprobe. Operations are non-destructive: always write to a new
output file. Re-encoding can be slow on long media — set realistic expectations.
Setup health check (run first, every session)
Verify with one solo step:
[{ "tool": "os.shell.run", "args": { "cmd": "ffmpeg", "args": ["-version"] } }]
Outcome map:
exit 0 + version → ready, proceed.
command not found: ffmpeg → enter Setup playbook → "ffmpeg missing".
Setup playbook (when prerequisites are missing)
ffmpeg missing
Reply (solo reply step):
«ffmpeg не установлен. Могу поставить: brew install ffmpeg. Поставить?»
On yes:
[{ "tool": "os.shell.run", "args": { "cmd": "brew", "args": ["install", "ffmpeg"] } }]
On Linux: apt-get install ffmpeg.
On Windows, offer this exact winget command after confirmation:
[{ "tool": "os.shell.run", "args": { "cmd": "winget", "args": ["install", "--id", "Gyan.FFmpeg", "-e"] } }]
When to use
- "Convert this video/audio to ", "extract the audio from this mp4".
- "Trim from 0:30 to 1:00", "resize to 720p", "make a GIF from this clip".
- "What codec / duration / resolution is this file?" (use
ffprobe).
When NOT to use
- Downloading media from URLs — that's
yt-dlp territory (separate skill).
- Still-image editing — use the
imagemagick skill.
- Lossless container-only edits where a remux suffices — still fine here, just
use
-c copy to avoid re-encoding.
Common operations
All examples invoke os.shell.run. Inspect first with ffprobe; the approval
gate surfaces each write. Use -c copy to remux without re-encoding when only
the container changes.
| Goal |
cmd / args |
| Inspect media |
ffprobe ["-hide_banner", "in.mp4"] |
| Convert MOV → MP4 |
ffmpeg ["-i", "in.mov", "-c:v", "libx264", "-c:a", "aac", "out.mp4"] |
| Extract audio (MP3) |
ffmpeg ["-i", "in.mp4", "-vn", "-q:a", "2", "out.mp3"] |
| Trim (start 30s, 30s long) |
ffmpeg ["-ss", "00:00:30", "-i", "in.mp4", "-t", "30", "-c", "copy", "clip.mp4"] |
| Resize to 720p |
ffmpeg ["-i", "in.mp4", "-vf", "scale=-2:720", "out_720p.mp4"] |
| Video → GIF |
ffmpeg ["-i", "in.mp4", "-vf", "fps=12,scale=480:-1", "out.gif"] |
| Extract one frame |
ffmpeg ["-ss", "00:00:05", "-i", "in.mp4", "-frames:v", "1", "frame.png"] |
| Remux only (fast) |
ffmpeg ["-i", "in.mkv", "-c", "copy", "out.mp4"] |
Rules
- Always write to a NEW output path; never overwrite the source.
- Inspect with
ffprobe first when unsure of codecs/duration/resolution.
- Warn the user that long re-encodes can take a while; prefer
-c copy when
only the container changes.
- Echo the output path (and
ffprobe duration if relevant) after each run.
1---2name: ffmpeg3description: Process audio and video with the `ffmpeg` / `ffprobe` CLIs — convert, trim, extract audio, resize, change format, make GIFs, inspect media. Use for any audio/video transformation.4---5
6# ffmpeg
7
8Transform audio and video files with [`ffmpeg`](https://ffmpeg.org/) and inspect
9them with `ffprobe`. Operations are non-destructive: always write to a new
10output file. Re-encoding can be slow on long media — set realistic expectations.
11
12## Setup health check (run first, every session)
13
14Verify with **one solo step**:
15
16```
17[{ "tool": "os.shell.run", "args": { "cmd": "ffmpeg", "args": ["-version"] } }]
18```
19
20Outcome map:
21- `exit 0` + version → ready, proceed.
22- `command not found: ffmpeg` → enter **Setup playbook → "ffmpeg missing"**.
23
24## Setup playbook (when prerequisites are missing)
25
26### ffmpeg missing
27
28Reply (solo `reply` step):
29
30> «`ffmpeg` не установлен. Могу поставить: `brew install ffmpeg`. Поставить?»
31
32On yes:
33
34```
35[{ "tool": "os.shell.run", "args": { "cmd": "brew", "args": ["install", "ffmpeg"] } }]
36```
37
38On Linux: `apt-get install ffmpeg`.
39
40On Windows, offer this exact winget command after confirmation:
41
42```
43[{ "tool": "os.shell.run", "args": { "cmd": "winget", "args": ["install", "--id", "Gyan.FFmpeg", "-e"] } }]
44```
45
46## When to use
47
48- "Convert this video/audio to <format>", "extract the audio from this mp4".
49- "Trim from 0:30 to 1:00", "resize to 720p", "make a GIF from this clip".
50- "What codec / duration / resolution is this file?" (use `ffprobe`).
51
52## When NOT to use
53
54- Downloading media from URLs — that's `yt-dlp` territory (separate skill).
55- Still-image editing — use the `imagemagick` skill.
56- Lossless container-only edits where a remux suffices — still fine here, just
57 use `-c copy` to avoid re-encoding.
58
59## Common operations
60
61All examples invoke `os.shell.run`. Inspect first with `ffprobe`; the approval
62gate surfaces each write. Use `-c copy` to remux without re-encoding when only
63the container changes.
64
65| Goal | cmd / args |
66|---|---|
67| Inspect media | `ffprobe` `["-hide_banner", "in.mp4"]` |
68| Convert MOV → MP4 | `ffmpeg` `["-i", "in.mov", "-c:v", "libx264", "-c:a", "aac", "out.mp4"]` |
69| Extract audio (MP3) | `ffmpeg` `["-i", "in.mp4", "-vn", "-q:a", "2", "out.mp3"]` |
70| Trim (start 30s, 30s long) | `ffmpeg` `["-ss", "00:00:30", "-i", "in.mp4", "-t", "30", "-c", "copy", "clip.mp4"]` |
71| Resize to 720p | `ffmpeg` `["-i", "in.mp4", "-vf", "scale=-2:720", "out_720p.mp4"]` |
72| Video → GIF | `ffmpeg` `["-i", "in.mp4", "-vf", "fps=12,scale=480:-1", "out.gif"]` |
73| Extract one frame | `ffmpeg` `["-ss", "00:00:05", "-i", "in.mp4", "-frames:v", "1", "frame.png"]` |
74| Remux only (fast) | `ffmpeg` `["-i", "in.mkv", "-c", "copy", "out.mp4"]` |
75
76## Rules
77
781. Always write to a NEW output path; never overwrite the source.
792. Inspect with `ffprobe` first when unsure of codecs/duration/resolution.
803. Warn the user that long re-encodes can take a while; prefer `-c copy` when
81 only the container changes.
824. Echo the output path (and `ffprobe` duration if relevant) after each run.