MoviePy中有几种剪辑修改类别:
- 更改剪辑属性的非常常用的方法:clip.set_duration,clip.set_audio,clip.set_mask,clip.set_start等。
- 已经实现的效果。 诸如clip.subclip(t1,t2)(仅保留t1和t2之间的剪切)之类的核心效果非常重要,它们作为类方法实现。 更高级和较不常见的效果(例如循环(使剪辑循环播放)或time_mirror(使剪辑向后播放))放置在特殊模块moviepy.video.fx和moviepy.audio.fx中,并与剪辑一起应用。 fx方法,例如clip.fx(time_mirror)(使剪辑向后播放),clip.fx(black_white)(使剪辑变为黑色)等。
- 您可以创建自己的效果使用。
所有这些效果的共同之处在于它们不在原处:它们不修改原始剪辑,而是创建一个新的剪辑,该剪辑是应用了更改的前一个剪辑的版本。 例如:
my_clip = VideoFileClip("some_file.mp4")
my_clip.set_start(t=5) # does nothing, changes are lost
my_new_clip = my_clip.set_start(t=5) # good !
此外,当您编写clip.resize(width = 640)时,它不会立即将效果应用于剪辑的所有帧,而仅应用于第一帧:所有其他帧仅在需要时才会调整大小(即, 何时将整个剪辑写入文件的预览时间。 否则,创建新剪辑既不浪费时间也不占用内存,所有计算都在最终渲染期间进行。
MoviePy中的时间表示
我们将看到许多接受时间作为参数的方法。 例如clip.subclip(t_start,t_end)会将剪辑剪切两次。 对于这些方法,时间可以以秒(t_start = 230.54),一对(分钟,秒)(t_start =(3,50.54)),三元组(小时,分钟,秒)(t_start = {0 ,3,50.54))或作为字符串(t_start = '00:03:50.54'))。
在大多数情况下,如果未提供时间,则可以猜测它们,例如在clip.subclip(t_start = 50)中,它暗示t_end对应于剪辑的结尾;在clip.subclip(t_end = 20)中,它暗示 t_start = 0。 如果时间为负,则将其视为剪辑结束之前的时间:clip.subclip(-20,-10)在结束前20s和结束前10s之间剪切剪辑。
更改剪辑属性的方法clip.fx
假设您有一些对片段实现效果的函数,即给定片段和一些参数并返回新片段的函数:
effect_1(clip, args1) -> new clip
effect_2(clip, args2) -> new clip
effect_3(clip, args3) -> new clip
其中args代表参数和/或关键字参数。 要将这些功能按此顺序应用于一个剪辑,您需要编写如下内容:
newclip = effect_3( effect_2( effect_1(clip, args3), args2), args1)
但这不容易阅读。 要使用更清晰的语法,可以使用clip.fx:
newclip = (clip.fx( effect_1, args1)
.fx( effect_2, args2)
.fx( effect_3, args3))
在moviepy.video.fx和moviepy.audio.fx模块中已经实现了许多效果。 如果相关,这些模块中的fx方法将自动应用于剪辑的声音和遮罩,因此您不必担心修改它们。 出于实用性考虑,当您从moviepy.editor import *使用时,这两个模块分别作为vfx和afx加载,因此您可能会编写如下内容:
from moviepy.editor import *
clip = (VideoFileClip("myvideo.avi")
.fx( vfx.resize, width=460) # resize (keep aspect ratio)
.fx( vfx.speedx, 2) # double the speed
.fx( vfx.colorx, 0.5)) # darken the picture
为方便起见,当您使用moviepy.editor时,可以通过更简单的方式调用诸如resize之类的常用方法:clip.resize(...)而不是clip.fx(vfx.resize,...)
创建自定义效果的方法clip.fl
您可以根据需要使用自定义过滤器和clip.fl_time,clip.fl_image以及更一般地说是clip.fl修改剪辑。
您可以使用clip.fl_time更改剪辑的时间轴,如下所示:
modifiedClip1 = my_clip.fl_time(lambda t: 3*t)
modifiedClip2 = my_clip.fl_time(lambda t: 1+sin(t))
现在,片段ModifyClip1播放与my_clip相同,只是快了三倍,而ModifyClip2将通过在时间t = 0s和t = 2s之间来播放my_clip。 请注意,在最后一种情况下,您创建了一个无限持续时间的剪辑(目前这不是问题)。
您还可以使用clip.fl_image修改剪辑的显示。 下面是一个剪辑,并反转了框架的绿色和蓝色通道:
def invert_green_blue(image):
return image[:,:,[0,2,1]]
modifiedClip = my_clip.fl_image( invert_green_blue )
最后,您可能需要同时考虑时间和帧图片来处理剪辑。 使用clip.fl(filter)方法可以做到这一点。 筛选器必须是一个带有两个参数并返回图片的函数。 第一个参数是get_frame方法(即函数g(t),给定时间返回该片段的帧),第二个参数是时间。
def scroll(get_frame, t):
"""
This function returns a 'region' of the current frame.
The position of this region depends on the time.
"""
frame = get_frame(t)
frame_region = frame[int(t):int(t)+360,:]
return frame_region
modifiedClip = my_clip.fl( scroll )
这将使剪辑向下滚动,并保持360像素的恒定高度。
在对新效果进行编程时,请尽可能使用fl_time和fl_image而不是fl来实现新效果。 原因是,当将这些效果应用于ImageClips时,MoviePy将认识到不需要将这些方法应用于每一帧,这将导致更快的渲染。
网友评论