压缩非常小的视频时,视频容器本身似乎会产生很大的开销。
以下是使用单帧 16x16 像素全黑图像的一些示例:
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -y /tmp/v1.mp4
wc -c /tmp/v1.mp4
# 1625 bytes
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -codec:v hevc -y /tmp/v2.mp4
wc -c /tmp/v2.mp4
# 3165 bytes
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -y /tmp/v1.h264
wc -c /tmp/v1.h264
# 744 bytes
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -codec:v hevc -y /tmp/v2.hevc
wc -c /tmp/v2.hevc
# 2354 bytes
这些数字看起来都出乎意料地大。是不是ffmpeg
存储了一些不需要的元数据?
有没有什么办法可以避免这些大的开销,特别是HEVC
?
相比之下,图像编解码器看起来更加紧凑:
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -y /tmp/v1.png
wc -c /tmp/v1.png
# 94 bytes
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -y /tmp/v1.jpg
wc -c /tmp/v1.jpg
# 222 bytes
答案1
我们需要删除存储的“SEI 用户编码器设置”:
- 对于 x264:https://forum.selur.net/showthread.php?tid=1282
- 对于 x265: --[no-]info 发出 SEI 识别编码器和参数。默认启用
使用上面的例子:
ffmpeg -i /tmp/v1.mp4 -c copy -bsf:v 'filter_units=remove_types=6' -y /tmp/v3.mp4
wc -c /tmp/v3.mp4
# 837 bytes (down from 1625 bytes)
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -codec:v hevc -x265-params info=0 -y /tmp/v4.mp4
wc -c /tmp/v4.mp4
# 903 bytes (down from 3165 bytes)
ffmpeg -i /tmp/v1.h264 -c copy -bsf:v 'filter_units=remove_types=6' -y /tmp/v3.h264
wc -c /tmp/v3.h264
# 56 bytes (down from 744 bytes)
ffmpeg -f lavfi -i color=c=black:s=16x16:r=1:duration=1 -codec:v hevc -x265-params info=0 -y /tmp/v3.hevc
wc -c /tmp/v3.hevc
# 97 bytes (down from 2354 bytes)