Format Conversion Guide
FFmpeg excels at converting between different container formats and codecs. This guide covers common conversion scenarios.
A container format (MP4, MKV, AVI) stores video, audio, and metadata. A codec (H.264, VP9, AAC) is the compression method used within the container.
List supported formats: ffmpeg -formatsList supported codecs: ffmpeg -codecs
Stream Copy (No Re-encoding)
The fastest conversion method uses -c copy to avoid re-encoding.
Basic Stream Copy
Simple container conversion
ffmpeg -i input.mp4 -c copy output.mkv
Copy specific streams
ffmpeg -i input.mkv -c:v copy -c:a copy output.mp4
Extract video only
ffmpeg -i input.mp4 -c:v copy -an output_video.mp4
When Stream Copy Works
Stream copy is supported when:
- Source codec is compatible with target container
- No filtering or processing is needed
- No quality changes required
ffmpeg -i input.mkv -c copy output.mp4
Some codec+container combinations are incompatible. For example, MP4 doesn’t support Theora video or Vorbis audio.
Common Container Conversions
MP4 Conversions
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4
MKV Conversions
ffmpeg -i input.mp4 -c copy output.mkv
ffmpeg -i input.avi -c:v copy -c:a copy output.mkv
ffmpeg -i video.mp4 -i audio1.aac -i audio2.aac \
-map 0:v -map 1:a -map 2:a -c copy output.mkv
MKV (Matroska) is highly flexible and supports virtually any codec combination.
WebM Conversions
WebM requires VP8/VP9 video and Vorbis/Opus audio.
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M -c:a libopus output.webm
AVI Conversions
ffmpeg -i input.mp4 -c:v mpeg4 -vtag xvid -q:v 5 -c:a libmp3lame output.avi
ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4
Codec Conversions
Video Codec Changes
ffmpeg -i input_h264.mp4 -c:v libx265 -crf 28 -c:a copy output_hevc.mp4
Audio Codec Changes
ffmpeg -i input.m4a -c:a libmp3lame -q:a 2 output.mp3
Resolution and Quality Changes
Change Resolution
ffmpeg -i input_4k.mp4 -vf scale=1920:1080 -c:v libx264 -crf 23 \
-c:a copy output_1080p.mp4
Change Bitrate
High quality to compressed
ffmpeg -i input_high.mp4 -b:v 2M -maxrate 2M -bufsize 4M \
-c:a aac -b:a 128k output_compressed.mp4
ffmpeg -i input.mp4 -c:v copy -c:a aac -b:a 96k output.mp4
Frame Rate Conversion
ffmpeg -i input_60fps.mp4 -r 30 -c:v libx264 -crf 23 output_30fps.mp4
Batch Conversion
Convert multiple files at once.
Bash Loop
for file in *.mkv; do
ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac "${file%.mkv}.mp4"
done
Convert all videos to WebM
for file in *.{mp4,avi,mov}; do
[ -f "$file" ] && ffmpeg -i "$file" -c:v libvpx-vp9 -crf 30 \
-c:a libopus "${file%.*}.webm"
done
Parallel Processing
ls *.mkv | parallel ffmpeg -i {} -c:v libx264 -crf 23 -c:a aac {.}.mp4
For large batch operations, consider using GNU Parallel for multi-core processing.
Lossless Conversions
Preserve original quality without re-encoding.
Lossless Video
ffmpeg -i input.avi -c:v libx264 -preset ultrafast -qp 0 lossless.mp4
Lossless Audio
ffmpeg -i input.mp3 -c:a flac output.flac
Convert to ALAC (Apple Lossless)
ffmpeg -i input.wav -c:a alac output.m4a
Handling Subtitles
Convert with Subtitles
ffmpeg -i input.mkv -c:v copy -c:a copy -c:s copy output.mp4
ffmpeg -i subtitles.srt subtitles.ass
VobSub to SRT (requires OCR)
ffmpeg -i input.mkv -map 0:s:0 output.srt
Not all subtitle formats work in all containers. MP4 supports mov_text, MKV supports most formats.
Advanced Conversions
Multiple Output Files
Create several versions in one pass.
ffmpeg -i input.mp4 \
-c:v libx264 -b:v 5M -s 1920x1080 output_1080p.mp4 \
-c:v libx264 -b:v 2M -s 1280x720 output_720p.mp4 \
-c:v libx264 -b:v 1M -s 854x480 output_480p.mp4
Extract and Convert
ffmpeg -i input.mp4 -vn -c:a libmp3lame -q:a 0 audio.mp3
Concatenate and Convert
Concatenate multiple files
# Create file list
echo "file 'video1.mp4'" > list.txt
echo "file 'video2.mp4'" >> list.txt
echo "file 'video3.mp4'" >> list.txt
# Concatenate
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4
Concatenate with re-encoding
ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" output.mp4
Codec-Container Matrix
| Container | H.264 | HEVC | VP9 | AV1 | AAC | MP3 | Opus |
|---|
| MP4 | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
| MKV | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| WebM | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ |
| AVI | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
| MOV | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
Device Compatibility
For maximum compatibility (all devices)
ffmpeg -i input.mkv -c:v libx264 -profile:v baseline -level 3.0 \
-pix_fmt yuv420p -c:a aac -b:a 128k -movflags +faststart output.mp4
For modern devices (2015+)
ffmpeg -i input.mkv -c:v libx264 -profile:v high -level 4.1 \
-pix_fmt yuv420p -c:a aac -b:a 192k -movflags +faststart output.mp4
For web streaming
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium \
-c:a aac -b:a 128k -movflags +faststart output.mp4
-movflags +faststart moves the moov atom to the beginning for faster web streaming.
Troubleshooting
ffprobe -v error -show_format -show_streams input.mp4
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name \
-of default=nw=1:nk=1 input.mp4
Fix Common Issues
ffmpeg -i input.mp4 -pix_fmt yuv420p -c:v libx264 -c:a copy output.mp4
Use stream copy when possible
Avoid re-encoding if formats are compatible:ffmpeg -i input.mkv -c copy output.mp4
Choose appropriate presets
Faster presets for large batches:ffmpeg -i input.avi -c:v libx264 -preset veryfast output.mp4
Use hardware acceleration
Leverage GPU encoding:ffmpeg -i input.mp4 -c:v h264_nvenc -preset p4 output.mp4
Next Steps
Encoding
Advanced encoding techniques
Hardware Acceleration
Speed up conversions with GPU
Streaming
Convert for streaming protocols
Filtering
Apply filters during conversion