ffmpeg例子

ffmpeg例子

我正在使用以下命令将视频转换为 GIF 文件ffmpeg

ffmpeg \
  -i input.flv \
  -ss 00:00:00.000 \
  -pix_fmt rgb24 \
  -r 10 \
  -s 320x240 \
  -t 00:00:10.000 \
  output.gif

效果很好,但是输出的 gif 文件质量很低。

有什么想法可以提高转换后的 gif 的质量吗?

答案1

ffmpeg例子

ffmpeg 的 GIF 输出
18.3万

ffmpeg可以输出高质量的 GIF。在开始之前,始终建议使用最新版本:下载或者编译

ffmpeg -ss 30 -t 3 -i input.mp4 \
    -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
    -loop 0 output.gif
  • -ss 30此示例将跳过输入的前 30 秒( )并创建 3 秒的输出( -t 3)。
  • 每秒帧数过滤器设置帧速率。示例中使用的速率为每秒 10 帧。
  • 规模过滤器将调整输出宽度为 320 像素,并自动确定高度,同时保持纵横比。lanczos缩放算法在此示例中使用。
  • 调色板调色板使用过滤器将生成并使用根据您的输入生成的自定义调色板。这些过滤器有很多选项,因此请参阅链接以获取所有可用选项和值的列表。另请参阅高级选项部分。
  • 分裂过滤器将允许所有操作在一个命令中完成,避免创建调色板的临时 PNG 文件。
  • 使用输出选项控制循环-loop,但值令人困惑。值为0表示无限循环,-1为不循环,1为循环一次表示播放两次。因此,值为 10 将导致 GIF 播放 11 次。

高级选项

调色板调色板使用过滤器有很多附加选项。最重要的是:

  • stats_mode(palettegen)。您可以强制过滤器将调色板集中在整个图片上(full这是默认设置)、仅移动部分(diff)或每个单独的帧(single)。例如,要为每个单独的帧生成调色板,请使用palettegen=stats_mode=single& paletteuse=new=1

  • dither(调色板)。选择抖动算法。主要有三种类型:确定性(bayer)、误差扩散(包括默认的所有其他算法sierra2_4a)和无。使用特定的抖动算法或根本不使用抖动,您的 GIF 可能会看起来更好。如果您想尝试,bayer请务必也测试该bayer_scale选项。

使用 FFmpeg 制作高质量 GIF以获得解释、示例图像以及高级用法的更多详细信息。

另请参阅调色板调色板使用所有可用选项和值的文档。


ImageMagickconvert示例

ffmpeg 的 GIF 输出
22.7万

另一个命令行方法是通过管道从 ImageMagick传输ffmpegconvert(或)。magick

ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v pam \
    -f image2pipe - | \
    convert -delay 10 - -loop 0 -layers optimize output.gif

ffmpeg选项:

  • -vf "fps=10,scale=320:-1:flags=lanczos"A过滤图使用每秒帧数规模过滤器。fps 将帧速率设置为 10,scale 将大小设置为 320 像素宽,高度自动确定并使用保留纵横比的值。lanczos缩放算法在此示例中使用。

  • -c:v pam选择 pam 图像编码器。示例输出 PAM (Portable AnyMap) 图像格式,这是一种简单、无损的 RGB 格式,支持透明度 (alpha),并受 支持convert。它的编码速度比 PNG 更快。

  • -f image2pipe选择 image2pipe 多路复用器,因为当输出到管道时ffmpeg需要告知使用哪个多路复用器。

convert选项:

  • -delay设置帧速率部分。

  • -loop 0陷入无限循环。

  • -layers optimize将启用通用 GIF 优化器。请参阅ImageMagick 动画优化了解更多详情。它不能保证产生较小的输出,因此值得尝试-layers optimize并比较结果。

设置帧速率

使用以下组合设置帧速率每秒帧数过滤ffmpeg-delay在 中convert。这可能会变得复杂,因为convert只获取原始图像流,因此不会保留任何 fps。其次,-delay中的值convert蜱虫(每秒有 100 个刻度),而不是每秒帧数。例如,fps=12.5= 100/12.5 = 8 = -delay 8

convert将值四舍五入-delay为整数,因此 8.4 的结果为 8,而 8.5 的结果为 9。这实际上意味着仅支持部分帧速率在所有帧上设置统一的延迟时(可以为每个帧设置特定的延迟,但这超出了这个答案的范围)。

-delay如果用作输出选项,它似乎会被忽略,因此必须-像示例中所示的那样先使用它。

最后,浏览器和图像查看器可能会实现最小延迟,因此-delay无论如何您都可能会被忽略。

视频由美国鱼类和野生动物管理局国家保护培训中心提供。

答案2

如果您希望避免使用中间图像文件,LordNeckBeard 提供的命令可以在ffmpeg和 ImageMagick 之间进行传输convert,这样就不需要中间文件了:

ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 10 -loop 0 - output.gif

告诉-f image2pipeffmpeg 将视频分割成图像并使其适合通过管道输出,并-vcodec ppm指定输出格式为 ppm(出于某种原因,如果格式为 png,则convert不会从管道读取所有图像,或者 ffmpeg 不会输出所有图像)。这-两个命令的 指定管道将分别用于输出和输入。

为了在不保存文件的情况下优化结果,您可以将输出通过管道传输convert到第二个convert命令:

ffmpeg -i input.flv -vf scale=320:-1 -r 10 -f image2pipe -vcodec ppm - | convert -delay 10 -loop 0 - gif:- | convert -layers Optimize - output.gif

指示gif:-convert其输出作为 gif 格式的数据进行管道传输,并-layers Optimize指示第二个convert执行optimize-frameoptimize-transparancy方法(请参阅 ImageMagick动画优化简介)。请注意,输出-layers Optimize可能并不总是提供较小的文件大小,因此您可能需要先尝试转换为未经过优化的 gif 以确保万无一失。

请记住,在整个过程中,所有内容都位于内存中,因此如果图像很大,则可能需要足够的内存。

答案3

从 ffmpeg 2.6 开始,我们可以做得更好。基于使用 FFmpeg 制作高质量 GIF

palette="/tmp/palette.png"
filters="fps=15,scale=320:-1:flags=lanczos"

ffmpeg -i input.flv -vf "$filters,palettegen" -y $palette
ffmpeg -i input.flv -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y output.gif

答案4

我做了自己的版本这个脚本,它也参数化了输出分辨率和帧速率。

运行./gifenc.sh input.mov output.gif 720 10将从您提供的电影中输出 720p 宽 10fps GIF。您可能需要chmod +x gifenc.sh对文件执行此操作。

#!/bin/sh

palette="/tmp/palette.png"

filters="fps=$4,scale=$3:-1:flags=lanczos"

ffmpeg -v warning -i "$1" -vf "$filters,palettegen" -y "$palette"
ffmpeg -v warning -i "$1" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y "$2"

您可以在我的Github

假设:ffmpeg 已安装,并且脚本与其他文件位于同一文件夹中。

相关内容