编辑历史:
- 2024/06/29 更新 AV1 部分调参内容
- 2024/08/18 介于接下来的内容还放在这过于冗长,又多开了一篇:https://baysonfox.com/2024/08/18/avif-av1-compress-part-two/
事出必有因
前几天闲来无事,于是打算看下自己的 Cosplay 收藏有多少,遂du -sh
,结果如下:
这可不好.jpg
于是点进去准备一探究竟,看看图片有多吃空间:
这能忍?开干!
那咋整呢?
摆在面前的有三种选择:
- JPEG XL
- AVIF
- WebP
于是查阅互联网,找到一篇来自 Moonvy 月维 的文章。
直接上结论:
AVIF 有损压缩效果最好,无损压缩非常糟糕。编码速度很慢。
JPEG XL 无损压缩效果最好,有损压缩较 AVIF 有些许差距。编码速度快。
WebP 2 无损压缩效果优秀,有损压缩的上限达到了 AVIF 的水平,但下限很低,不稳定。编码速度很慢。
但是考虑到未来可能还有网页浏览的需求,再加上 WebP 2 本身就没法在我的林檎OS(也就是 macOS)上正常浏览,且可以接受一定程度的有损压缩,于是直接冲 AVIF。
支线任务: 装上 libavif
决定好要用 AVIF,但是系统里大概率没有libavif
,于是先装再说。
介于我用 macOS ,直觉便是brew search avif
,brew install libavif
,秒了。
但是,古人曾言:
AVIF 是这样的。林檎用户只要无脑装
libavif
就可以,可是其他系统的用户要考虑的事就很多了。
各路 Linux 玩家往这里看:https://web.dev/articles/compress-images-avif;
至于 Windows , 自求多福。
AVIF, 启动
毕竟是尺度有那么一丢丢大的 Cosplay (真的只有一丢丢!),所以没有对比图(
处理用的命令如下:
avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim \
-a deltaq-mode=3 -a sharpness=3 -y 420 --jobs 8 --ignore-exif --ignore-xmp Coser-***.jpg Coser-***.avif
至于为什么是这么个参数,原文是这么说的:
Note: “–min 0 –max 63 -a end-usage=q -a cq-level=18 -a tune=ssim” are the recommended settings for AVIF images.
而--ignore-exif --ignore-xmp
为的是尽可能减小文件体积,反正 Exif 和 XMP 大概率都没啥用。
结果:
Successfully loaded: Coser-***.jpg
AVIF to be written: (Lossy)
- Resolution : 7952x5304
- Bit Depth : 8
- Format : YUV420
- Chroma Sam. Pos: 0
- Alpha : Absent
- Range : Full
- Color Primaries: 2
- Transfer Char. : 2
- Matrix Coeffs. : 6
- ICC Profile : Present (3144 bytes)
- XMP Metadata : Absent
- Exif Metadata : Absent
- Transformations: None
- Progressive : Unavailable
Encoding with AV1 codec 'aom' speed [6], color quality [51 (Medium)],
alpha quality [100 (Lossless)], tileRowsLog2 [0], tileColsLog2 [0],
8 worker thread(s), please wait...
Encoded successfully.
- Color AV1 total size: 1334940 bytes
- Alpha AV1 total size: 0 bytes
Wrote AVIF: Coser-***.avif
再看看图片大小(下方为原图):
效果立竿见影
93%的压缩率,很难不觉得 AVIF 不香。
随便写个小脚本:
for file in *.{jpg,JPG};
do avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim \
-a deltaq-mode=3 -a sharpness=3 -y 420 --jobs 10 \
--ignore-exif --ignore-xmp $file ${file%*.*}.avif;
done
图片部分,堂堂结束!
视频部分
那么…… AV1 or HEVC?
会出现这个问题本质上还是因为自己没有 N卡,不然直接硬件加速上AV1解决一切问题(
当然,看标题就已经能够得出结论了:最后选了AV1。
但为什么是 AV1 不是 HEVC?
虽然 HEVC 在 macOS + ffmpeg 上有 hevc_videotoolbox 的硬件加速,但相较于 AV1(libsvtav1) 体积反而会来的更大些(但也不至于到无法忍受的地步);
且在同等画质水平(肉眼几乎无感, 姑且将其设定为SSIM ≥ 0.95)下体积表现很好。
AV1 软件编码不慢吗?
慢是慢,但是在各种魔法参数的优化下(见下文),ffmpeg 里速度表现还可以(4.45x),虽然没有 HEVC 硬编快(8.24x),但也不错。
再加上并没有什么转码时间上的要求,AV1 在这种情况下还蛮香的。
于是乎,AV1 成了最终选择.
同上,脚本如下:
for video in *;
do ffmpeg -i $video -c:v libsvtav1 -preset 10 -crf 38 \
-svtav1-params input-depth=10:tune=2:enable-qm=1:qm-min=0:keyint=300 \
-c:a copy -threads 10 ${video%*.*}-av1.mp4;
done
具体参数不再赘述,在此附上参考文章:
- https://wiki.x266.mov/docs/encoders/SVT-AV1#encoding
- https://www.ffmpeg.org/ffmpeg-all.html#libsvtav1
- https://gitlab.com/AOMediaCodec/SVT-AV1/-/blob/master/Docs/Parameters.md
TODO: 详细的文档记录& benchmarks (PSNR SSIM etc.)
最终结果
Cosplay 图库里的数据实在太多 根本压不完(
这一部分等全部搞定之后再更新(
更新:压完嘞(
最后结果: 354G -> 64G
82% 的空间优化,可喜可贺可喜可贺(
技术细节:视频下的 AV1 编码调参
ffmpeg
作为老牌的音视频处理瑞士军刀,配合 SVT-AV1 ,可供调整的编码参数多了不是一点半点,搞得人晕头转向(
在此额外参考了 Comparing SVT-AV1 Presets: Size, Quality, and Speed with CRF Variations,文中对 SVT-AV1 编码器在不同预设和crf下的编码性能与质量进行了实验。
略过文中的测试方法,直接看结论:
编码性能(以 FPS 衡量):
编码质量(SSIM):
PSNR:
VMAF:
由图可知,所使用的preset与crf (-preset 10 -crf 38
) 下,SSIM 与 PSNR 都与较低预设值和较低 crf 的对应参数区别不大,编码速度也落在了比较舒适的范围,因此使用此参数。
事实上,根据原文作者的结论,似乎-preset 12 -crf 38
与-preset 2
的视频参数似乎区别不大,但是速度提升了135倍,完全可以直接无脑冲……?
用数据说话
为了更贴合实际,又找了个 Cosplay 的图包里的视频进行实验:
实验工具:
- FFmpeg 7.0.1, built with Apple Clang version 15.0.0
- SVT-AV1 Encoder Lib v2.1.1, built with Apple LLVM 15.0.0
实验步骤:
- 把编码的 preset 固定为 N, N∈[0,12], 步长为1
- 将编码所用 crf 设置为 20~63, 步长为6
- 对每个编码结果,测量 VMAF、SSIM与PSNR.
实验结果:
那么,结论是
在编码速率和编码质量来看,-preset 10 -crf 38
的参数的确符合了要求,也没有产生视觉上的瑕疵,与上文的结论一致。