FFmpeg 截取 webp 动图

FFmpeg 支持对动态 webp 图片的编码,但是默认参数下编码后的图片有两个比较明显的问题:

  • 动图不会自动循环播放,会停留在最后一帧画面
  • 图像质量差,有比较明显的马赛克
  1. 动图自动循环播放

1.1 命令行下

1
ffmpeg -i input.mp4 -loop 0 output.webp

1.2 libavformat 库下

1
av_opt_set_int(formatContext, "loop", 0, AV_OPT_SEARCH_CHILDREN);

将 loop 值设置为 0,即为自动循环播放。默认值为 1。

注意,loop 是 AVFormatContext 中的选项,不是 AVCodecContext 的选项。

  1. 调整质量

libwebp 有 4 个质量相关的参数:

  • lossless:是否无损编码
  • compression_level:压缩等级,0-6,值越大质量越好,默认值为 4
  • qscale,0-100 间的 float,值越大质量越好,默认值为 75
  • preset,几种预设配置,比如数字图片、户外自然相片等

粗略测试,只有 qscale 效果比较明显且副作用较小。

1.1 命令行下

使用编码器通用选项 qscale:

1
ffmpeg -i input.mp4 -qscale 85 output.webp

1.2 libavcodec 库下

实测通过:

1
av_opt_set_double(videoCodec, "qscale", 85, AV_OPT_SEARCH_CHILDREN);

方式修改 qscale 无效,必须修改 AVCodecContext::global_quality

1
videoCodec->global_quality = 85 * FF_QP2LAMBDA;

这句才能起到上边命令行一样的作用。

85 是一个比较理想的值,可以生成 gif 同样质量的动态图片。相比默认值 75,会增加 50% 左右的体积;但是相比 gif,依然有一倍有余的优势。

评论