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 秒。
所以我们看到:
我们还可以使用记录的palettegen
参数,例如palettegen=max_colors=16
实现不同尺寸质量的权衡点。
参数分解
-ss 00:00:03 -to 00:00:06
:剪切视频的开始和结束时间。
不,GIF 不是在线盗版分发视频的最佳方式。
另见:https : //stackoverflow.com/questions/18444194/cutting-the-videos-based-on-start-and-end-time-using-ffmpeg
-vf scale=512:-1
: 使输出512
像素为高,并调整宽度以保持纵横比。
这是网络图像的常见用例,其分辨率往往比视频小得多。
如果删除此选项,则输出 GIF 与输入视频的高度相同。
例如,可以通过以下方式找到原始视频高度ffprobe
:https : //superuser.com/questions/595177/how-to-retrieve-video-file-information-from-command-line-under-linux/1035178#1035178并且是在我们的例子中为 1024 x 1024。
-r 15
:采样 FPS。
例如,原始视频为 30 FPS,因此-r 15
意味着ffmpeg
每 2 ( = 30 / 15
)帧将选取一帧。
然而,感知输出 FPS 会调整以匹配输入,因此您不会注意到加速,只会注意到更大的粒度。
输入 FPS 可以用 找到ffprobe
,输入帧的总数可以用 找到,mediainfo
解释如下:https : //superuser.com/questions/84631/how-do-i-get-the-number-of-frames -in-a-video-on-the-linux-command-line/1044894#1044894
我推荐这个选项,因为视频格式通常有更高的帧率,因为分辨率更高。对于较小的 GIF,较低的帧率不太明显,因此我们可以跳过一些帧并制作较小的 GIF。
摄像机镜头示例
如果您想使用类似的命令查看来自 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,所以我无法上传它。
一些论据的解释:
-loop 0
:将 Netscape Gif 扩展循环计数字段添加到输出中。0 表示无限循环,如下所述:http : //www.vurdalakov.net/misc/gif/netscape-looping-application-extensioneog
,firefox
即使没有它,chrome 默认情况下也会无限循环,所以我不确定它有多必要是了。
-delay 5
:在显示下一帧之前等待的时间,以百分之一秒为单位,如以下所述:https : //en.wikipedia.org/wiki/GIF#Animated_GIF字节 324。所以100
意味着 1 FPS,5
意味着1 / 0.5 == 20FPS
.
-deconstruct
:使用矩形差异跨帧压缩,另请参阅:如何使用 ImageMagick 调整动画 GIF 文件的大小?
即使您降低高度和帧率,输出的 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 上测试。
吉夫斯基
这是引起我注意的另一个选项,它声称具有智能算法,所以让我们尝试一下。
首先,我们需要将视频转换为一系列图像,然后将其输入 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
.
May*_*hux 127
两个步骤:
从视频中提取图像
在与您的.mp4
文件相同的目录中创建一个名为 frames 的目录。使用命令:
ffmpeg -i video.mp4 -r 5 'frames/frame-%03d.jpg'
Run Code Online (Sandbox Code Playgroud)
-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
Run Code Online (Sandbox Code Playgroud)
cd frames
convert -delay 20 -loop 0 *.jpg myimage.gif
Run Code Online (Sandbox Code Playgroud)
-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
Run Code Online (Sandbox Code Playgroud)
文档:转换 gif 选项
您最终会得到一个相当大的文件,请查看图像魔法指南以优化 gif选项,您可以将其添加到第二步命令中以获得较小的文件。
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)进行编译。