如何在命令行中制作和优化 GIF

介绍

除了 JPGPNG, GIF是自20世纪90年代以来流行的最常见图像格式之一。

GIF实际上是一个旧的技术,它们现在比在许多情况下嵌入网页视频更低效率,这是因为大多数网页视频使用现代视频压缩技术和比GIF更受欢迎的现代编码器。 _Codecs_用于编码和解码视频,大多数平台都有专用的硬件来播放这些编码器。 GIF,另一方面,总是通过CPU直接解码。

然而,GIF仍然是有用的,因为它们被认为是图像而不是视频. 由于 Web 和其他应用程序的工作方式,这意味着它们将在更多情况下自动渲染和动画,不需要单独嵌入或链接。

在本教程中,您将尝试几个工具来从视频片段创建GIF,优化它们的尺寸和质量,并确保您可以在许多情况下使用它们。

前提条件

本教程将为 Ubuntu 22.04 服务器提供安装说明,您可以通过遵循我们在 Ubuntu 22.04 初始服务器设置上的指南来设置此设置。

您还需要安装 Homebrew包管理器来安装本教程中的工具之一。

步骤 1 — 安装 ffmpeg、Gifski 和 Gifsicle

在本教程中,您将需要三个工具来跟随这些示例,首先是: ffmpeg用于剪辑和操纵视频,然后是 Gifski用于创建GIF,最后是 Gifsicle用于优化和进一步操纵您的GIF。

ffmpeggifsicle都可在Ubuntu的默认存储库中使用,并且可以通过apt包管理器安装。

1sudo apt update

然后,安装ffmpeggifsicle包与apt install:

1sudo apt install ffmpeg gifsicle

最后一个工具,gifski,是通过Homebrew可用的。安装它与brew安装(这将需要几分钟,因为Homebrew安装其他依赖):

1brew install gifski

您现在已经在您的机器上安装了所有必要的工具,接下来,您将开始通过获得样本视频来创建一个GIF。

步骤 2 – 下载和检查样本视频

如果您还没有想要使用的视频,您可以使用我们的视频在 Introducing App Platform by DigitalOcean作为起点。

您可以从我们的服务器上从其他地方下载本视频的副本,使用curl:

1curl -O https://deved-images.nyc3.digitaloceanspaces.com/gif-cli/app-platform.webm

curl是一个用于制作各种Web请求的命令行工具. 使用带有URL的O旗指示curl下载远程文件并将其以相同的文件名本地存储。

现在你有本地视频的副本,你可以检查其中的一些元数据。当你试图创建高质量的GIF时,这将是相关的。当你早些时候安装ffmpeg时,它还包含了一个命令,名为ffprobe,可以用来检查媒体文件中的分辨率,framerate和其他信息。

1ffprobe app-platform.webm
 1[secondary_label Output]
 2 3Input #0, matroska,webm, from 'app-platform.webm':
 4  Metadata:
 5    ENCODER         : Lavf59.27.100
 6  Duration: 00:01:59.04, start: -0.007000, bitrate: 1362 kb/s
 7  Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv, bt709), 1920x1080, SAR 1:1 DAR 16:9, 25 fps, 25 tbr, 1k tbn (default)
 8    Metadata:
 9      DURATION        : 00:01:59.000000000
10  Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
11    Metadata:
12      DURATION        : 00:01:59.041000000

输出列出了文件中包含的任何流(通常是一个视频和至少一个音频流),以及流的样本速率,编解码器和其他属性. 从输出中突出的信息中,您了解到这个视频被编码到1080p分辨率,并以每秒25播放。

这是足够的信息,可以转到下一步,你将从这个视频中剪除一个剪辑,从中创建一个GIF。

步骤 3 – 从视频中剪切一个剪辑

现在你有一个长达两分钟的视频文件,你知道它的属性. 在将其切成GIF之前,你唯一需要做的就是从中提取一个更短的剪辑。

在终端壳中播放视频并不太方便,所以您可以与YouTube上的视频一起观看,找到一个理想的切割场所. 在本教程中,您将从00:00:09切割到00:00:12,从而产生相当平滑的动画:

3-second video clip from App Platform launch

您可以通过将app-platform.webm视频转换为ffmpeg来完成此切割:

1ffmpeg -ss 00:00:09 -to 00:00:12 -i app-platform.webm -c copy clip.webm

这个命令被打破了:

  • -ss 00:00:09 -to 00:00:12是如何理解‘ffmpeg’的时代码。在这种情况下,从一个起始位置切割到剪辑中的终结位置。你也可以根据持续时间或一秒的碎片剪辑。
  • -i app-platform.webm是你输入文件的路径,先于‘-i’。
  • -c copy是你通常会指定输出音频或视频编码器为‘ffmpeg’的地方。 使用‘拷贝’而不是编码器可以重新编码视频,这可以更快,避免任何质量损失,只要你不需要瞄准不同的输出格式。 因为你随后会把这个剪辑制作成GIF,保留原生输入格式很好,节省时间。 _

这会创建一个名为clip.webm的新三秒视频,您可以使用ls -lh来验证其存在并检查其大小:

1ls -lh clip.webm
1[secondary_label Output]
2-rw-r--r-- 1 sammy sammy 600K Nov 16 14:27 clip.webm

事实证明,三秒的视频只有600K大小,这将在下一步创建GIF时成为一个很好的比较点。

<$>[注] 注: 如果您在本地机器上工作,您可以使用名为 Lossless Cut的开源GUI工具来执行相同的操作。 Lossless Cut特别有用,因为它运行相同的ffmpeg命令,快速从基于时间代码的视频中提取剪辑,而无需重新编码视频。

步骤 4 – 将视频转换为 GIF

现在你有一个三秒长的视频和其率和分辨率的上限在脑海中,你可以从中创建一个GIF. 如果你正在开发一个自动转换管道上传视频到GIF,它可能有助于自动提取视频分辨率和framerate从ffprobe,直接传递到这些下一个几个命令. 在本教程中,你只会硬编码一些合理的分辨率和framerate值为你的输出。

你可以用ffmpeg自己做,但语法可能很难改变或理解:

1ffmpeg -filter_complex "[0:v] fps=12,scale=w=540:h=-1,split [a][b];[a] palettegen [p];[b][p] paletteuse" -i clip.webm ffmpeg-sample.gif

请注意,在这个例子中,你已经将剪辑的分辨率和缩率降低了大约一半,达到12fps和540p分辨率。这通常是GIF的良好起点。因为GIF像图像一样被处理,它们在网页加载时被下载完整,而与视频不同,它们没有在较低分辨率下逐步流的概念。使用CDN(https://andsky.com/tech/tutorials/what-is-a-cdn)可以帮助优化任何像这些类型的静态网站资产的交付,但你仍然应该试图避免在没有特定原因的情况下提供巨大的图像。因此,在那里,你应该始终避免让你的GIF大于必要;在3M下,图像通常是好的做法。你可以使用ls -lh来检查你的新GIF的文件大小:

1ls -lh ffmpeg-sample.gif
1[secondary_label Output]
2-rw-r--r-- 1 sammy sammy 2.0M Nov 16 14:28 ffmpeg-sample.gif

你以这种方式创建了2M GIF,虽然这很好,但你可以使用gifski的更少复杂语法来产生更好的结果。

1gifski --fps 12 --width 540 -o gifski-sample.gif clip.webm

注意您只需要保留重要细节 - 框架和分辨率 - 以及输入和输出文件名称。

1ls -lh gifski-sample.gif
1[secondary_label Output]
2-rw-r--r-- 1 sammy sammy 1.3M Nov 16 14:33 gifski-sample.gif

这个只有 1.3M,在相同的质量水平上有了显著的改进. 在这个时候,你可能会被诱惑去尝试制作一个全方位,全分辨率的GIF版本。

1gifski --fps 25 --width 1080 -o gifski-high.gif clip.webm

检查这个最新测试文件的大小:

1ls -lh gifski-high.gif
1[secondary_label Output]
2-rw-r--r-- 1 sammy sammy 6.9M Nov 16 14:37 gifski-high.gif

6.9M绝对太大,考虑到您的原始视频片段只有 0.6M! 记住,GIF与现代视频编码器相比并不特别高效。 在编码它们到合理的文件大小时,您需要做出一些小的牺牲。

<$>[注] 注: 在本教程的任何时候,如果您在远程服务器上工作,您可以本地下载和检查您的GIF,甚至可以将其移动到一个可访问的目录中,以便您可以在Web浏览器中查看它们。

步骤 5 – 优化、验证和查看 GIF

对于本教程的最后一步,你将使用gifsicle来改进你的GIF。gifsicle是给GIF的,而ffmpeg是给音频和视频的:它几乎可以做任何事情,但结果可能是相当复杂的。

开始运行标准的gifsicle优化命令:

1gifsicle -O3 --lossy=80 --colors 256 gifski-sample.gif -o optimized.gif

在此命令中,您提供了最具攻击性的优化选项 -O3, --lossy 80 允许从源输入中损失 20% 的图像质量,以及 `--colors 256' 在您的输出图像中使用最多 256 种颜色。这将产生比您可能预期的更高质量的图像,几乎没有可见的图像质量损失,因为 GIF 不会使用现代 跨框视频压缩的视频编码器的方式,也不会默认使用 JPEG 风格的图像压缩技术。

与最后一步一样,检查optimized.gif的大小:

1ls -lh optimized.gif
1[secondary_label Output]
2-rw-r--r-- 1 sammy sammy 935K Nov 16 14:44 optimized.gif

这个最后一步已经成功地将文件大小减少到比原始视频大一点,为动画图像非常合理的935K,这是本教程早些时候显示的相同的优化GIF。

您可以参阅 Gifsicle 手册来了解操纵您的 GIF 的其他方法,例如,您可以将 GIF 爆炸成多个图像文件,每个动画框架一个:

1gifsicle --explode optimized.gif

这会为每个单个图像创建多个文件,名为optimized.gif.000,optimized.gif.001,等等:

1ls -lh optimized*
1[secondary_label Output]
2-rw-r--r-- 1 sammy sammy 935K Nov 16 14:46 optimized.gif
3-rw-r--r-- 1 sammy sammy 20K Nov 16 14:54 optimized.gif.000
4-rw-r--r-- 1 sammy sammy 17K Nov 16 14:54 optimized.gif.001
5-rw-r--r-- 1 sammy sammy 22K Nov 16 14:54 optimized.gif.002
6-rw-r--r-- 1 sammy sammy 22K Nov 16 14:54 optimized.gif.003
7

您还可以使用--rotate-90--rotate-180选项旋转您的 GIF:

1gifsicle --rotate-90 optimized.gif -o rotated.gif

尽管其效率低下,GIF仍然有用,因为它们几乎可以在任何地方使用,当你需要一个短片自动动画时,或者你特别需要一个图像而不是视频格式时,有时没有好的旧GIF的替代品。

结论

在本教程中,您使用了多种工具来从现有视频中创建一个优化的GIF,您还审查了开源视频操纵和GIF操纵工具的生态系统,以及一些进一步编辑GIF的其他选项。GIF是一个有趣的,无时效的技术。在许多方面,它们不是现代的,但在某些情况下仍然没有真正的替代品,而与GIF工作的工具是强大和良好的维护。

接下来,您可能想了解如何在 Node.js 中构建媒体处理 API(https://andsky.com/tech/tutorials/how-to-build-a-media-processing-api-in-node-js-with-express-and-ffmpeg-wasm)。

Published At
Categories with 技术
Tagged with
comments powered by Disqus