░ 前往老猿Python博文目录 ░
一、简介
MoviePy是一个用于视频编辑的Python模块,可用于进行视频的基本操作(如剪切、拼接、标题插入)、视频合成(也称非线性编辑)、视频处理或创建高级效果。
它可以读写最常见的视频格式,MoviePy能处理的视频是ffmpeg格式的,老猿理解支持的文件类型至少包括:*.mp4 *.wmv *.rm *.avi *.flv *.webm *.wav *.rmvb等 。
MoviePy使用ffmpeg读取、导出视频和音频文件,使用ImageMagick生成文本和输出GIF文件。Python的快速数字库Numpy保证了不同媒体的处理。高级效果和增强使用了Python的许多图像处理库(PIL、Scikit-image、scipy等)。
moviepy的核心对象是剪辑(clips),包括AudioClips 和VideoClips。它们可以修改(剪切、减速、变暗…)或与剪辑混合以形成新剪辑,可以使用PyGame或IPython Notebook预览,并可以输出到对应类型的文件(如MP4、GIF、 MP3等)。例如,VideoClips可以从视频文件、图像、文本或自定义动画创建。VideoClips可以有一个音频轨道(这是一个AudioClip)和一个mask遮罩(一个特殊的VideoClip,指示当剪辑与其他剪辑混合时要隐藏哪些部分)。
关于moviepy的两个专栏是老猿阅读moviepy库当前最新版本1.0.3的文档、源代码以及大量测试的基础上总结的MoviePy学习教程,本文将两个专栏的核心知识点,包括重要类的相关方法及作用、视频音频剪辑变换方法、场景式的支撑能力进行了导览式介绍,并给出了相关知识点教程的原文链接。
教程同时介绍了使用PyQt+moviepy实现的图形化视频剪辑工具的开发过程,并提供多视频合成(含顺序拼接和同屏播放)、从视频中选择多时间段范围的视频拼接、将视频转动画或图片文件的工具的win7和win10版本可执行文件下载。
二、Moviepy导览
2.1、核心类介绍
2.1.1、剪辑基类clip
Moviepy的剪辑的实现由类库提供基础能力,其中clip类是基类,提供了:
- 设置多个剪辑拼接时设置每个剪辑开始播放开始时间和结束时间的set_start方法和set_end方法
- 设置剪辑时长的set_duration方法
- 获取剪辑帧数据的get_frame方法
- 对剪辑进行变换的fl方法
- 基于剪辑时间线进行变换的fl_time方法
- 对剪辑调用指定函数进行变换的fx方法
- 获取剪辑片段的subclip方法
- 去除剪辑指定时间线范围的cutout方法
注意:截止现有的Moviepy1.03版本,所有剪辑的变换都不是对调用剪辑的改变,而是基于调用者的副本进行的改变,且这些剪辑方法返回的都是变换了的调用者副本。
更多关于剪辑基类clip的介绍请参考公开博文《moviepy音视频剪辑:moviepy中的剪辑基类Clip的属性和方法详解》或付费专栏文章《moviepy音视频剪辑:moviepy中的剪辑基类Clip详解》。
2.1.2、视频剪辑类VideoClip
视频剪辑类VideoClip是视频剪辑的基类,它提供了:
- 将视频中指定时间点的视频转成图像保存的save_frame方法
- 将视频剪辑输出到视频文件的write_videofile方法
- 将视频剪辑按设定频率输出成一张张图片的write_images_sequence方法
- 将视频剪辑输出成gif动画的write_gif方法
- 将视频剪辑应用特定函数进行变换的subfx方法
- 将视频剪辑帧进行扩展或剪裁的fill_array方法
- 给视频剪辑增加遮罩的add_mask方法
- 用于当视频比较小扩展后给视频剪辑无视频部分设置背景色的on_color方法
- 用于使用特定函数构造帧的set_make_frame方法
- 设置剪辑音频的set_audio方法
- 设置剪辑遮罩的set_mask方法
- 调整剪辑透明度的set_opacity方法
- 设置多个剪辑同屏播放时各剪辑在屏幕位置的set_position方法
- 将指定时间的帧变成一个单独的图像剪辑(静止的图像视频剪辑)的to_ImageClip方法
- 将调用者剪辑作为别的剪辑遮罩的to_mask方法
- 将遮罩剪辑变成普通剪辑的to_RGB方法
- 将剪辑去除声音的without_audio方法
- 对剪辑的音频进行变换的afx方法
可以看到VideoClip提供了将视频剪辑进行输出和变换的相关方法,更多关于视频剪辑类VideoClip的内容请参考公开文章《moviepy音视频剪辑:视频剪辑基类VideoClip的属性及方法详解》或付费专栏文章《moviepy音视频剪辑:视频剪辑基类VideoClip详解》。
2.1.3、视频剪辑子类
视频剪辑子类都是从VideoClip直接或间接派生的类,包括:
- 直接从视频文件构读取剪辑的VideoFileClip类
- 将多个VideoClip类剪辑合成一个剪辑的CompositeVideoClip类
- 从一个图片文件夹目录下的所有图片文件构造剪辑的ImageSequenceClip类
- 直接从数组数据构造剪辑的DataVideoClip类
- 可以用于科学研究特定场景的UpdatedVideoClip类,UpdatedVideoClip类构造的剪辑要求满足基于时间线要求的设定条件才会输出帧
- 从一个图像文件或图像数组构造静态图像剪辑的ImageClip类
- 仅显示一种颜色的剪辑ColorClip类
- 用于生成文字视频的TextClip类。
更多关于这些类的介绍请参考公开博文《moviepy音视频剪辑:视频基类VideoClip子类VideoFileClip、CompositeVideoClip、ImageSequenceClip介绍》、《moviepy音视频剪辑:视频基类VideoClip子类DataVideoClip、UpdatedVideoClip、ImageClip、ColorClip、TextClip类详解》或付费专栏文章《moviepy音视频剪辑:视频基类VideoClip子类VideoFileClip、CompositeVideoClip、ImageSequenceClip介绍及使用案例》、《moviepy音视频剪辑:视频基类VideoClip子类DataVideoClip、UpdatedVideoClip、ImageClip、ColorClip、TextClip及使用案例》。
需要注意的是TextClip是基于安装了ImageMagick才能使用,并且中文处理还有些特殊注意的地方,具体请参考付费专栏文章《moviepy音视频剪辑:视频基类VideoClip子类DataVideoClip、UpdatedVideoClip、ImageClip、ColorClip、TextClip及使用案例》。
2.1.4、音频剪辑类
在本部分介绍了:
- 音频的基本概念以及音频剪辑基类AudioClip类,AudioClip类可以使用write_audiofile方法将音频剪辑输出到文件、使用max_volume方法恢复音频剪辑的最大音量、使用iter_chunks方法迭代访问音频剪辑的内容、使用to_soundarray输出音频剪辑特定时刻的片段,关于这些的详细内容请参考《moviepy音视频开发:音频剪辑基类AudioClip》或付费专栏文章《moviepy音视频开发:音频剪辑基类AudioClip详解》
- 从音频文件或视频文件中的音频读取音频构建音频剪辑的AudioFileClip类,详细内容请参考《moviepy音视频开发:音频文件存取类AudioFileClip属性和方法介绍》
- 将几个音频剪辑合成一个音频剪辑的CompositeAudioClip类,详细内容请参考《moviepy音视频开发:音频合成类CompositeAudioClip介绍》
- 从一个numpy数组构建音频剪辑AudioArrayClip类,详细介绍请参考《moviepy音视频开发:音频合成类AudioArrayClip介绍》
2.2、视频和音频剪辑合成变换方法
2.2.1、视频变换原理以及视频变换基础方法fl
视频帧在程序中被表示为与视频分辨率大小对应的一个三维矩阵,这个矩阵的行数是视频的高、列数是视频的宽,元素是YUV表示的像素点。视频剪辑变换本质上就是对帧数据的处理,也就是对帧对应的三维数组数据的操作。
可以使用fl方法进行视频的剪辑变换处理,fl方法是视频变换的基础方法,所有Moviepy的其他变换方法如fl_time以及后面介绍的其他变换函数都是基于fl来实现的。
更多关于视频变换的原理及fl方法的内容请参考《Python+moviepy音视频剪辑:视频帧数据的本质、Clip的fl方法进行变换处理的原理以及滚屏案例》。
2.2.2、时间特效变换方法fl_time
时间特效处理可以实现快播、慢播、倒播等,时间特效处理使用fl_time方法,它是基于前面介绍的fl方法的实现。
时间特效处理其实非常简单,就是对时间的一个变换,变换时,假设t1是剪辑的时间线,从0开始一直到剪辑的最后end地方的一个线性坐标,而时间特效是通过调用函数或方法得到t2,t2 = t_fun(t1),然后特效处理后的剪辑时间线t1对应的帧被替换为原剪辑t2位置的帧。
MoviePy中提供的与时间相关的变换函数如speedx等都是通过fl_time实现的。
更多关于时间特效的处理fl_time方法请参考《moviepy音视频剪辑:使用fl_time进行诸如快播、慢播、倒序播放等时间特效处理的原理和可能遇到的坑》或付费专栏文章《moviepy音视频剪辑:使用fl_time进行诸如快播、慢播、倒序播放等时间特效处理的原理、代码实现以及需要注意的坑》。
2.2.3、视频剪辑颜色变换函数
除了使用fl方法以及fl_time方法进行剪辑变换外,MoviePy还提供了一些通过二者实现的一些特定变换函数,好方便使用者能快速使用,这些变换函数老猿将其为分为颜色变换、时间变换、大小变换、内容变换四个部分。
颜色变换函数包括:
- blackwhite函数将剪辑变为灰度剪辑,即黑白视频
- colorx函数调整剪辑颜色的饱和度,使剪辑的明度变大或降低
- fadein、fadeout实现剪辑开头或结尾的淡入淡出处理
- gamma_corr对剪辑图像进行gamma修正
- invert_colors函数实现剪辑像素颜色反转,即负片转换
- lum_contrast函数对剪辑的亮度对比度(luminosity-contrast )进行校正
- mask_color函数基于剪辑自身的像素值给剪辑生成不同透明度遮罩
更多关于视频剪辑颜色变换函数的详细内容请参考《moviepy音视频剪辑:颜色相关变换函数blackwhite、colorx、fadein/out、gamma_corr、invert_colors、lum_contrast、mask_color介绍》或付费专栏文章《moviepy音视频剪辑:颜色相关变换函数blackwhite、colorx、fadein/out、gamma_corr、invert_colors、lum_contrast、mask_color详解》
2.2.4、视频剪辑时间变换函数
与时间变换相关的时间特效函数包括:
- 将指定时刻位置的帧延时显示的freeze函数
- 将剪辑中指定屏幕范围内容固定为参数指定的某个时刻的内容的freeze_region函数
- 将剪辑重复n次或无限循环的loop函数
- 使剪辑在它自己的末端逐渐淡入的make_loopable函数
- 调整剪辑播放速度的speedx函数
- 倒序播放剪辑的time_mirror函数
- 合成当前剪辑叠加自身倒序播放剪辑的time_symmetrize函数
详细内容请参考《moviepy音视频剪辑:与time时间线相关的变换函数freeze_region、make_loopable、speedx、time_mirror、time_symmetrize介绍》或付费专栏文章《moviepy音视频剪辑:与time时间线相关的变换函数freeze_region、make_loopable、speedx、time_mirror、time_symmetrize详解及使用案例》。
2.2.5、视频剪辑大小变换函数
视频剪辑大小变换函数包括:
- 从视频中选择一个矩形范围生成新剪辑的crop函数
- 在剪辑的四周增加一个外边框的margin函数
- 调整剪辑的大小的resize函数
详细内容请参考《moviepy音视频剪辑:与大小相关的视频变换函数crop、even_size、margin、resize介绍》或付费专栏文章《moviepy音视频剪辑:与大小相关的视频变换函数详解》。
2.2.6、视频剪辑内容变换函数
视频剪辑内容变换函数包括:
- 实现人脸模糊化的headblur函数
- 将两个遮罩剪辑的所有像素的RGB值各取最小值作为新剪辑的像素RGB值mask_and函数
- 将两个遮罩剪辑的所有像素的RGB值各取最大值作为新剪辑的像素RGB值mask_or函数
- 将剪辑内容左右对换或上下颠倒的mirror_x、mirror_y函数
- 对剪辑中的图像使用画笔特效的painting函数
- 将剪辑逆时针旋转指定的角度或弧度的rotate函数
- 在屏幕上水平或垂直滚动播放剪辑的内容的scroll函数
- 对剪辑像素值调整为前后一段时间范围剪辑像素的算术平均值的supersample函数
详细内容请参考《moviepy音视频剪辑:视频变换处理与内容相关的变换函数headblur、mask_and/or、mirror_x/y、rotate、painting、scroll介绍》或付费专栏文章《moviepy音视频剪辑:视频变换处理与内容相关的变换函数介绍》。
2.3、场景化支撑能力介绍
- 可以使用VideoFileClip、AudioFileClip和write_videofile、write_audiofile进行音视频的加载和输出
- 可以使用concatenate_videoclips和clips_array将多个视频合成一个顺序播放或同屏播放的视频
- 输出视频文件前使用preview和imdisplay预览剪辑和视频帧
- 使用manual_tracking和headblur实现手动追踪人脸打马赛克
- 使用manual_tracking、autoTrack和headblur 视频半自动追踪人脸打马赛克
- 使用credits1给视频加片头片尾字幕
相关文章请参考《PyQt+moviepy音视频剪辑实战文章目录》或付费专栏文章《moviepy音视频开发专栏文章目录》中的“moviepy场景化功能的支撑能力介绍”部分。
2.4、部分实战案例以及可执行工具
本部分主要介绍笔者用PyQt+moviepy实现的图形化视频剪辑工具,目前已经提供了多视频合成(包括顺序拼接和同屏播放)、从视频中选择多个时间段范围的视频进行拼接、将视频转动画或图片文件的工具,并提供相关工具的win7和win10下的打包可独立执行文件包的下载。
相关内容请参考《PyQt+moviepy音视频剪辑实战文章目录》或付费专栏文章《moviepy音视频开发专栏文章目录》中的“moviepy实战案例”部分。
2.5、moviepy部分关键知识点
这是老猿认为的MoviePy重要的知识点的介绍,相关文章请参考《PyQt+moviepy音视频剪辑实战文章目录》或付费专栏文章《moviepy音视频开发专栏文章目录》中的“moviepy部分关键知识点”部分。
2.6、moviepy学习遇到的坑
moviepy学习中遇到的问题不少,老猿将使用moviepy开发碰到的一些棘手问题的解决情况整理成单独的博文进行了介绍,相关文章请参考《PyQt+moviepy音视频剪辑实战文章目录》或付费专栏文章《moviepy音视频开发专栏文章目录》中的“moviepy学习遇到的坑”部分。
2.7、图形图像及音视频处理的基础知识
本部分主要适合笔者这种图像及音视频处理小白,在学习moviepy过程中发现需要了解的一些图形图像及音视频处理的基础知识的总结或转载。相关文章请参考《PyQt+moviepy音视频剪辑实战文章目录》或付费专栏文章《moviepy音视频开发专栏文章目录》中的“图形图像及音视频处理的基础知识”部分。
三、小结及后续安排
整个Moviepy的学习到现在断断续续已经三个多月,在学习过程中,老猿基于阅读moviepy1.03版本的源代码以及大量测试验证的基础上,将相关知识进行了总结,发布成了免费专栏《专栏:PyQt+moviepy音视频剪辑实战》和收费专栏《专栏:*moviepy音视频开发专栏》。两个专栏的内容基本对应,只是收费专栏内容相比免费专栏更详细和深入、案例更多。如果大家跟随老猿的学习脚步,应该还是有比较大的收获。
要学习和研究的东西很多,上述两个专栏将接近收尾,后续主要将不定期补充部分场景化能力或实战案例。
更多moviepy的介绍请参考《PyQt+moviepy音视频剪辑实战文章目录》或《moviepy音视频开发专栏》。
关于老猿的付费专栏
老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只需要19.9元,都适合有一定Python基础但无相关专利知识的小白读者学习。这2个收费专栏都有对应免费专栏,只是收费专栏的文章介绍更具体、内容更深入、案例更多。
收费专栏文章目录:《moviepy音视频开发专栏文章目录》、《使用PyQt开发图形界面Python应用专栏目录》。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。