影片壓縮完整指南:從原理到 FFmpeg 實戰
想壓縮影片,又想保持畫質。CRF 和位元率有什麼差別?H.264 和 H.265 該用哪個?這些是接觸影片壓縮時常見的疑問。搞懂原理,FFmpeg 的參數就不再是玄學,而是合理選擇。這篇從壓縮的根本講起,一路到實戰。
為什麼影片能壓縮
影片的本質是「連續的影像幀」。一秒 24-60 幀。未壓縮的 1080p 60fps 影片需要約 3 Gbps 頻寬,一分鐘就 22 GB。YouTube 能流暢播放這種龐大資料,是因為破壞性壓縮利用了人類視覺的特性。
人類視覺的 3 個特性
- 對亮度敏感、對色彩遲鈍:人對亮度變化敏感,對色彩變化遲鈍。YUV 4:2:0 把色彩資訊取樣減半,資料量省 50%
- 對靜態敏感、對動態遲鈍:靜止背景要高畫質,移動物體畫質低一點也看不出來
- 對高頻細節遲鈍:邊緣和紋理的細節可以模糊,人眼不易察覺
現代影片壓縮都建立在這 3 個特性上。
三個壓縮維度
1. 空間壓縮(幀內壓縮)
削減單一幀內的冗餘,類似 JPEG 影像壓縮:
- DCT 轉換:把像素區塊(通常 8x8)轉到頻率域
- 量化:丟棄高頻成分(人眼遲鈍的細節)
- 熵編碼:霍夫曼編碼或算術編碼再壓縮
2. 時間壓縮(幀間壓縮)
利用幀與幀之間的相似性,這是影片壓縮的核心:
- I 幀(關鍵幀):存完整影像,壓縮率低
- P 幀(前向預測):只存和前一幀的差異
- B 幀(雙向預測):存和前後幀的差異,壓縮率最高
典型 GOP(Group of Pictures)結構:
I B B P B B P B B P B B P I B B P ...只有 I 幀存完整影像,其餘都是差異。這樣資料量大幅降低。
3. 熵壓縮
無損壓縮再削減資料:
- 霍夫曼編碼
- 算術編碼(CABAC/CAVLC)
- 行程編碼
主要影片編碼器比較
| 編碼器 | 發布年 | 壓縮效率 | 編碼速度 | 瀏覽器支援 | 使用場景 |
|---|---|---|---|---|---|
| H.264 (AVC) | 2003 | 好 | 快 | 普及 | 萬用 |
| H.265 (HEVC) | 2013 | 優(比 H.264 小 30-50%) | 慢 | 有限 | 封存、4K |
| VP9 | 2013 | 優(相當 H.265) | 慢 | Chrome、Firefox | YouTube、WebM |
| AV1 | 2018 | 最高(比 H.265 小 20-30%) | 非常慢 | 現代瀏覽器 | 下一代串流 |
詳細比較見 H.264 vs H.265 vs AV1 編碼器比較指南。
FFmpeg 壓縮實戰
CRF 模式(畫質優先)
bash
# H.264 CRF 壓縮(推薦)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset slow -c:a aac -b:a 128k output.mp4
# H.265 CRF 壓縮(更小)
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset slow -c:a aac -b:a 128k output.mp4CRF 值參考:
| CRF 值 | 畫質 | 檔案大小 | 使用場景 |
|---|---|---|---|
| 18 | 視覺無損 | 大 | 高畫質封存 |
| 23(H.264 預設) | 好 | 中 | 一般使用 |
| 28(H.265 預設) | 好 | 小 | 網頁用 |
| 32 | 可接受 | 非常小 | 行動用 |
位元率模式(大小優先)
bash
# 固定位元率(CBR)— 適合直播
ffmpeg -i input.mp4 -c:v libx264 -b:v 4M -maxrate 4M -bufsize 8M -c:a aac -b:a 128k output.mp4
# 可變位元率(VBR)— 適合 VOD
ffmpeg -i input.mp4 -c:v libx264 -b:v 4M -c:a aac -b:a 128k output.mp4preset 選擇
| preset | 編碼速度 | 壓縮率 | 使用場景 |
|---|---|---|---|
| ultrafast | 最快 | 最差 | 直播 |
| fast | 快 | 好 | 快速測試 |
| medium(預設) | 中 | 好 | 一般使用 |
| slow | 慢 | 更好 | 封存 |
| veryslow | 最慢 | 最高 | 最終交付 |
改解析度
bash
# 降 to 720p
ffmpeg -i input.mp4 -vf "scale=-1:720" -c:v libx264 -crf 23 -c:a aac output.mp4
# 降 to 480p
ffmpeg -i input.mp4 -vf "scale=-1:480" -c:v libx264 -crf 23 -c:a aac output.mp4改幀率
bash
# 60fps → 30fps
ffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a aac output.mp4
# 60fps → 24fps(電影感)
ffmpeg -i input.mp4 -r 24 -c:v libx264 -crf 23 -c:a aac output.mp4各場景壓縮範本
網頁用影片
bash
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset slow -profile:v high -level 4.0 -pix_fmt yuv420p -movflags +faststart -c:a aac -b:a 128k output.mp4-profile:v high -level 4.0:保證相容性-pix_fmt yuv420p:最相容的色彩空間-movflags +faststart:網頁漸進式播放
行動用影片
bash
ffmpeg -i input.mp4 -vf "scale=-1:720" -r 30 -c:v libx264 -crf 26 -preset slow -c:a aac -b:a 96k output.mp4封存用影片
bash
ffmpeg -i input.mp4 -c:v libx265 -crf 20 -preset slow -c:a aac -b:a 192k output.mp44K 影片壓縮
bash
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -preset medium -x265-params "pool=0:frame-threads=0" -c:a aac -b:a 192k output.mp4常見問題
1. 壓縮後畫質明顯下降
原因: CRF 太高或位元率太低
解決方案: 降低 CRF(23→18)或提高位元率
2. 編碼慢
原因: preset 太慢或解析度太高
解決方案: 用 -preset medium 或 fast,降解析度
3. 檔案比預期大
原因: 來源已經高壓縮,重新編碼只會降低畫質
解決方案: 切換到 H.265 或降解析度
4. iPhone 播放不了
原因: 用了 H.265 或像素格式不相容
解決方案: 用 H.264 和 -pix_fmt yuv420p
壓縮前後畫質比較
bash
# 確認原始影片位元率
ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1 input.mp4
# 確認壓縮後位元率
ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1 output.mp4
# 用 PSNR 測量畫質(30dB 以上算好)
ffmpeg -i input.mp4 -i output.mp4 -filter_complex "psnr" -f null -
# 用 VMAF 測量畫質(80 以上算好,Netflix 的指標)
ffmpeg -i input.mp4 -i output.mp4 -filter_complex "libvmaf" -f null -詳見 影片元資料分析指南。
總結
影片壓縮的核心是利用人類視覺特性的破壞性壓縮。FFmpeg 實戰中:
- 畫質優先: CRF 模式(H.264 用 CRF 23,H.265 用 CRF 28)
- 大小優先: 位元率模式(CBR 或 VBR)
- 相容優先: H.264 + yuv420p + high profile
- 效率優先: H.265(縮小 30-50%,編碼慢)
必記基本範本:
bash
# 通用壓縮(涵蓋 90% 場景)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset slow -c:a aac -b:a 128k output.mp4快速參考:
- CRF 參考: H.264 18-28,H.265 23-32
- preset: 一般用
medium,封存用slow - 相容性: H.264 + yuv420p + high profile
- 壓縮效率: H.265 > VP9 > H.264