What You’ll Learn in This Article

Tested version: FFmpeg 6.1 (ubuntu-latest / CI verified) Target OS: Windows / macOS / Linux

Note on filenames: This article uses placeholder filenames such as input.avi and input.mkv. In actual commands, replace these with the path of the file you want to process.


Background: The Difference Between Codecs and Containers

The main codecs that can be placed 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
OptionMeaning
-i input.aviSpecify the input file
-c:v libx264Specify H.264 (libx264) as the video codec
-c:a aacSpecify AAC as the audio codec
output.mp4Output filename (the .mp4 extension determines the container)

Primary source: FFmpeg Wiki - H.264 Encoding Guide


Adjusting Video Quality (CRF)

Use -crf to specify video quality. Lower values mean higher quality (larger file size).

ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac output.mp4
CRF valueQuality guideUse case
18Near visually losslessArchiving
23Default. Good balanceGeneral use
28Stronger compressionFile size priority
51Lowest qualityAlmost never used

“For general viewing, a range of 18–28 is recommended” — FFmpeg H.264 Guide


Adjusting Encoding Speed (preset)

Use -preset to adjust the trade-off between encoding speed and compression efficiency.

ffmpeg -i input.avi -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k output.mp4
presetSpeedCompression efficiency
ultrafastFastestLow
fastFastSomewhat low
mediumDefaultBalanced
slowSlowHigh
veryslowSlowestHighest

At a constant CRF, slower presets produce smaller file sizes at the same quality. Primary source: H.264 Guide - preset


Stream Copy (No Re-encoding)

When the input is already H.264/AAC, you can convert only the container without re-encoding.

ffmpeg -i input.mkv -c copy output.mp4

Specifying Audio Bitrate

ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac -b:a 192k output.mp4
-b:a valueUse case
96kLow quality, audio only
128kGeneral video
192kMusic / audio quality priority
320kHighest quality (approximate AAC upper limit)

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

The final -y flag skips the overwrite confirmation if the output file already exists (useful for batch processing).


Troubleshooting

Encoder libx264 not found

Cause: The installed FFmpeg build does not include libx264 Solution: Reinstall FFmpeg from the official site or your package manager. On Windows, the Full build from gyan.dev is recommended.

Output File Is Too Large

Increase the CRF value (28–32) or change to -preset fast to reduce the file size.

Stream Copy Fails

-c copy only works when the input codec is compatible with the output container. If it fails, re-encode with -c:v libx264 -c:a aac.


Primary sources: FFmpeg H.264 Wiki / FFmpeg AAC Wiki