为什么在 FFmpeg 中转换为 GIF 时会出现像素化视频?

为什么在 FFmpeg 中转换为 GIF 时会出现像素化视频?

我想要编码这个 WEBM 视频:

我注意到 FFmpeg 在质量方面已经得到了很大的提升。

我正在将 WEBM 转换为 GIF,希望这能有所帮助。几乎所有在线转换器都使用 FFmpeg 进行转换,因此质量也会有同样的损失。

请注意,FFmpeg 编码的第一帧非常像素化:

在此处输入图片描述

这是我一直用于编码的命令。

ffmpeg -i connecting.webm -vf "fps=40,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif

即使我将 WEBM 源转换为 MP4 而不是 GIF,质量损失仍然存在。

我必须添加-vf选项来修复错误的帧速率。错误的转换如下所示。

在此处输入图片描述

为什么会发生这种情况?

答案1

原始 WebM 输入文件有一个 alpha(透明度)通道。
可能的解决方案是将半透明视频覆盖在黑色背景上:

ffmpeg -y -c:v libvpx-vp9 -i connecting.webm -vf "[v:0]fps=40[v0];color=black:rate=40[b];[b][v0]scale2ref[b][v0];[b]setsar=1[b];[b][v0]overlay=shortest=1,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif

当忽略 alpha 时,视频会像素化,因为平滑度是通过逐渐改变物体周围的透明度来创建的。


  • -c:v libvpx-vp9- 使用libvpx-vp9解码器。我们需要它,因为默认解码器会忽略 alpha(透明度)通道。
  • color=black:rate=40[b]- 创建具有某些标称分辨率的 40fps 的黑色视频。
  • [b][v0]scale2ref[b][v0]- 将黑色视频缩放至输入视频的分辨率。
  • [b]setsar=1[b]- 将黑场视频的宽高比设置为 1:1。
  • [b][v0]overlay=shortest=1- 将输入视频叠加在黑屏视频上。
  • scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse"- 按比例生成调色板并使用它,如问题所示。

输出:
在此处输入图片描述


关于输入的 alpha(透明度)通道的备注:

执行的时候ffprobe connecting.webm显示:

  Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv, progressive), 400x400, SAR 1:1 DAR 1:1, 60 fps, 60 tbr, 1k tbn (default)
    Metadata:
      alpha_mode      : 1
      ENCODER         : Lavc58.134.100 libvpx-vp9
      DURATION        : 00:00:01.067000000

alpha_mode : 1数据标记有一个 alpha(透明)通道。

我认为这是某种“特殊”配置(通常,当有 alpha 通道时,我会期望像素格式为 yuva420p,而不是 yuv420p)。
有一些关于alpha_mode : 1VP8 编码

相关内容