Skip to content

Instantly share code, notes, and snippets.

@ngoc-minh-do
Created October 11, 2025 14:09
Show Gist options
  • Select an option

  • Save ngoc-minh-do/73fc962f4cd60624011a8ecd8b1b4492 to your computer and use it in GitHub Desktop.

Select an option

Save ngoc-minh-do/73fc962f4cd60624011a8ecd8b1b4492 to your computer and use it in GitHub Desktop.

Video Compression Using FFmpeg (HEVC / H.265 & H.264)

This note explains how to compress videos using FFmpeg with HEVC (H.265) and H.264 (AVC), focusing on broad compatibility across devices β€” PCs, TVs, ARM devices, mobile, and browsers.


1. Recommended Format & Codec

Parameter Recommendation
Container MP4 (.mp4) β€” universal support
Video Codec HEVC / H.265 (hvc1) or H.264 (avc1)
Audio Codec AAC LC
Audio Bitrate 128–192 kbps
Resolution Match target device (1080p, 720p)
Frame Rate Keep source unless downscaling
Chroma / Bit Depth 4:2:0, 8-bit (broad compatibility)

HEVC gives smaller file sizes at same quality; H.264 maximizes legacy device support.


2. Key FFmpeg Concepts

πŸ”Ή Video Scaling

-vf scale=WIDTH:-2
  • Adjusts width, keeps aspect ratio (height auto, even number)

πŸ”Ή Rate Control / Quality

Option Meaning
-rc:v vbr Variable bitrate, adjusts bitrate per scene complexity
-cq:v N Constant quality target (lower = higher quality, bigger file)
-crf N Constant Rate Factor (libx265 / libx264), lower = higher quality

HEVC CQ examples (1080p):

  • 18–22 β†’ very high quality
  • 23–27 β†’ balanced quality & size
  • 28–30 β†’ smaller file, some compression artifacts

Max Bitrate Control

-b:v 3000k -maxrate 3500k -bufsize 7000k
  • -b:v β†’ target bitrate
  • -maxrate β†’ max bitrate peak
  • -bufsize β†’ VBV Buffer Size (Rate Control Window)
    • Common rule: bufsize = 2 Γ— maxrate β†’ avoids quality drops

πŸ”Ή Fast Start

-movflags +faststart
  • Enables streaming / instant playback.

πŸ”Ή Codec Tag

  • HEVC β†’ -tag:v hvc1 for iOS / modern player support
  • H.264 β†’ MP4 uses avc1 by default

πŸ”Ή Audio

  • AAC LC, 128–192 kbps β†’ universal support

3. FFmpeg Quick Reference

NVENC HEVC (modern devices, smaller size)

ffmpeg -y -hwaccel cuda -i input.mp4 \
    -map 0:v -vf scale=1920:-2 \
    -c:v hevc_nvenc -preset p7 -rc:v vbr -cq:v 25 -tag:v hvc1 \
    -map 0:a -c:a aac -b:a 160k \
    -movflags +faststart \
    output_hevc.mp4

Explanation:

  • -hwaccel cuda β†’ NVIDIA GPU acceleration
  • -map 0:v β†’ Select all video streams
  • -vf scale=1920:-2 β†’ Scale width to 1920px, auto height to maintain aspect ratio
  • -c:v hevc_nvenc β†’ Use NVENC hardware HEVC encoder
  • -preset p7 β†’ slowest NVENC preset β†’ best quality / smallest file
  • -rc:v vbr β†’ Variable bitrate, adjusts to scene complexity
  • -cq:v 25 β†’ Constant quality target (lower = higher quality, bigger file)
  • -tag:v hvc1 β†’ HEVC tag for MP4, ensures broad device compatibility
  • -map 0:a -c:a aac -b:a 160k β†’ Encode all audio streams to AAC 160 kbps
  • -movflags +faststart β†’ Allows streaming / instant playback

HEVC Remux (already HEVC, fix compatibility)

ffmpeg -i input.mp4 -c copy -tag:v hvc1 -movflags +faststart output_fixed.mp4

NVENC H.264 (maximum legacy compatibility)

ffmpeg -y -hwaccel cuda -i input.mp4 \
    -map 0:v -vf scale=1920:-2 \
    -c:v h264_nvenc -preset p7 -rc:v vbr -cq:v 23 -profile:v high -level 4.0 \
    -map 0:a -c:a aac -b:a 160k \
    -movflags +faststart \
    output_h264.mp4

Explanation:

  • -c:v h264_nvenc β†’ NVENC hardware H.264 encoder
  • -profile:v high -level 4.0 β†’ Ensures compatibility with most devices (TVs, browsers, PCs)
  • Other options same as HEVC example, optimized for H.264

CPU H.265 / x265 (libx265)

ffmpeg -i input.mp4 \
    -c:v libx265 -preset slow -crf 24 \
    -c:a aac -b:a 160k \
    -movflags +faststart \
    output_x265.mp4

Explanation:

  • -crf 24 β†’ constant quality, smaller CRF = better quality, larger file
  • Preset slow β†’ better compression
  • CPU encoding is slower than NVENC but may yield slightly smaller files at same quality

CPU H.264 / x264 (libx264)

ffmpeg -i input.mp4 \
    -c:v libx264 -preset slow -crf 23 -profile:v high -level 4.0 \
    -c:a aac -b:a 160k \
    -movflags +faststart \
    output_x264.mp4

Explanation:

  • CRF 23 β†’ good balance of quality and file size
  • High profile + level 4.0 β†’ maximum compatibility

4. Tips & Recommendations

  1. HEVC vs H.264
    • HEVC β†’ modern devices, smaller file
    • H.264 β†’ maximum compatibility
  2. CQ / CRF
    • Lower = higher quality, larger file
    • Higher = smaller file, may show artifacts
  3. Audio β†’ AAC LC 128–192 kbps
  4. Streaming & Web β†’ always use -movflags +faststart
  5. Scaling β†’ keep width/height divisible by 2 (-2 auto-fixes height)
  6. Check FFmpeg options
    ffmpeg -h encoder=hevc_nvenc
    ffmpeg -h encoder=h264_nvenc
    ffmpeg -h encoder=libx265
    ffmpeg -h encoder=libx264
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment