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

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

我想用视频制作动画.gif.mp4我更喜欢通过命令行来做,所以请只列出命令行工具。

答案1

ffmpeg3.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

opengl-旋转三角形.gif

在此处输入图片描述

图像信息:426kB,45 帧,512x512 表观尺寸,合并,在联想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

opengl-旋转三角形调色板.gif

在此处输入图片描述

图像信息:979K,45 帧,512x512 表观尺寸,合并,在联想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

STS-132_升空_航天飞机_亚特兰蒂斯号.gif

在此处输入图片描述

图像信息:1.3MB,75 帧,512x288 表观尺寸,合并(但效果极小,因为镜头从一开始就略微平移),在联想 P51 上的转换时间:2.3 秒。

palettegen这是一个只需 2 秒即可满足 2MiB 上传限制的版本:

在此处输入图片描述

图像信息:1.5MB,30帧,512x288表观尺寸,在联想P51上的转换时间:43秒。

更直接的:

sudo apt-get install ffmpeg
ffmpeg -i in.mp4 out.gif

也可以,但输出的 GIF 会比输入的视频大得多,因为视频格式可以使用高级算法更有效地跨帧压缩,而 GIF 只能简单的矩形框架差速器

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

opengl-旋转三角形图像-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

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

对一些论点的解释:

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

直接:

convert input.mp4 rpi2-bare-metal-blink.gif

可以工作,但几乎因为内存溢出而导致我的电脑死机,并且为我的 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

opengl-旋转三角形-gifski.gif

在此处输入图片描述

图像信息:954K、45 帧、512x512 表观尺寸、未合并、在联想 P51 上的转换时间:4.8 秒。

2s STS 如下:

在此处输入图片描述

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

因此对我来说,主观上,这似乎并没有比 ffmpeg 带来显著的优势palettegen

答案2

两个步骤:

  • 从视频中提取图像

    在与文件相同的目录中创建一个名为 frames 的目录.mp4。使用命令:

    ffmpeg -i video.mp4  -r 5 'frames/frame-%03d.jpg'
    


    -r 5 stands for FPS value
        for better quality choose bigger number
        adjust the value with the -delay in 2nd step
        to keep the same animation speed
    
    %03d gives sequential filename number in decimal form
    

    来源

  • 将图像转换为 gif

    cd frames
    convert -delay 20 -loop 0 *.jpg myimage.gif
    


    -delay 20 means the time between each frame is 0.2 seconds
       which match 5 fps above.
       When choosing this value
           1 = 100 fps
           2 = 50 fps
           4 = 25 fps
           5 = 20 fps
           10 = 10 fps
           20 = 5 fps
           25 = 4 fps
           50 = 2 fps
           100 = 1 fps
           in general 100/delay = fps
    
    -loop 0 means repeat forever
    

    文档:转换 gif 选项

你最终会得到一个相当大的文件,看看图像魔法指南来优化 gif您可以在选项上添加到第二步命令以获得更小的文件。

答案3

图像化是一款基于节点的一体化实用程序,可简化转换。它依赖于nodejs、、npmffmpegimagemagick这些都在存储库中可用。

安装完成后,npm可以gifify使用以下命令进行全局安装:

    npm install -g gifify

可以使用以下方法将视频转换为 .GIF:

    gifify video.mp4 -o video.gif

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

    gifify clip.mp4 -o clip.gif --from 01:48:23.200 --to 01:48:25.300 --text 'we are the knights who say nip!'

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

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

答案4

全面披露:这是我的项目。

如果你使用的是 Linux,你可以使用Linux-mpv-gif 生成器

您将需要 ffmpeg、kdialog 和 mpv。

sudo apt install ffmpeg kdialog mpv

你必须mpv-gif.lua放在$HOME/.config/mpv/scripts

现在,当您在 mpv 上运行视频时,您将能够使用g设置起始帧、G设置结束帧、Ctrl+g创建 gif。当您按下 时Ctrl+g,它会询问您要将 gif 保存在哪里。

相关内容