如何通过命令行从 MP4 视频创建动画 GIF?

May*_*hux 194 command-line mp4 gif

我想.gif.mp4视频中制作动画。我更喜欢从命令行执行此操作,因此请仅列出命令行工具。

Cir*_*郝海东 236

ffmpeg 3.4.4 可以直接在Ubuntu 18.04上做

您可能想要使用以下内容:

sudo apt install ffmpeg
wget -O opengl-rotating-triangle.mp4 https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.mp4?raw=true
ffmpeg \
  -i opengl-rotating-triangle.mp4 \
  -r 15 \
  -vf scale=512:-1 \
  -ss 00:00:03 -to 00:00:06 \
  opengl-rotating-triangle.gif
Run Code Online (Sandbox Code Playgroud)

opengl-旋转三角形.gif

在此处输入图片说明

图像信息:426kB,45 帧,512x512 外观尺寸,合并,Lenovo P51 上的转换时间:0.5 秒。

上述转换在ulimit -Sv 1000000(DRAM 使用限制为 1GB)之后也有效,因此它不会像我之前使用 Imagemagick 所做的尝试那样“消耗大量内存”,这几乎杀死了我的机器。但是 500MB 失败了,因为 ffmpeg 无法加载其共享库...是时候升级您的 RAM 了 ;-)?

这篇文章中描述了测试数据生成过程。

输出具有可见的点图案,这在下面的“ffmpeg + convert”方法中不可见。我们可以尝试使用以下描述的方法来提高图像质量:

例如使用palettegen过滤器:

ffmpeg \
  -i opengl-rotating-triangle.mp4 \
  -r 15 \
  -vf "scale=512:-1,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
  -ss 00:00:03 -to 00:00:06 \
  opengl-rotating-triangle-palettegen.gif
Run Code Online (Sandbox Code Playgroud)

opengl-rotating-triangle-palettegen.gif

在此处输入图片说明

图像信息:979K,45 帧,512x512 外观尺寸,合并,Lenovo P51 上的转换时间:3.5 秒。

所以我们看到:

  • 点图案现在不那么明显了
  • GIF 大小大约翻了一番。TODO:为什么简单地选择调色板会增加图像尺寸?是不是因为现在有更多的颜色,所以我们需要每种颜色更多的位?如何观察每个调色板?
  • 生成时间慢了 7 倍,大概是因为 ffmpeg 首先扫描整个视频以确定最佳调色板

我们还可以使用记录的palettegen参数,例如palettegen=max_colors=16实现不同尺寸质量的权衡点。

参数分解

摄像机镜头示例

如果您想使用类似的命令查看来自 Wikimedia Commons 的摄像机视频的结果质量:

wget https://upload.wikimedia.org/wikipedia/commons/f/f9/STS-132_Liftoff_Space_Shuttle_Atlantis.ogv
ffmpeg -i STS-132_Liftoff_Space_Shuttle_Atlantis.ogv -r 15 -vf scale=512:-1 \
  -ss 00:00:17 -to 00:00:22 STS-132_Liftoff_Space_Shuttle_Atlantis.gif
Run Code Online (Sandbox Code Playgroud)

STS-132_Liftoff_Space_Shuttle_Atlantis.gif

在此处输入图片说明

图像信息:1.3MB,75 帧,512x288 外观尺寸,合并(但是影响很小,因为镜头从一开始就轻微平移),Lenovo P51 上的转换时间:2.3 秒。

这是一个palettegen只有 2 秒才能满足 2MiB 上传限制的版本:

在此处输入图片说明

图像信息:1.5MB,30 帧,512x288 外观尺寸,Lenovo P51 转换时间:43 秒。

更直接的:

sudo apt-get install ffmpeg
ffmpeg -i in.mp4 out.gif
Run Code Online (Sandbox Code Playgroud)

也可以工作,但输出 GIF 将比输入视频大得多,因为视频格式可以使用高级算法更有效地跨帧压缩,而 GIF 只能执行简单的矩形帧 diff

18.04 之前:ffmpeg+convert没有中间文件的单行

ffmpeg以前无法处理 GIF。我拥有的最好的东西是:

sudo apt-get install ffmpeg imagemagick
ffmpeg -i opengl-rotating-triangle.mp4 -r 15 -vf scale=512:-1 \
  -ss 00:00:03 -to 00:00:06 -f image2pipe -vcodec ppm - |
  convert -deconstruct -delay 5 -loop 0 - opengl-rotating-triangle-image-magick.gif
Run Code Online (Sandbox Code Playgroud)

opengl-rotating-triangle-image-magick.gif

在此处输入图片说明

图像信息:995kB,45 帧,512x512 外观尺寸,合并。

对于亚特兰蒂斯号航天飞机的镜头,类似的:

ffmpeg -i STS-132_Liftoff_Space_Shuttle_Atlantis.ogv -r 15 -vf scale=512:-1 \
  -ss 00:00:17 -to 00:00:22 -f image2pipe -vcodec ppm - |
  convert -deconstruct -delay 5 -loop 0 - STS-132_Liftoff_Space_Shuttle_Atlantis_512x.gif
Run Code Online (Sandbox Code Playgroud)

产生了更好看的输出,但最终的 GIF 相当大,为 6.2MB,所以我无法上传它。

一些论据的解释:

即使您降低高度和帧率,输出的 GIF 仍然可能比视频大,因为“真实”非 GIF 视频格式跨帧压缩,而 GIF 仅压缩单个帧。

一个直接:

convert input.mp4 rpi2-bare-metal-blink.gif
Run Code Online (Sandbox Code Playgroud)

工作,但由于内存溢出几乎杀死了我的计算机,并且为我的 2s 1Mb 输入文件产生了 100 倍的输出。也许有一天 ImageMagick 会迎头赶上。

另见:https : //superuser.com/questions/556029/how-do-i-convert-a-video-to-gif-using-ffmpeg-with-reasonable-quality

在 Ubuntu 17.10 上测试。

吉夫斯基

https://gif.ski/

这是引起我注意的另一个选项,它声称具有智能算法,所以让我们尝试一下。

首先,我们需要将视频转换为一系列图像,然后将其输入 gifsky,例如:

sudo snap install gifski
mkdir -p frames
ffmpeg \
  -i opengl-rotating-triangle.mp4 \
  -r 15 \
  -vf scale=512:-1 \
  -ss 00:00:03 -to 00:00:06 \
  frames/%04d.png
gifski -o opengl-rotating-triangle-gifski.gif frames/*.png
Run Code Online (Sandbox Code Playgroud)

opengl-旋转三角形-gifski.gif

在此处输入图片说明

图像信息:954K,45 帧,512x512 外观尺寸,未合并,Lenovo P51 上的转换时间:4.8 秒。

和 2 秒 STS:

在此处输入图片说明

图像信息:1.6M,30 帧,512x288 外观尺寸,未合并,Lenovo P51 上的转换时间:2.8 秒。

所以对我来说,主观上,这似乎并没有比 ffmpeg 的palettegen.

  • 我同意。小尺寸的 gif 更适合网络。感谢 `scale=320:-1` (2认同)
  • 对于那些想知道的人:删除 `-r 10` 将使 GIF 恢复正常速度。 (2认同)
  • 我的 gif 比 mp4 大 20% :O (2认同)

May*_*hux 127

两个步骤:

您最终会得到一个相当大的文件,请查看图像魔法指南以优化 gif选项,您可以将其添加到第二步命令中以获得较小的文件。

  • 请记住,第一个命令必须存在 `frames` 文件夹。 (4认同)
  • 对于那些想要一种通常有效的快速优化方法并且懒得阅读链接的人,只需将 `-layers Optimize` 添加到最后一个 `convert` 命令,在 `*.jpg` 之前。但是检查输出,它可能会受到影响。对我来说,它将 gif 大小从 5 MB 减少到 700 KB,而没有任何可察觉的质量损失:) (4认同)
  • 不使用 JPG 文件格式,默认设置非常有损,我建议使用 PNG 进行初始文件导出。`ffmpeg -i video.mp4 -r 5 'frames/frame-%03d.png'`。 (3认同)

ccp*_*zza 12

gifify是一种多合一的基于节点的实用程序,可简化转换。这取决于nodejs, npm, ffmpeg, 和imagemagick哪些都可以在存储库中使用。

一旦你已经npm安装了可以安装gifify在全球:

    npm install -g gifify
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式将视频转换为 .GIF:

    gifify video.mp4 -o video.gif
Run Code Online (Sandbox Code Playgroud)

您还可以选择在视频中设置开始和结束位置并添加文本标题:

    gifify clip.mp4 -o clip.gif --from 01:48:23.200 --to 01:48:25.300 --text 'we are the knights who say nip!'
Run Code Online (Sandbox Code Playgroud)

?? 即使是较小的视频,转换也可能需要几分钟时间才能完成。

注意:ffmpeg并且imagemagick可能需要使用一些特定的库(即相应的 libass 和 fontconfig)进行编译。