前言

上一篇文章讲了 MoviePy 的一些使用,今天来说一下怎么把视频转成 gif ,以及怎么把 gif 转成视频。

视频转 gif

1
2
3
4
path = "input.mp4"
basename = os.path.basename(path).split(".") # 提取不带扩展的文件名
video = VideoFileClip(path)
video.write_gif(basename[0] + ".gif") # 使用 write_gif 把视频转成gif

直接把视频转成 gif 文件会很大,我们通过控制显示帧数来减小文件的大小

1
2
3
4
path = "input.mp4"
basename = os.path.basename(path).split(".")
video = VideoFileClip(path)
video.write_gif(basename[0] + ".gif", fps=24) # 设置帧率为24

通过更改帧率有一定程度的减小文件大小,不过效果不是很好。

批量转换

有了上面的基础,就可以把目录下的所有视频都转成 gif ,这样效率就非常高了。

1
2
3
4
5
items = os.listdir(".") # 获取当前目录下的所有文件
for item in items:
    basename = os.path.basename(item).split(".")
    video = VideoFileClip(os.path.abspath(item))
    video.write_gif(basename[0] + ".gif")

把 gif 转为视频

上面说了把视频转成 gif ,我转念一想是不是可以把 gif 转回视频,带着这个想法我写下了如下代码

1
2
video = VideoFileClip("input.gif")
video.write_videofile("output.mp4") # 使用 write_videofile把gif转成MP4格式的视频

结果还真可以,把 gif 转成视频了,占用的空间就小了,因为视频有压缩。

为什么转成 gif 文件还变大了?

首先,我们看到的动画其实本质就是一张张不同的图片快速播放,造成了视觉错觉,所以看起来画面像是会动一样。

gif 里面存储的就是这一张张图片,所以 gif 的文件大小一定是要大于/等于这些图片文件大小的总和。

Mac 上你可以使用下面这条指令来把 gif 中图片提取出来

1
convert input.gif frame-%02d.png

再来说下视频,视频其实也是一张张不同的图片快速播放,但是视频会对这些图片进行压缩。在播放的时候会进行解码,保存成文件的时候会进行编码。因为相近的图片大部分的像素是一样的所以进行压缩是可行的。

常用的压缩算法有 H.264/AVCH.265/HEVC

经过算法压缩后所以最后的文件不会那么大。如果不压缩那么你的磁盘存不了 1 部电影。

一部未经编码的 720p 电影的大小取决于几个因素,包括电影的长度、每秒帧数(fps)和位深度(表示每个像素的位数)。

作一个粗略的估计,720p 分辨率通常被是 1280 x 720 像素。假设 24 位颜色深度和 24 fps,则一秒钟的 720p 视频的未压缩大小将约为 1.3 GB(1280 x 720 x 24 x 24 bits/8 bits/byte = 1.3 GB)。帧率一般要到 60 才算流畅。

因此,一部 720p 电影的整体大小,例如两个小时,将是约 1.3 GB/秒 x 7200 秒 = 9440 GB 或约 9.4 TB。

参考

关注公众号[devbins],回复[gif]获取源码