If a video will not play or upload because it is not an MP4, FFmpeg can convert it. It reads almost any video format, including AVI, MKV, and MOV.
In the commands below, replace
input.avi,input.mkvand the other example names with the path to your own file.
Codecs and Containers
- Container (the file extension):
.mp4,.mkv,.aviand so on. It is the “wrapper” that holds the video and audio. - Codec: the way the video or audio is compressed. For MP4, the standard choice is
H.264 (libx264)for video andAACfor audio.
The main codecs used in an MP4 container are H.264 or H.265 (HEVC) for video and AAC for audio.
Basic Command
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4
| Option | Meaning |
|---|---|
-i input.avi |
The input file |
-c:v libx264 |
Encode the video as H.264 (libx264) |
-c:a aac |
Encode the audio as AAC |
output.mp4 |
The output file name (the .mp4 extension sets the container) |
Primary source: FFmpeg Wiki - H.264 Encoding Guide
Adjusting Video Quality (CRF)
-crf sets the video quality. A lower value gives higher quality and a larger file.
ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4
| CRF value | Quality guide | Use case |
|---|---|---|
| 18 | Near visually lossless | Archiving |
| 23 | Default. Good balance | General use |
| 28 | Stronger compression | File size priority |
| 51 | Lowest quality | Almost never used |
“A subjectively sane range is 17–28” — FFmpeg H.264 Guide
Adjusting Encoding Speed (preset)
-preset trades encoding speed against compression efficiency.
ffmpeg -i input.avi -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k output.mp4
| preset | Speed | Compression efficiency |
|---|---|---|
| ultrafast | Fastest | Low |
| fast | Fast | Somewhat low |
| medium | Default | Balanced |
| slow | Slow | High |
| veryslow | Very slow | Very high |
A slower preset compresses more efficiently. But at the same CRF, quality and file size both change with the preset, and a slower preset does not always give a smaller file. Primary source: H.264 Guide - preset
Stream Copy (No Re-encoding)
If the input already has H.264 video and AAC audio, you can change only the container, without re-encoding.
ffmpeg -i input.mkv -c copy output.mp4
- Advantage: finishes almost instantly and loses no quality
- Note: it fails if the MP4 container cannot hold the input codec. In that case, use
-c:v libx264 -c:a aacinstead.
Specifying Audio Bitrate
ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac -b:a 192k output.mp4
-b:a value |
Use case |
|---|---|
| 96k | Low quality, speech only |
| 128k | General video |
| 192k | Music / audio quality priority |
| 320k | Very high quality |
Summary of Commonly Used Command Examples
ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4
ffmpeg -i input.mkv -c:v libx264 -crf 22 -preset slow -c:a aac -b:a 192k output.mp4
ffmpeg -i input.mkv -c copy output.mp4
ffmpeg -y -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4
In the last command, -y overwrites an existing output file without asking first. This is useful in batch scripts.
Troubleshooting
Unknown encoder 'libx264'
Cause: Your FFmpeg build does not include libx264.
Solution: Install an FFmpeg build that includes libx264. On Windows, the Full build from gyan.dev is recommended. Some Linux packages leave it out, for example Fedora’s ffmpeg-free.
Output File Is Too Large
Raise the CRF value (28–32) to make the file smaller. A faster -preset does not make the file smaller at the same quality. To get close to a target file size, use 2-pass encoding: see Two-Pass Encoding.
Stream Copy Fails
-c copy works only when the output container can hold the input codecs. If it fails, re-encode with -c:v libx264 -c:a aac.