Pygame教程系列二:MoviePy视频播放篇

【前言】

     在pygame 2.0.0版本之前,播放视频可以使用pygame.movie.Movie('xxxx.mpg')播放(只支持.mpg格式的视频),但是在pygame
2.0.0之后,作者因为觉得视频模块维护成本太高就给抛弃了,假如你使用pygame 2.0.0+,还调用上述方法就会出现以下报错:NotImplementedError: movie module not available (ModuleNotFoundError: No module named 'pygame.movie'),那么,用pygame游戏引擎开发出来的界面还有办法可以播放视频吗?寻寻觅觅找了好久,发现有个叫MoviePy的python模块刚好是利用pygame进行视频预览的,可以拿来一用

一、MoviePy简介

      MoviePy是一个用于视频编辑的Python模块,可用于基本操作(例如剪切,串联,标题插入),视频合成(也称为非线性编辑),视频处理或创建高级效果,也可以读写最常见的视频格式,包括GIF。

二、MoviePy安装

使用pip进行安装

pip install moviepy

上面安装过程中,会把它的依赖库: Numpy, imageio, Decorator, tqdm,ffmpeg 自动下载安装好

三、MoviePy使用

阅读本篇之前,建议先阅读上一篇:Pygame教程系列一:快速入门篇,本篇只是在上一篇的基础上增加一个开头视频的播放

1、案例效果展示

2、示例代码

from moviepy.editor import *
import pygame
# 标识是否退出循环
exitFlag = False
# 设置画面刷新的帧率,即1s内刷新几次
FPS = 10
# 播放开头视频,截取开始的3s,来播放
clip = VideoFileClip(r'E:\AS-workspace\pygameTest\video\TomCat.mp4').subclip(0,3)
# 设置窗口标题
pygame.display.set_caption("pygame视频教程")
# 设置窗口大小
surface = pygame.display.set_mode(clip.size)
# 设置icon
icon = pygame.image.load('E:\AS-workspace\pygameTest\drawable\icon.png').convert_alpha()
pygame.display.set_icon(icon)
# 全屏模式预览播放
clip.preview()
# 关闭并释放资源
clip.close()
# 加载本地图片
bgSurface = pygame.image.load('E:\AS-workspace\pygameTest\drawable\BG.jpg').convert()
# 获取游戏时钟
clock = pygame.time.Clock()
# 图片缩放
scaleImg = pygame.transform.scale(icon, (400, 400))
# 获取图片的矩形框
rect = scaleImg.get_rect()
# 移动步长
step = 10
# 绘制背景
surface.blit(bgSurface,(0,0))
# 刷新帧率
newRect = None
while not exitFlag:
    clock.tick(FPS)
    # 重新绘制背景指定区域,等同于擦除图片效果
    if rect:
        surface.blit(bgSurface, rect,rect)
    # 图片移动指定步长
    newRect = rect.move(step, 0)
    # 弹出事件,这个一定要写,要不事件栈满了之后就会卡死
    for event in pygame.event.get():
        # 点击关闭
        if event.type == pygame.QUIT:
            exitFlag = True
    # 绘制图片到屏幕画布指定区域
    surface.blit(scaleImg,newRect)
    # 控制在窗口内来回移动
    if newRect.x > 800 - newRect.w:
        step = -10
    elif newRect.x < 0:
        step = 10

    # 更新绘制到屏幕上
    pygame.display.update([rect,newRect])
    rect = newRect

if __name__ == '__main__':
    pass

3、代码详析

1)使用MoviePy的视频预览功能,需要声明导入以下库:

from moviepy.editor import *

注意,一般IDE工具会提示导入以下库:

from moviepy.video.io.VideoFileClip import VideoFileClip

但是,这个类VideoFileClip里面并没有preview()这个预览方法,因为这个方法是在moviepy.editor这个类中声明赋值VideoFileClip类的,所以按工具提示导入会找不到preview()方法
Pygame教程系列二:MoviePy视频播放篇_第1张图片

2)对比于上一篇的示例代码,你会发现这一篇使用pygame时候,没有调用pygame.init(),可能有人会问:上一篇不是说使用pygame之前一定要先初始化吗?答案是:没错,使用之前一定要先调用pygame.init()进行初始化,这一篇你没看到我代码中有调用这个初始化代码,那是因为moviepy.video.io.preview这个类已经有对pygame进行初始化了,下图是该类的截图:
Pygame教程系列二:MoviePy视频播放篇_第2张图片
3)上面的这个导入语句:from moviepy.editor import * 会将 moviepy.video.io.preview类导入,导入preview的同时,那个pg.init()这个初始化语句也已经被导入调用了,所以在这里我们就不需要再多调用一遍了

4)clip = VideoFileClip(r'E:\AS-workspace\pygameTest\video\TomCat.mp4').subclip(0,3), 加载本地视频并截取视频的0~3s部分赋值给clip对象

5)pygame.display.set_caption("pygame视频教程"),设置窗口的标题;其实从上面preview类的截图可看到,preview类里面有设置窗口标题为MoviePy,这里需要重新设置为自己想要的标题,否则标题就会显示MoviePy

6)在调用clip.preview()之前,正常来说,是不应该调用set_mode()的,因为在preview()方法中会重新设置窗口大小为视频的大小:
Pygame教程系列二:MoviePy视频播放篇_第3张图片

7)但是假如不先调用set_mode(),又想要调用pygame.image.load() 加载图片然后设置窗口图标的话, 运行会报错:pygame.error: No video mode has been set,所以只能老实地先设置窗口大小为视频的宽高,然后再设置窗口图标

# 设置窗口大小
surface = pygame.display.set_mode(clip.size)
# 设置icon
icon = pygame.image.load('E:\AS-workspace\pygameTest\drawable\icon.png').convert_alpha()
pygame.display.set_icon(icon)

8)调用clip.preview(),就可以播放视频,这个方法也可以设置直接全屏播放:clip.preview(fullscreen=True),还可以设置视频播放的帧率:clip.preview(fps=5)

9)视频播放完毕之后,记得调用clip.close(),来释放占用的资源

【扩展讨论】

我们看看preview()方法里面的实现:
Pygame教程系列二:MoviePy视频播放篇_第4张图片
Pygame教程系列二:MoviePy视频播放篇_第5张图片
1、实际上moviePy preview播放视频是把视频某个时间点对应的那一帧图片绘制到屏幕surface对象而已

2、preview()也在循环体中对事件队列做了处理,在点击窗口的关闭按钮或者按Esc键就会退出绘制视频画面的循环体,所以最上面那段代码,假如我们在播放视频时候点击关闭按钮,那么就会直接跳过播放视频这段代码,继续执行clip.preview()后面的代码

你可能感兴趣的:(python,pygame,python,游戏)