Why another FFmpeg options reference?
The output of ffmpeg -h full is over 7,000 lines. A GitHub gist of the same dump has 469 stars, which tells you two things: developers need this reference, and nobody wants to read raw help output.
This guide organizes the FFmpeg options and flags you'll actually use into categories, with syntax, real examples, and notes on when each flag matters. It covers the options that show up in 95% of real commands. Not exhaustive on purpose. That's what the official docs are for.
If you're new to FFmpeg entirely, start with the command line tutorial for installation and basic syntax. If you want full command recipes instead of individual flags, the cheat sheet has 50 copy-paste commands organized by task.
How FFmpeg options work
FFmpeg options follow a strict ordering that trips people up constantly.
Three rules:
Global options go first, before any
-i.Input options go directly before the
-ithey apply to.Output options go after all inputs but before the output filename.
Get the order wrong and FFmpeg either ignores your flag or applies it to the wrong file. The -ss flag is the classic example: put it before -i and it seeks the input (fast, approximate). Put it after -i and it trims the output (slow, frame-accurate). The trim guide covers this in detail.
You can verify what FFmpeg options and codecs your build supports:
That last one is useful when you can't remember the exact name of a codec option. It dumps every flag the encoder accepts with descriptions.
Global options
These apply to the entire FFmpeg process, not to any specific input or output.
-y — overwrite without asking
Without -y, FFmpeg prompts for confirmation if the output file exists. Add this to any script or automation pipeline. Forgetting it is a common reason cron jobs and CI pipelines hang forever because FFmpeg sits there waiting for input that never comes.
-n — never overwrite
Opposite of -y. If the output exists, FFmpeg exits immediately with code 1. Useful for batch jobs where you want to skip already-processed files without wasting cycles.
-v / -loglevel — control output verbosity
Levels, from most to least verbose: debug, verbose, info (default), warning, error, fatal, quiet. Use -v error in scripts to suppress progress output and only surface problems. Add +repeat to see repeated log messages: -v warning+repeat.
You can combine a level with +repeat or +level suffixes:
-hide_banner — suppress build info
Skips the FFmpeg version, build config, and library versions that print on every run. Doesn't affect actual processing. Most developers alias ffmpeg to ffmpeg -hide_banner in their shell config:
-stats / -nostats — progress reporting
-stats is on by default (that's the frame= 1234 fps=60 ... line you see). Turn it off with -nostats when you're piping FFmpeg output or logging to a file. The stats line includes speed=2.5x, which tells you encoding is running at 2.5x realtime. Handy for estimating how long a job will take.
-progress — machine-readable progress
Outputs key=value pairs you can parse in scripts. Each update includes frame, fps, total_size, out_time, speed, and progress (which reads continue during encoding and end when finished). More reliable than parsing the stats line with regex.
Input options
These go directly before the -i flag and affect how FFmpeg reads the input.
-i — input file
You can specify multiple inputs. Each gets an index starting from 0. Use -map (covered below) to pick which streams from which inputs end up in the output. URLs work too:
-f — force input format
FFmpeg usually detects the format automatically. Force it when dealing with raw streams, pipes, or when auto-detection gets it wrong. The formats guide covers all supported containers and when you'd need to specify one explicitly.
-ss (before -i) — seek to start time
When placed before -i, this seeks the input at the demuxer level. It's fast because FFmpeg jumps to the nearest keyframe instead of decoding every frame from the start. The tradeoff: your start time might be off by a fraction of a second (up to one GOP length, typically 2-10 seconds for most content).
Put -ss after -i for frame-accurate seeking at the cost of speed. The trim video guide has benchmarks comparing both approaches.
Accepted time formats:
-t — limit duration
Stops reading/writing after 30 seconds. Works as both input and output option. Accepts seconds (30) or timestamp format (00:00:30).
-to — stop at timestamp
Unlike -t (duration), -to specifies an absolute time to stop. Watch out: when -ss is before -i, -to becomes relative to the seek point, which makes it behave like -t. This is the single most confusing quirk in FFmpeg.
-stream_loop — loop input
Loops the input a specified number of times. -stream_loop -1 loops forever (useful for streaming). Only works with formats that support seeking.
-re — read input at native frame rate
Without -re, FFmpeg reads the input as fast as possible. With it, FFmpeg reads at the file's native speed (1x realtime). You need this for live streaming. Without it, FFmpeg would dump the entire file to the streaming server in seconds.
Output options: video
-c:v / -vcodec — video codec
Selects the video encoder. These are the codecs you'll run into most often:
| Codec | Flag | Use case |
| H.264 | libx264 | Maximum compatibility |
| H.265 | libx265 | 50% smaller at same quality |
| AV1 | libsvtav1 | Best compression, slow encode |
| VP9 | libvpx-vp9 | WebM containers |
| Copy | copy | No re-encoding (instant) |
Use copy when you just need to change the container or trim on keyframes. It's the difference between a 2-second remux and a 15-minute encode. The formats guide explains when container changes alone are enough, and the transcoding guide covers choosing between these codecs.
-b:v — video bitrate
Sets a target bitrate. 2M = 2 megabits/sec. Suffixes: K (kilobits), M (megabits). Works for both CBR and as a target for ABR. For most use cases, CRF (below) produces better results because it adapts to scene complexity.
-crf — constant rate factor
CRF is the simplest way to control quality. Lower numbers mean higher quality and bigger files. The scale depends on the codec:
H.264: 0-51, default 23. Visually lossless around 18.
H.265: 0-51, default 28. Visually lossless around 22.
AV1 (SVT-AV1): 0-63, default 35.
CRF 23 for H.264 is the sweet spot for most content. You rarely need to go lower unless you're archiving source footage. The compression guide has side-by-side file size comparisons across CRF values and explains when to use CRF vs two-pass bitrate targeting.
CRF values aren't comparable across codecs. CRF 23 in libx264 and CRF 28 in libx265 produce roughly similar visual quality. People set CRF 23 in libx265 expecting the same result as libx264 and end up with files much larger than they expected.
-preset — encoding speed vs compression
Controls how much time the encoder spends optimizing compression. Options from fastest to slowest: ultrafast, superfast, veryfast, faster, fast, medium (default), slow, slower, veryslow.
Slower presets produce smaller files at the same CRF. The difference between medium and slow is typically 5-10% smaller output. Between medium and ultrafast, it can be 2-3x. For batch processing, medium is the right tradeoff. For a single important encode, slow is worth the wait. Don't bother with placebo. The name is accurate.
H.265 uses the same preset names. NVENC uses a different scale (p1 through p7). The GPU acceleration guide covers NVENC presets and benchmarks.
-tune — optimize for content type
Adjusts encoder settings for specific content types:
| Tune | Best for |
film | Live-action footage with grain |
animation | Cartoons, anime, flat areas |
grain | Preserve film grain explicitly |
stillimage | Slideshow-style content |
fastdecode | Low-power playback devices |
zerolatency | Live streaming, real-time |
zerolatency disables B-frames and reduces lookahead, which cuts latency but hurts compression. Only use it when latency actually matters (live streaming, video conferencing).
-profile:v and -level — compatibility constraints
Profiles restrict which encoder features are used. baseline (no B-frames, no CABAC) for old devices. main for most streaming. high (default) for maximum compression. Level sets resolution and bitrate caps, so 4.1 supports up to 1080p@30fps or 720p@60fps.
You rarely need to set these unless targeting specific devices (smart TVs, old phones, hardware decoders with limited feature sets).
-pix_fmt — pixel format
Sets the chroma subsampling. yuv420p is what browsers and most players expect. ProRes and some camera formats use yuv422p or yuv444p, which look better but aren't widely supported for playback. If your video shows a black screen in some players, wrong pixel format is usually why.
-r — frame rate
Sets the output frame rate. FFmpeg duplicates or drops frames to match. As an input option before -i, it forces the input frame rate (only useful for raw formats or image sequences).
-s — resolution
Shorthand for resizing. Equivalent to -vf scale=1280:720. If you need to preserve aspect ratio, use the scale filter directly:
The -1 tells FFmpeg to calculate the height automatically. Use -2 instead of -1 to ensure the result is divisible by 2 (required by H.264/H.265).
-aspect — display aspect ratio
Sets the display aspect ratio metadata. Doesn't resize pixels, just tells the player how to display them. Use this when the file's SAR (sample aspect ratio) is wrong and the video looks stretched.
-vn — disable video
Drops all video streams. Use when extracting audio.
-g — keyframe interval (GOP size)
Sets the maximum number of frames between keyframes. Default is 250 (about 10 seconds at 25fps). For streaming, use fps * 2 (e.g., -g 60 for 30fps) so the player can seek to any 2-second point. For HLS/DASH, set this to match your segment duration for clean segment boundaries.
Output options: audio
-c:a / -acodec — audio codec
Common audio codecs: aac (MP4 default), libmp3lame (MP3), libopus (best quality per bit, WebM/OGG), copy (no re-encoding), flac (lossless).
-b:a — audio bitrate
128k is fine for speech. 192k-256k for music. 320k for archival (though at that point, FLAC makes more sense).
-ar — sample rate
Sets audio sample rate in Hz. 44100 is CD quality. 48000 is video standard. Rarely needs changing unless you're feeding audio into something with strict requirements.
-ac — channel count
1 for mono, 2 for stereo. Downmixing 5.1 surround to stereo: -ac 2. FFmpeg handles the downmix automatically using standard coefficients.
-an — disable audio
Drops all audio streams. Useful when creating silent loops or processing video-only content.
-af volume — adjust audio level
Multiplier: 1.0 is unchanged, 0.5 is half volume, 2.0 is double. You can also use dB: -af "volume=3dB". For broadcast-standard loudness normalization, use the loudnorm filter:
Filter options
Filters are where FFmpeg gets interesting. This is the part of the FFmpeg arguments list that most people underuse.
-vf / -filter:v — video filter chain
Apply one or more video filters as a comma-separated chain. Filters run left to right. Each filter takes the output of the previous one.
Common filters worth knowing:
The watermark guide covers overlay positioning in detail. The frame extraction guide shows how to combine filters with frame output.
-af / -filter:a — audio filter chain
Same syntax as video filters, applied to audio:
-filter_complex — complex filter graphs
Use this instead of -vf when you have multiple inputs, multiple outputs, or need to split/merge streams. The syntax uses stream labels in brackets. More verbose, but it handles things simple filters can't: picture-in-picture, combining audio from different sources, or creating multiple output resolutions from one input.
A practical example, side-by-side comparison:
Format and container options
-f — force output format
Usually FFmpeg guesses the format from the filename extension. Force it when writing to pipes, using raw formats, or when the extension is ambiguous. For a full breakdown of container formats and when to use each, see the formats guide.
-movflags +faststart — web-optimized MP4
Moves the MP4 moov atom to the beginning of the file. Without this, browsers download the entire file before playback starts. Always include it for web video. There's no downside.
-movflags +frag_keyframe+empty_moov — fragmented MP4
Creates a fragmented MP4 suitable for DASH streaming or progressive download of live content. Each fragment is independently decodable. Use this when generating MP4 for adaptive bitrate streaming.
-hls_time / -hls_list_size — HLS streaming
Creates HLS segments for adaptive streaming. -hls_time 6 sets 6-second segments. -hls_list_size 0 keeps all segments in the playlist (set to a number for live streams with a sliding window). Pair with -g 180 (for 30fps) to ensure keyframes align with segment boundaries.
-metadata — set file metadata
Sets container-level metadata. Use -metadata:s:v:0 for stream-specific metadata. To strip all metadata, use -map_metadata -1.
Stream mapping
-map — select streams manually
Without -map, FFmpeg auto-selects one stream per type (one video, one audio, one subtitle). With -map, you have full control. The syntax is input_index:stream_type:stream_index.
This is particularly useful when merging files. The merge videos guide covers concatenation and stream mapping for multi-file workflows.
-map_metadata — copy metadata
-map_metadata 0 copies metadata from the first input. -map_metadata -1 strips everything. Useful for privacy or when metadata causes player issues. See the metadata stripping guide for the full walkthrough.
-disposition — set stream flags
Marks a stream as default, forced, or other flags. Useful when muxing multiple audio tracks and you want players to auto-select a specific one.
Hardware acceleration
-hwaccel — hardware decode
Options: cuda (NVIDIA), vaapi (Linux/Intel/AMD), videotoolbox (macOS), qsv (Intel Quick Sync), d3d11va (Windows).
The -hwaccel_output_format cuda part keeps decoded frames in GPU memory, avoiding slow CPU-GPU transfers that can cut throughput in half. Always pair these two FFmpeg flags together. The GPU acceleration guide benchmarks NVENC vs CPU encoding across codecs and resolutions.
Hardware encoders
Hardware encoders trade a small quality decrease for speed. NVENC on a modern GPU encodes 10-50x faster than libx264 on CPU. Good for real-time processing and batch jobs where encoding time matters more than squeezing out every last byte.
NVENC presets use p1-p7 (not the ultrafast-veryslow scale), and quality is controlled with -cq rather than -crf on some versions. Run ffmpeg -h encoder=h264_nvenc to see what your build supports.
Using these FFmpeg options via API
Every flag in this guide works with the RenderIO API. Send the command over HTTP and get results stored in the cloud. No FFmpeg installation, no server to maintain. Get an API key and you can run any of these commands in about 30 seconds.
Replace the ffmpeg_command value with any command from this guide. Input files get downloaded from your URLs, FFmpeg runs in a sandboxed container, and output files get uploaded to cloud storage. You get back metadata like duration, codec, resolution, and file size with every result.
For batch processing (say, compressing 500 videos with the same CRF and preset), loop over the API instead of managing FFmpeg processes yourself. The commands list guide pairs dozens of FFmpeg commands with their exact API calls. Language-specific examples are in the Python SDK guide and the Node.js guide. Sign up here to try it.
Common FFmpeg options questions
What's the difference between -ss before and after -i?
Before -i, FFmpeg seeks at the demuxer level. Fast but potentially inaccurate by up to one keyframe interval. After -i, FFmpeg decodes every frame from the start until it reaches your timestamp. Slow but frame-accurate. For most trimming tasks, put -ss before -i with -c copy for speed. If you need exact frame cuts, put it after -i and re-encode. The trim video guide covers this with benchmarks.
How do I check what options my FFmpeg build supports?
What does -c copy actually do?
It skips re-encoding entirely. FFmpeg copies the compressed bitstream from input to output without decoding or re-encoding. This is instant (limited by disk I/O, not CPU) and lossless, with no generation loss. The tradeoff: you can't apply filters, change codecs, or do frame-accurate cuts. Use it when you only need to change the container format, strip/add streams, or cut on keyframe boundaries.
Why does FFmpeg ignore my options?
Usually option placement. FFmpeg flags before -i are input options. Flags after -i but before the output filename are output options. Put an output option in the input position and FFmpeg silently ignores it. Run with -v verbose to see what FFmpeg is actually doing with your command.
What's the best CRF value?
There's no universal answer. It depends on the codec and your quality requirements. For H.264, CRF 18-23 covers most use cases (18 for archival, 23 for distribution). For H.265, add 5-6 to get equivalent quality (so 23-28). The compression guide has visual comparisons and file size tables across CRF values.
How do I combine -crf with a maximum bitrate?
This tells the encoder to target CRF 23 quality but never exceed 2 Mbps. Set -bufsize to roughly 2x your maxrate. Useful for streaming platforms that cap bitrate.
Quick reference table
These are the most common FFmpeg flags and arguments in one table.
| Option | Category | What it does |
-y | Global | Overwrite output without asking |
-n | Global | Exit if output file exists |
-v error | Global | Only show errors |
-hide_banner | Global | Suppress build info |
-progress | Global | Machine-readable progress output |
-i | Input | Specify input file |
-f | Input/Output | Force format |
-ss | Input/Output | Seek to time position |
-t | Input/Output | Limit duration |
-to | Output | Stop at timestamp |
-re | Input | Read at native frame rate |
-stream_loop | Input | Loop input N times |
-c:v | Output | Set video codec |
-c:a | Output | Set audio codec |
-c copy | Output | Copy streams without re-encoding |
-crf | Codec | Constant quality factor |
-preset | Codec | Speed vs compression tradeoff |
-tune | Codec | Content-type optimization |
-profile:v | Codec | Compatibility profile |
-pix_fmt | Codec | Pixel format (yuv420p for web) |
-b:v | Output | Video bitrate |
-b:a | Output | Audio bitrate |
-r | Output | Frame rate |
-g | Codec | Keyframe interval (GOP size) |
-s | Output | Resolution |
-vf | Filter | Video filter chain |
-af | Filter | Audio filter chain |
-filter_complex | Filter | Multi-input filter graph |
-map | Stream | Manual stream selection |
-map_metadata | Stream | Copy or strip metadata |
-disposition | Stream | Set stream default/forced flags |
-movflags | Format | MP4 container flags |
-metadata | Format | Set file metadata |
-hwaccel | Hardware | Hardware decode acceleration |
-vn / -an | Output | Disable video/audio stream |