moviepy音视频剪辑:视频剪辑基类VideoClip的属性及方法详解

☞ ░ 前往老猿Python博文目录

1、概述

在《moviepy音视频剪辑:moviepy中的剪辑基类Clip详解》和《moviepy音视频剪辑:moviepy中的剪辑基类Clip的属性和方法详解》介绍了剪辑相关类及类关系。能够看到视频剪辑类VideoClip是其中很是重要的一个剪辑类,它主要有六个直接子类(VideofileClip、 ImageSequenceClip、CompositeVideoClip、ImageClip、DataVideoClip、UpdatedVideoClip)和两个间接子类(ColorClip, TextClip)。html

2、VideoClip的构造方法和属性

2.一、构造方法

2.1.一、构造方法语法:

__init__(self, make_frame=None, ismask=False, duration=None, has_constant_size=True)python

2.1.二、参数释义

  • make_frame:帧的构建方法,帧的构建方法用于根据时间构建帧,该方法是get_frame获取帧时调用的方法。帧的构建能够从已有剪辑中获取或变换,也能够代码本身填充;
  • ismask:是否做为遮罩使用
  • duration:构建剪辑的时长
  • has_constant_size:表示是否全部帧大小都是相同,若是是动态图像,该值必须为False,该值用于增长遮罩时使用,若是固定大小,遮罩大小就是剪辑的大小,若是不是,则遮罩大小须要加遮罩的视频帧取对应帧的大小。

2.二、size属性

剪辑的大小和分辨率,是一个二元组,内容为:(宽度,高度),单位是像素,直接经过属性名访问。web

2.三、w,h属性

w,h属性即剪辑的宽和高,单位是像素,实际这两个属性就是从size属性获取的。属性访问直接经过属性名访问。数组

2.四、ismask属性

布尔类型表示剪辑是否为遮罩,该属性在构造方法中传入。网络

2.五、make_frame属性

帧的构建方法,经过构造方法传入或set_make_frame方法设置,帧的构建方法用于根据时间构建帧,该方法是get_frame获取帧时调用的方法。帧的构建能够从已有剪辑中获取或变换,也能够代码本身填充。app

2.六、mask属性

当一个视频帧有遮罩时,使用该属性记录遮罩的剪辑。若是为None,则视频剪辑彻底不透明。能够经过add_mask、set_opacity等方法来构建剪辑的遮罩,也能够经过set_mask来将已有的剪辑设置为视频剪辑的遮罩。框架

2.七、aspect_ratio属性

aspect_ratio属性为剪辑的纵横比,实际上就是剪辑的宽/高。注意该属性为浮点数,只读,经过属性名访问。ide

3、VideoClip的访问方法

3.一、save_frame方法

save_frame方法调用语法以下:
save_frame(self, filename, t=0, withmask=True)svg

该方法用于将t指定时刻位置的帧保存到指定图像文件,t 表示方法能够是以下四种之一:函数

  1. 秒,为一个浮点数数字,如75.35
  2. 分钟和秒组成的元组,如(1,15.35)
  3. 时、分、秒组成的元组,如(0,1,15.35)
  4. 用冒号分隔的时间字符串,如‘0:1:15.35’

若是withmask为True,对应帧的遮罩会被写入图片的alpha通道层,仅对PNG图像有效。

注:

图像的alpha通道通常用做不透明度参数。若是一个像素的alpha通道数值为0%,那它就是彻底透明的(也就是看不见的),而数值为100%则意味着一个彻底不透明的像素(传统的数字图像)。在0%和100%之间的值则使得像素能够透过背景显示出来,就像透过玻璃(半透明性),它使数码合成变得容易。alpha通道值能够用百分比、整数或者像RGB参数那样用0到1的实数表示。

3.二、write_videofile方法

write_videofile方法用于将视频剪辑输出到文件,调用语法以下:

write_videofile(self, filename, fps=None, codec=None,
                        bitrate=None, audio=True, audio_fps=44100,
                        preset="medium",
                        audio_nbytes=4, audio_codec=None,
                        audio_bitrate=None, audio_bufsize=2000,
                        temp_audiofile=None,
                        rewrite_audio=True, remove_temp=True,
                        write_logfile=False, verbose=True,
                        threads=None, ffmpeg_params=None,
                        logger='bar')
参数说明以下:
  • filename:视频文件名,只要是ffmpeg支持的视频文件如 .ogv, .mp4, .mpeg, .avi, .mov等均可以
  • fps:帧率,每秒编码的帧数
  • codec:用于图像编码的编解码器,能够是ffmpeg支持的任何编解码器。若是文件名的扩展名为“.mp4”、“.ogv”、“.webm”,则会相应地设置编解码器,但若是不喜欢默认值,则仍能够进行设置。对于其余扩展名,必须相应地设置输出文件名。一些经常使用的编解码器以下:
  • ‘libx264’:视频压缩效果好的一款编解码器,MP4的缺省编解码器,视频质量经过bitrate参数调节
  • ‘mpeg4’:一种可选的MP4编解码器,能够替代’libx264’,能够得到更好的视频质量
  • ‘rawvideo’:完美的视频质量,但文件会巨大,对应视频文件为’.avi’
  • ‘png’:完美的视频质量,对应视频文件为’.avi’,但文件大小比’rawvideo’小
  • ‘libvorbis’:是一种彻底开放、免费的编解码器,有不错的视频格式,可是要不广,对应视频文件为’.ogv’
  • ‘libvpx’:一种很适合在HTML5中使用的网络视频轻量级编开源解码器,对应视频文件为’.webm’
  • bitrate:输出视频的比特率,也即码率BPS(Bits Per Second),指每秒传送的数据位数
  • audio:能够为True、False或文件名,若是True且剪辑附加了音频,则音频将做为视频的音频保存,若是为False则不保存音频,若是为音频文件名则将此音频文件将做为视频的音频
  • audio_fps:声音的采样频率
  • preset:设置FFMPEG用于优化压缩的时间。字符串类型,可选值有:ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、 placebo。请注意,这不会影响视频的质量,只影响视频文件的大小。因此若是赶时间而文件大小不是很重要能够设置为ultrafast
  • audio_nbytes:音频的采用的位数,对应基于字节为单位就是声道数;
  • audio_codec:音频解码器,例如’.mp3’的’libmp3lame’、‘ogg’的’libvorbis’、 ‘m4a’的’libfdk_aac’、 ‘pcm_s16le’ 16位声音和’pcm_s32le’的32位声音。默认值为“libmp3lame”,除非视频扩展名为“ogv”或“webm”,在这2种状况下,默认值为“libvorbis”。
  • audio_bitrate:音频比特率,字符串形式,如“50k”、“500k”、“3000k”,用于将肯定输出文件中音频的大小/质量。请注意,这主要是一个指示性目标,输出文件的比特率不必定会按此设置。
  • audio_bufsize:音频缓冲区大小
  • temp_audiofile:若是输出由音频,则该参数用于指定要生成并合并到电影中的临时音频文件的名称,若是没有指定则用缺省模式的临时文件名
  • rewrite_audio:这个参数目前没有做用,估计是为了兼容之前的版本
  • remove_temp:是否删除临时文件
  • write_logfile:若是为True,将为音频和视频输出记录日志文件。日志文件将以“.log”结尾,包含输出文件的名称
  • verbose:已经废弃使用,留下来是为了兼容性,之前用于打开/关闭消息。如今使用logger=None。
  • threads:用于ffmpeg的线程数,能够加快多核计算机上视频输出的速度
  • ffmpeg_params:需额外传递的其余ffmpeg参数,用列表传递,形如:[’-option1’,‘value1’,’-option2’,‘value2’]
  • logger:字符串类型,"bar"表示进度条、None 表示不设置、或任何程序日志记录器的名字

3.三、write_images_sequence方法

write_images_sequence方法用于将剪辑输出到一系列文件中,调用语法以下:

write_images_sequence(self, nameformat, fps=None, verbose=True,withmask=True, logger='bar')
参数说明以下:
  • nameformat:输出格式和文件名规则,指定了文件系列序号的数字格式和图片类型扩展名的文件名,例如文件名的“frame%03d.png”表示文件名开头为“frame”,后面“%03d”表示文件顺序号以3位数字来顺序编号,文件名后缀“png”表示编码格式为PNG。文件名格式还能够带路径方式,如“目录名\f%04d.jpeg”等。但要求目录名必须已存在,另外若是输出的文件数比设置的序列号范围要多,则会自动往上加1扩展,直到全部内容都输出完成
  • fps:每秒输出帧数,若是没指定则按剪辑的fps进行输出
  • withmask:是否将遮罩做为图像的alpha通道输出,仅对png图像格式有效
  • verbose:是否输出处理信息
  • logger:字符串类型,"bar"表示进度条、None 表示不设置、或任何程序日志记录器的名字

3.四、write_gif方法

write_gif将剪辑转换成gif动画输出到文件中,调用语法:

def write_gif(self, filename, fps=None, program='imageio',
                  opt='nq', fuzz=1, verbose=True,
                  loop=0, dispose=False, colors=None, tempfiles=False,
                  logger='bar'):
参数说明以下:
  • program:用于转换的软件,能够是“imageio”(这将经过imageio使用FreeImage库),或者是“ImageMagick”,或者是“ffmpeg”
  • opt:应用优化的选项,若是program参数是’imageio’,opt必须是’wu’(Wu)或“nq”(Neuquant),。若是program=‘ImageMagick’,opt能够是“optimizeplus”或“OptimizeTransparency”
  • fuzz:仅当program='ImageMagick’时须要,经过考虑小于fuzz%的颜色差别其实是相同的来压缩GIF文件大小
  • loop:表示GIF文件播放时循环播放多少次,若是为0就一直不停地播放,不然播放设定次数后就中止,该参数由GIF文件头控制
  • dispose:表示播放动画时渲染当前帧时,如何处理前一帧,该参数由GIF文件头控制,moviepy没有说明该参数怎么使用,缺省值为False,老猿查阅了相关资料,才基本确认该参数的做用,但GIF中该控制参数有四个取值,不知道是否都支持,取值及含义以下:
  • 为0表示绘制一个完整大小的、不透明的GIF帧来替换上一帧,就算连续的两帧只在局部上有细微的差别,每一帧依然是完整独立的绘制
  • 为1表示未被当前帧覆盖的前一帧像素将继续显示,这种方式经常使用于对GIF动画进行优化,当前帧只需在上一帧的基础上作局部刷新,上一帧中没有被当前帧覆盖的像素区域将继续展现。这种方式既能节省内存,也能提升解码速度
  • 为2 表示绘制当前帧以前,会先把前一帧的绘制区域恢复成背景色,这种方式经常使用于优化不少帧背景相同的状况,上一帧的背景色能经过当前帧的透明区域显示
  • 为3表示绘制当前帧时,会先恢复到最近一个设置为False或1的帧,而后再将当前帧叠加到上面,这种方式性能比较差,已经被慢慢废弃
  • colors:关于这个参数moviepy没有说明,老猿将该值设置为一个比较大的值,结果报错“ValueError: GIF quantize param must be 2…256”,最后查阅资料确认该参数表示色彩量化使用的调色板索引,取值为2到256。GIF最高支持8位256色,那么若是原图是真彩色的,则在生成最终效果图时,就涉及到真彩色到256的降色。真彩色是24位的,有2的24种颜色,每一个像素用3个字节标识一个颜色,R、G、B各占一个字节,而256色每一个像素只用一个字节从调色板中索引一种颜色,调色板最多有256种颜色。将2^24种颜色降为256种颜色,降色的过程被成为色彩量化。色彩量化过程分两步:一、根据图片定制调色板;二、遍历像素,对于每个像素,从调色板中找最接近的颜色,记录该颜色索引。关于调色板请参考《调色板详解
  • tempfiles:将每一个帧写入一个文件,而不是将它们传递到RAM中。在内存不多的计算机上颇有用,只能与ImageMagick或ffmpeg一块儿使用。

3.五、subfx方法

subfx方法用于对剪辑指定时间段进行变换,返回该段剪辑变换后的剪辑和原剪辑其余段拼接后的新剪辑,剪辑的时长会自动调整。语法以下:
subfx(self, fx, ta=0, tb=None, **kwargs)

参数说明:
  • fx:用于对剪辑进行变换处理的函数名,这些函数能够是自定义函数,也能够是moviepy.video.fx包下的模块内定义好的能够直接使用的函数,以及其余可能的函数
  • ta:剪辑段开始位置
  • tb:剪辑段结束位置,若是tb为None,则tb被设置为原剪辑的duration,若是tb为负数,则tb被设置为剪辑的duration + tb
  • kwargs,调用fx函数时须要传入的关键字参数

subfx其实是调用基类Clip的fx方法来实现的,关于Clip的fx方法请参考《moviepy音视频剪辑:moviepy中的剪辑基类Clip的属性和方法详解》。

3.六、fl_image方法

fl_image方法是对get_frame方法获取的帧进行变换的方法,本质上是《moviepy音视频剪辑:moviepy中的剪辑基类Clip详解》介绍的fl方法在内容变换方面的一种变种。

调用语法:fl_image(self, image_func, apply_to=None)
参数说明:
  • image_func:参数image_func是对剪辑帧进行图像变换的函数,带一个参数,参数就是要处理的帧,这个帧直接经过get_frame去获取,image_func函数的返回值为通过变换后的帧
  • apply_to:apply_to表示变换是否须要同时做用于剪辑的音频和遮罩,其值能够为’mask’、‘audio’、[‘mask’,‘audio’]

对比fl方法的调用方法fl(self, fun, apply_to=None, keep_duration=True):

  • fl_image因为只变换内容,所以不涉及时间的变换,keep_duration就是默认为True
  • image_func不带时间参数,这是由于系统默认调用get_frame(t)来获取帧,无需image_func带时间参数
  • fl_image本质上是执行以下语句来完成帧内容的变换:fl(lambda gf, t: image_func(gf(t)), apply_to)
注意:

image_func参数对应的帧数组是只读的,不能修改,实际上get_frame(t)返回的全部帧数组都是只读的。帧的类型为numpy.ndarray,而numpy.ndarray直接定义的数据是可修改的,为何帧数据不能修改笔者暂时还没弄明白(报错ValueError: assignment destination is read-only),为了规避该问题,将参数img数据采用以下形式的赋值语句:frame= np.array(img)就能够对新的变量frame进行修改,全部变换能够针对新变量frame进行,返回也必须是新变量frame。

3.七、fill_array方法

fill_array方法是用来进行多个视频合成时处理帧的,更可能是一个moviepy内部使用的方法,但当应用须要对帧进行变换时也能够调用。fill_array将pre_array的宽和高设置为参数shape对应的数据。

调用语法:fill_array(self, pre_array, shape=(0, 0))
参数说明:
  • pre_array:要处理的数据,结构必须为相似帧的三维数组,其对应的宽和高在pre_array.shape[0::1]内
  • shape:须要将 pre_array变换到的数组维度,shape实际上对应帧的新的宽和高
说明:

fill_array处理数据时,若是发现shape对应的宽或高大于pre_array自己的宽或高,则扩展pre_array的宽或高,扩展的位置使用[1,1,1]填充。若是shape对应的宽或高小于pre_array自己的宽或高,则对pre_array的宽或高超出的数据进行丢弃处理。

3.八、add_mask方法

add_mask方法就是给剪辑增长遮罩,遮罩的duration是调用者的duration,遮罩是由彻底不透明(全1组成的YUV值)的像素构成。调用语法很是简单:add_mask(self)

add_mask方法就是将给定剪辑彻底遮挡,并返回被遮挡后的剪辑。

3.九、on_color方法

on_color方法用于将当前剪辑放置到一个指定颜色背景的可能更大的剪辑上,用于在原始剪辑扩展大小时将空白处设置为指定颜色。返回值为处理后的新剪辑。

调用语法以下:
on_color(self, size=None, color=(0, 0, 0), pos=None,   col_opacity=None)
参数说明:
  • size:是(宽度,高度)的二元组,若是没有设置缺省为调用剪辑的大小
  • color:设定的背景色RGB颜色组
  • pos:原剪辑对应的剪辑在新剪辑的框架上的位置,请见下面函数set_position的说明
  • col_opacity:以背景色构造的底部剪辑的不透明度,取值为0到1的浮点数,若是为0表示彻底透明,为1表示彻底不透明,其余表示不透明度的比率。这个参数对新剪辑中原剪辑对应内容没有做用,仅用于底部背景色构造的剪辑,下图蓝色边框是透明度为0.6时背景色案例

在这里插入图片描述

3.十、set_make_frame方法

set_make_frame方法用于设置剪辑帧构建的make_frame方法,make_frame方法在get_frame中被调用来返回指定位置的帧内容。set_make_frame方法很是简单,调用语法以下:set_make_frame(self, mf),参数mf为剪辑帧的构建方法名,除self外,带一个t参数。

注意:
  • set_make_frame方法在父类Clip中也有,在此重写除了实现父类相同的功能外,同时在设置make_frame方法,立刻会调用get_frame更新剪辑的size属性
  • 修改make_frame改动的不是原剪辑,而是返回一个设置了make_frame方法的原剪辑的拷贝对应的新剪辑,这是moviepy几乎全部设置方法的特色,必定要用返回的新剪辑覆盖到操做的剪辑变量!不过开发团队也准备在后续版本中进行改变,但至少到如今最新的1.03版本这点是没有变化的。

3.十一、set_audio方法

set_audio方法将原剪辑的拷贝剪辑的音频设置为参数指定音频后返回新剪辑。调用语法:set_audio(self, audioclip)

3.十二、set_mask方法

set_mask方法将原剪辑的拷贝剪辑的遮罩设置为参数指定剪辑后返回新剪辑。调用语法:set_mask(self, mask),参数mask是调用对象用于遮罩的剪辑。

3.1三、set_opacity方法

set_opacity方法将原剪辑拷贝剪辑遮罩的每一个元素的值与参数值相乘后返回,实际上就是调整遮罩剪辑帧的YUV值。调用语法:set_opacity(self, op),其中参数op表示透明度或不透明度,为任何浮点数,通常设置为【0,1】区间的一个值。

3.1四、set_position方法

set_position方法用于多个剪辑合成一个剪辑时设置调用剪辑实例的拷贝在合成剪辑的位置。

调用语法:

set_position(self, pos, relative=False)

参数说明:
  • pos:剪辑须要放置的位置,能够是以下方式取值:

  • (x,y):x,y用于指定剪辑左上角在合成剪辑的坐标位置

  • (“center”,“top”):设定水平居中,垂直位置到顶部,相似的设置还有’bottom’、‘right’、‘left’

  • (factorX,factorY):基于剪辑的大小设置相对位置, factorX和factorY为(0,1)之间的浮点数,计算位置时是以factorX乘以剪辑的宽,factorY乘以剪辑的高来计算位置,这里剪辑的宽和高是老猿认为应该是最终生成剪辑的宽和高

  • x和y的=的值能够是前三种的组合,x和y能够用不一样的方式来设置

  • f(t)->(x,y):为一个经过时间计算该时刻指定剪辑左上角在合成剪辑的坐标位置

  • relative:是否相对位置,若是pos使用factorX或factorY时,relative须要设置为True

3.1五、to_ImageClip方法

to_ImageClip方法将剪辑对应时刻t的帧转换成ImageClip图像剪辑,图像剪辑是全部帧都是固定图像数据的剪辑,全部帧都对应为图像数据。

调用语法:

to_ImageClip(self, t=0, with_mask=True, duration=None)

说明:

参数很是简单,不单独解释,但注意图像剪辑在输出到文件时须要设置duration和fps值(为1便可),同时可能在输出文时要指定codec类型,不然可能播放失败。

3.1六、to_mask方法

to_mask方法返回一个由调用者剪辑实例构建的遮罩剪辑。

调用语法:

to_mask(self, canal=0)

说明:

to_mask方法用于将当前剪辑生成一个遮罩剪辑,处理时若是调用对象自己有遮罩,则直接返回调用剪辑的遮罩,不然根据调用剪辑的数据生成遮罩数据,生成时是将调用剪辑的每一帧数据的具体像素的YUV值中的某个除以255来实现遮罩的效果,具体对YUV哪一个数据进行处理由参数canal指定,0代码Y值、1表明U值、2表明V值。

3.1七、to_RGB方法

返回一个由遮罩剪辑生成的非遮罩剪辑。

调用语法:

to_RGB(self)

说明:

该方法的处理过程是,若是调用剪辑不是遮罩,则直接返回自身,不然将剪辑的帧像素YUV各乘以255,再将每一个像素的YUV三元组变成一个九元组,其元素是YUV值重复3遍。

这样变换的缘由老猿并不十分清楚,查阅了一些资料,估计是由于YUV到RGB并非简单YUV到RGB的一个转换,而是到24位真彩色的转换,由于通常来讲直接采集到的视频数据是RGB24的格式,其位数是YUV的三倍,当RGB24变为YUV时实际上是进行了降色处理,如今要恢复到RGB24所以须要进行乘以3。

但这里有些原理没说清楚,好比RGB24是用三个字节来表示颜色,YUV在这里也用了三个字节,RGB为何变成了9个字节?这个问题一时无解,先留着。

另外这个方法在moviepy中只是对遮罩进行处理,当带遮罩的剪辑输出到文件或将剪辑的帧保存到图像或gif文件时会调用该方法对剪辑的遮罩进行处理。

3.1八、without_audio方法

without_audio方法就是将剪辑拷贝后的声音去除,除了self不带其余参数,返回一个去除了声音的新剪辑。

3.1九、afx方法

afx方法对原剪辑浅拷贝后的拷贝剪辑的声音进行变换,返回新剪辑。

调用语法:

afx(self, fun, *a, **k)

说明:
  • 声音变换由函数fun进行
  • a和k是fun变换函数须要带的可变参数和关键字参数
  • afx其实是调用父类Clip的fx方法去执行fun函数的

4、小结

本文详细介绍了视频剪辑基类VideoClip的构造方法、属性和相关处理方法,相关内容参考了moviepy.video.VideoClip.py的文档字符串以及源代码,并针对部分疑难点进行了资料查询和测试,相关内容的探索和写做断断续续持续了一个多星期(_,为了弥补损失,同时为了将相关探索内容更快传播,将一些重要知识点单独成文发布了),做为一个类对象的介绍来讲已经比较全面了。

VideoClip不少方法如save_frame、write_videofile、write_images_sequence、write_gif能够用于输出视频中的对应数据,而subfx、fl_image、add_mask、on_color、set_opacity等是进行视频变换的重要方法。

在文中对部分方法举例进行了运用,但在哪些场景怎么去使用这些方法没有系统介绍,将在后面关于运用场景的文章中进行部分方法使用的介绍。

更多moviepy的介绍请参考《PyQt+moviepy音视频剪辑实战文章目录》或《moviepy音视频开发专栏》。

关于收费专栏

老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只须要19.9元,都适合有必定Python基础但无相关专利知识的小白读者学习。这2个收费专栏都有对应免费专栏,只是收费专栏的文章介绍更具体、内容更深刻、案例更多。

收费专栏文章目录:《moviepy音视频开发专栏文章目录》、《使用PyQt开发图形界面Python应用专栏目录》,本文收费专栏对应文章为《moviepy音视频剪辑:视频剪辑基类VideoClip详解》。

对于缺少Python基础的同仁,能够经过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。

若是有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学5G!

☞ ░ 前往老猿Python博文目录