H.265/HEVC delivers the same visual quality as H.264 in files 40–50 % smaller. FFmpeg with libx265 is the most powerful way to leverage this codec from the command line.
| Codec |
Year |
Compression |
Speed |
Compatibility |
| H.264 (libx264) |
2003 |
Good |
Very fast |
Universal |
| H.265 (libx265) |
2013 |
Very good |
Medium |
Wide |
| AV1 (libaom) |
2018 |
Excellent |
Slow |
Growing |
ffmpeg -i input.mp4 -c:v libx265 -c:a copy output_h265.mp4
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a copy output.mp4
ffmpeg -i input.mp4 -c:v libx265 -crf 24 -preset medium -c:a aac -b:a 128k output.mp4
| CRF Range |
Use case |
| 18–20 |
Master files, no perceptible loss |
| 21–26 |
High-quality online distribution |
| 27–32 |
General streaming |
| 33–40 |
Mobile, very limited bandwidth |
# ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium output.mp4
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset slow output.mp4
# NVIDIA NVENC
ffmpeg -i input.mp4 -c:v hevc_nvenc -cq 28 -preset p4 output_nvenc.mp4
# Intel Quick Sync
ffmpeg -i input.mp4 -c:v hevc_qsv -global_quality 28 output_qsv.mp4
# Apple VideoToolbox (M1/M2/M3)
ffmpeg -i input.mp4 -c:v hevc_videotoolbox -q:v 60 output_mac.mp4
# Check available encoders
ffmpeg -encoders 2>/dev/null | grep hevc
#!/bin/bash
mkdir -p output_h265
for f in *.mp4; do
name="${f%.mp4}"
ffmpeg -i "$f" -c:v libx265 -crf 26 -preset medium \
-c:a aac -b:a 128k -movflags +faststart \
"output_h265/${name}_h265.mp4" -y
done
import subprocess
from pathlib import Path
def compress_h265(input_path, output_path, crf=26, preset='medium'):
cmd = ['ffmpeg', '-i', str(input_path),
'-c:v', 'libx265', '-crf', str(crf), '-preset', preset,
'-c:a', 'aac', '-b:a', '128k', '-movflags', '+faststart',
str(output_path), '-y']
result = subprocess.run(cmd, capture_output=True, text=True)
return result.returncode == 0
for video in sorted(Path('videos/').glob('*.mp4')):
output = Path('h265') / video.name
output.parent.mkdir(exist_ok=True)
ok = compress_h265(video, output)
if ok:
orig = video.stat().st_size / 1024 / 1024
comp = output.stat().st_size / 1024 / 1024
print(f"OK: {video.name} → {orig:.1f}MB → {comp:.1f}MB ({(1-comp/orig)*100:.0f}% smaller)")