FFmpeg recipe

FFmpeg: Convert HEVC (H.265) to H.264 MP4

Chrome refuses HEVC, Windows 10 needs a paid codec. This recipe re-encodes to H.264 for universal playback.

Command

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a copy -y output.mp4
Prefer no terminal?
Use the Video Converter in your browser
Open Video Converter →

What each flag does

-iInput file. Can be a video, audio, or image. Repeat for multiple inputs.
-c:vVideo codec for output. e.g. libx264, libx265, libvpx-vp9.
-crfConstant Rate Factor — quality target (lower = better, larger file). 23 is visually lossless for libx264.
-preset mediumSpeed vs. compression tradeoff. Use slow for archival, faster for quick conversion.
-c:a copyStream-copy the audio (typically AAC). Avoids needless re-encode.

Notes & gotchas

  • Output file will be ~1.5–2× larger than the HEVC source for equivalent quality.
  • For 10-bit HEVC (HDR), pass -pix_fmt yuv420p to ensure SDR-compatible output.

Check it worked

ffprobe -v error -show_entries stream=codec_name,bit_rate -of csv=p=0 output.mp4

h264, and a bitrate roughly one and a half to two times the source. A smaller file usually means the quality setting was too aggressive.

What to change

-crf trades size against quality23 keeps it close to the source. The H.264 result is roughly twice the size of the HEVC original at matching quality — that is the cost of compatibility.
10-bit sourcesAdd -pix_fmt yuv420p to force 8-bit. Without it some encoders keep 10-bit and the file still will not play where you needed it to.
-preset controls time, not qualityslower gives a smaller file at the same CRF. veryfast gives a bigger one faster. Neither changes how it looks.

If it fails

Conversion is extremely slow on a long clip.

Why: HEVC decoding and H.264 encoding are both expensive, and by default neither uses the GPU.

Fix: Add -preset faster to trade a little file size for speed, or use a hardware encoder such as -c:v h264_videotoolbox on macOS or -c:v h264_nvenc with an NVIDIA card.

The picture looks washed out compared with the source.

Why: The source carries HDR or a wide colour space and the output is being written as standard range without a conversion.

Fix: Add a tone-mapping filter, or accept SDR and set -pix_fmt yuv420p explicitly so players interpret it consistently.

Related recipes