FFmpeg is not one program — it's a suite of tools. The three you'll use daily are:
- `ffmpeg` – the conversion and processing engine.
- `ffprobe` – the media inspector.
- `ffplay` – the lightweight media player and filter debugger.
Under the hood, they all share the same libraries (libavcodec, libavformat, libavfilter). Once you understand the command syntax and stream specifiers, you unlock the full power of FFmpeg.
Key takeaways
- ffmpeg syntax:
ffmpeg [global] [input] [filters] [output]— order matters. - Stream specifiers (e.g.,
:a:1,:v:0) let you target specific streams for codec, bitrate, or mapping. - Putting
-ssbefore-imakes seeking fast; putting it after makes it frame‑accurate. ffprobe -show_format -show_streams -of jsonis the ultimate scriptable inspection tool.ffplaycan preview complex filter graphs without writing a file.
Part 1: The `ffmpeg` command syntax
The general structure of every ffmpeg command is:
ffmpeg [global options] [input options] -i input [filter options] [output options] output
But the most important rule is: order is not arbitrary. Options are applied at the moment they are parsed. Let's break it down.
Input options vs. output options
- Before
-i→ applies to that specific input file (e.g.,-ss 00:10before-iseeks in the input). - After
-i→ applies to the output file (e.g.,-c:v libx264sets the output encoder). - Global → applies to the whole command (e.g.,
-yto overwrite,-loglevel).
Example: the crucial `-ss` position
This is the most common pitfall for beginners.
# Fast seek (input option) — starts at keyframe, instant ffmpeg -ss 00:10 -i input.mp4 -t 5 -c copy clip.mp4 # Frame‑accurate seek (output option) — decodes from start, slow but precise ffmpeg -i input.mp4 -ss 00:10 -t 5 -c:v libx264 clip.mp4
When -ss is before -i, FFmpeg uses fast seeking. It jumps to the nearest keyframe (instant, no decoding). When -ss is after -i, FFmpeg decodes everything from the start until it reaches the timestamp (slow, but frame‑accurate). Use the first one for lossless -c copy cuts; use the second only when you need exact frame precision and are re‑encoding.
Common global and output options
-y– overwrite output file without asking.-n– never overwrite output file.-loglevel error– only show errors (cleaner output).-hide_banner– hide the compilation banner.-stats– show encoding progress (enabled by default).-map 0– copy all streams from the first input.-map 0:v:0– copy only the first video stream.-c copy– copy all streams without re‑encoding (stream copy).-c:v libx264– set video codec.-c:a aac– set audio codec.-b:v 2M– set video bitrate to 2 Mbps.-f mp4– force the output container format.
Part 2: Stream specifiers — the superpower you've been missing
A stream specifier is a suffix you attach to an option (e.g., -c, -b, -map) to tell FFmpeg which specific streams you want to target.
The syntax is option:stream_specifier.
Basic stream specifier syntax
| Specifier | Meaning | Example |
|---|---|---|
:v | All video streams | -c:v libx264 |
:a | All audio streams | -b:a 128k |
:s | All subtitle streams | -c:s copy |
:d | All data streams | -map 0:d |
:v:0 | First video stream (index 0) | -c:v:0 libx264 |
:a:1 | Second audio stream (index 1) | -c:a:1 aac |
:s:2 | Third subtitle stream | -c:s:2 mov_text |
:v:0,a:0 | Video 0 and Audio 0 (combined) | -map 0:v:0 -map 0:a:0 |
:m:language:eng | Streams with English language tag | -c:m:language:eng copy |
Practical stream specifier examples
# Re‑encode video to H.265, but copy audio & subtitles as‑is ffmpeg -i input.mkv -c:v libx265 -crf 24 -c:a copy -c:s copy output.mkv # Set a lower bitrate for the second audio stream only ffmpeg -i input.mkv -c:a:0 copy -b:a:1 96k -c:a:2 copy output.mkv # Map only the first video and the second audio from input 0 ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -c copy output.mp4 # Copy all video streams, but only English subtitles ffmpeg -i input.mkv -c:v copy -c:s:m:language:eng copy output.mkv
To see which streams are available in a file (and their indexes), use:
ffmpeg -i input.mkv
This prints a detailed list of streams with their indices. For example: Stream #0:0[0x1](eng): Video: h264 ... means :v:0 or :a:0 depending on the type.
Part 3: ffprobe — the media inspector
ffprobe is the Swiss Army knife for inspecting media files. It reads the container, streams, packets, and frames without decoding the video, making it incredibly fast.
Basic ffprobe usage
# Show all streams, metadata, and format info ffprobe input.mp4 # Show only the container format ffprobe -show_format input.mp4 # Show only the streams (video/audio/subtitle) ffprobe -show_streams input.mp4 # Show frame-by-frame information (can be huge) ffprobe -show_frames input.mp4 # Show only video streams ffprobe -select_streams v -show_streams input.mp4
Output formats for scripting
ffprobe shines when you need to parse its output programmatically. Use -of (or -print_format) to choose the output format.
# JSON output (excellent for Python/Node.js) ffprobe -v quiet -print_format json -show_format -show_streams input.mp4 # XML output ffprobe -v quiet -print_format xml -show_format input.mp4 # CSV output (for spreadsheets) ffprobe -v quiet -of csv -select_streams v -show_entries stream=codec_name,width,height input.mp4 # Compact, human‑friendly ffprobe -v quiet -of default=noprint_wrappers=1 -show_entries format=format_name,duration input.mp4
Common ffprobe tasks
- Get duration:
ffprobe -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4 - Get resolution:
ffprobe -v quiet -select_streams v:0 -show_entries stream=width,height -of csv=p=0 input.mp4 - Get codec details:
ffprobe -v quiet -select_streams v:0 -show_entries stream=codec_name,profile,level -of default=noprint_wrappers=1 input.mp4 - Get bitrate:
ffprobe -v quiet -show_entries format=bit_rate -of default=noprint_wrappers=1:nokey=1 input.mp4
Use ffprobe when you need to build automated workflows — it's the foundation of FFmpegLab's media analysis.
Part 4: ffplay — the interactive player and filter debugger
ffplay is a simple media player built on top of FFmpeg. It's not meant to replace VLC or MPC‑HC. Instead, it's a debugging and prototyping tool for filters, seeking, and raw stream analysis.
Basic playback
# Play a video with sound ffplay input.mp4 # Play only audio ffplay -nodisp input.mp3 # Play at half speed ffplay -vf "setpts=2.0*PTS" input.mp4
Previewing filters in real‑time
This is where ffplay truly shines. Instead of encoding a file to test a complex filter chain, you can preview it instantly.
# Test a scale + crop + fade filter live ffplay -vf "scale=640:-1,crop=640:360,format=gray,fade=t=in:st=0:d=2" input.mp4 # Test audio filters (speed up audio) ffplay -af "atempo=2.0" input.mp4
ffplay keyboard shortcuts
| Key | Action |
|---|---|
| f | Toggle fullscreen |
| s | Step frame‑by‑frame (pause first) |
| Space | Pause / resume |
| Left / Right | Seek backward / forward 10 seconds |
| Down / Up | Seek backward / forward 1 minute |
| m | Mute / unmute |
| q or ESC | Quit |
ffplay is also useful for testing stream selection and raw YUV/PCM data. For example, to play the raw video stream without audio: ffplay -vn -nodisp input.mp4 (audio only).
Cheat sheet: quick reference
| Task | Command |
|---|---|
| Remux MP4 → MKV (lossless) | ffmpeg -i input.mp4 -c copy output.mkv |
| Encode H.265 with CRF 24 | ffmpeg -i input.mov -c:v libx265 -crf 24 -c:a aac output.mp4 |
| Copy only first video + second audio | ffmpeg -i input.mkv -map 0:v:0 -map 0:a:1 -c copy output.mkv |
| Fast lossless cut from 1:05 to 1:35 | ffmpeg -ss 00:01:05 -i input.mp4 -to 00:01:35 -c copy clip.mp4 |
| Frame‑accurate cut (re‑encode) | ffmpeg -i input.mp4 -ss 00:01:05 -to 00:01:35 -c:v libx264 -crf 18 clip.mp4 |
| Inspect file in JSON | ffprobe -v quiet -print_format json -show_format -show_streams input.mp4 |
| Preview grayscale + fade with ffplay | ffplay -vf "format=gray,fade=t=out:st=5:d=3" input.mp4 |
Putting it all together
Once you understand the syntax, the stream specifiers, and the positioning of options, you stop guessing. You know exactly why a command works—or why it fails.
These fundamentals power every tutorial on this site. Pair this knowledge with our Complete Codecs Guide to choose the right encoder, and the Complete Formats Guide to pick the right container.
Ready to put this into practice with a visual interface? FFmpegLab gives you a timeline and property panels that generate these exact commands for you — while running entirely offline.