02, Moviepy 官方示例-结尾效果

3,360 阅读3分钟

code

from moviepy.editor import *
from moviepy.video.tools.drawing import circle

if __name__ == '__main__':
    video = VideoFileClip('../demo/result.mp4', audio=False).subclip(0, 5).add_mask()
    w, h = video.size
    video.mask.get_frame = lambda t: circle((w,h),(w/2, h/4), radius=max(0, int(900-200*t)), col1=1, col2=0, blur=4)
    the_end = TextClip('The end',font="Amiri-bold", color="white", fontsize=70).set_duration(video.duration)
    # the_end = ImageClip('../demo/123.png').resize(video.size).set_duration(video.duration)
    final = CompositeVideoClip([the_end, video], size=video.size)
    final.write_videofile("../demo/theEnd.mp4")

1, clip

clip是moviepy的一个重要的类。我们一般使用的是他的子类

作用 类名 备注
操作视频剪辑 VideoFileClip
操作音频剪辑 AudioFileClip
操作图片剪辑 ImageClip 继承VideoClip
操作文字剪辑 TextClip 继承ImageClip,其原理是先用imagemagic 生成图片, 再使用imageClip处理
复合视频剪辑 CompositeVideoClip 把视频合并, 注意第一个参数为数组, 后面的片段在前面片段的上面, 重合部分会遮挡下面

如果要使用TextClip, 需要安装imagemagic

2, mask遮罩层

遮罩层, 一般都是黑白灰的。 比如: 视频1, 视频2, mask2 其中视频2设置了遮罩层mask2, 我们使用复合视频剪辑CompositeVideoClip([视频1, 视频2.set_mask(mask2)]), 最终的视频就是 mask2图片区域为白色只能看到视频2, 而区域为黑色的只能看到视频1

啥都不说, 上代码

# coding:utf-8
# Text with moving letters

from moviepy.editor import *
from moviepy.video.tools.drawing import circle
import cv2
import numpy as np

if __name__ == '__main__':
    img1 = ImageClip('../demo/123.png').resize((400, 500)).set_duration(5)

    img2 = ImageClip('../demo/cat.jpg').resize((400, 500)).set_duration(5)

    # 绘制一个40 *500 的黑色矩形, 其中有一个200*200的白色区域
    img3 = np.zeros([500, 400, 3])
    img4 = np.ones((200, 200, 3), np.uint8)
    img4.fill(255)
    img3[100:300, 100:300] = img4
    cv2.imwrite('../demo/mask.png', img3)

    mask = ImageClip('../demo/mask.png').resize((400, 500)).set_duration(5).to_mask()
    final = CompositeVideoClip([img1, img2.set_mask(mask)], size=(400, 500)).set_fps(15)
    final.write_videofile("../demo/mask_demo.mp4")

绘值出来的遮罩层图片:

第一张图片:

第二张图片:

结果截图:

一般来说, 当只有图片1的时候, 如果我们在图片1上面再加一张大小一样的图片2时, 图片1就会被完全遮挡, 这时候我们只能看到图片2, 如果再对图片2 设置遮罩层后, 我们就会发现,遮罩层的白色区域, 我们只能看到图片2, 而遮罩层的黑色区域居然透过了图片2, 看到了最下面的图片1。

3, video.mask.get_frame

可能有人不理解代码中的这一句是什么意思:

video.mask.get_frame = lambda t: circle((w,h),(w/2, h/4), radius=max(0, int(900-200*t)), col1=1, col2=0, blur=4)

我们先来看下circle:

# coding:utf-8
# Text with moving letters

from moviepy.editor import *
from moviepy.video.tools.drawing import circle
import cv2
import numpy as np

if __name__ == '__main__':
    img = circle(screensize=(400, 500), center=(200, 120), radius=100, col1=(0,0,0), col2=(255, 255, 0), blur=4)
    cv2.imshow('circle', img)
    cv2.waitKey(0)

他其实就是在 (400, 500)的画布上, 绘制一个圆心为(200, 120), 半径为100 的圆, col1和col2 标识圆内的颜色和圆外的颜色, 如果用1和0 那么只能用于标识遮罩层。blur表示圆边缘的模糊度

结果如图所示:

那么上面一句就是赋值mask.get_frame函数 为随着时间增大而半径不断减小的一个圆