4. H.264 与 H.265 不同 CRF 质量参数对比

任务说明

对同一段输入视频,分别用 H.264(libx264)和 H.265(libx265)以多组 CRF 值编码,采集每组的码率与 PSNR,观察质量随 CRF 变化的趋势,并对比两种编码器在相同 CRF 下的差异。

环境与依赖

  • FFmpeg(需包含 libx264、libx265,可用 ffmpeg -encoders | findstr 264 确认)
  • Python 3(仅用标准库,负责批量调用与结果汇总)
  • 一段测试视频 input.mp4,放在脚本同目录

实现思路

input.mp4 libx264 CRF 18/23/28/33 libx265 CRF 18/23/28/33 ffmpeg 编码 + PSNR 统计 码率/PSNR 汇总对比

脚本对每个编码器遍历 CRF 列表,调用 ffmpeg 编码并同时用 psnr 滤镜输出质量指标,从 ffmpeg 日志中解析实际码率与平均 PSNR,最后打印对比表。

完整代码

import subprocess, re, os

INPUT = "input.mp4"
CRF_LIST = [18, 23, 28, 33]
ENCODERS = {"H.264": "libx264", "H.265": "libx265"}

def run(enc, crf):
    out = f"out_{enc}_{crf}.mp4"
    cmd = ["ffmpeg", "-y", "-i", INPUT,
           "-c:v", enc, "-crf", str(crf), "-preset", "medium",
           "-c:a", "copy", out,
           "-lavfi", f"psnr=stats_file=psnr_{enc}_{crf}.log"]
    # 用 -f null 单独跑一次 PSNR,避免与编码输出冲突
    cmd = ["ffmpeg", "-y", "-i", INPUT,
           "-c:v", enc, "-crf", str(crf), "-preset", "medium",
           "-c:a", "copy", out]
    subprocess.run(cmd, capture_output=True)
    psnr_cmd = ["ffmpeg", "-i", INPUT, "-i", out,
                "-lavfi", "psnr", "-f", "null", "-"]
    r = subprocess.run(psnr_cmd, capture_output=True, text=True)
    log = r.stderr
    m = re.search(r"average:([\d.]+)", log)
    psnr = float(m.group(1)) if m else float("nan")
    size = os.path.getsize(out)
    # 用 ffprobe 取时长算码率
    dur = float(subprocess.run(
        ["ffprobe", "-v", "error", "-show_entries", "format=duration",
         "-of", "default=nk=1:nw=1", out],
        capture_output=True, text=True).stdout.strip())
    kbps = size * 8 / dur / 1000
    return kbps, psnr

print(f"{'编码器':<8}{'CRF':<6}{'码率(kbps)':<14}{'PSNR(dB)':<10}")
for name, enc in ENCODERS.items():
    for crf in CRF_LIST:
        kbps, psnr = run(enc, crf)
        print(f"{name:<8}{crf:<6}{kbps:<14.1f}{psnr:<10.2f}")

运行方式

python compare_crf.py

脚本会在当前目录生成 out_H.264_*.mp4 与 out_H.265_*.mp4 文件,并打印对比表。

验证与判定

  • 表格中每个编码器应有 4 行,CRF 越大码率越低、PSNR 越低,趋势单调即符合预期。
  • 相同 CRF 下,H.265 通常码率更低、PSNR 略高或相当;若某组异常,检查 ffmpeg 是否支持对应编码器。
  • 主观质量:用播放器打开同 CRF 的 H.264 与 H.265 输出,对比细节保留与块效应,H.265 在低码率下应更平滑。