moviepy音视频剪辑:使用fl_time进行诸如快播、慢播、倒序播放等时间特效处理的原理和可能遇到的坑

1、引言

在《moviepy音视频剪辑:moviepy中的剪辑基类Clip的属性和方法详解》介绍了fl_time方法返回一个新剪辑,新剪辑是调用剪辑的一个浅拷贝,但新剪辑的时间线被调整,实际上这个方法就是对剪辑进行一个基于时间特效的处理,如快播、慢播、倒序播放等。html

2、时间特效处理的基本原理

时间特效处理其实很是简单,就是对时间的一个变换,变换时,假设t1是剪辑的时间线,从0开始一直到剪辑的最后end地方的一个线性坐标,而时间特效是经过调用函数或方法获得t2,t2 = t_fun(t1),而后特效处理后的剪辑时间线t1对应的帧被替换为原剪辑t2位置的帧。python

n倍速变换,实际上是新剪辑t1时刻的帧对应原剪辑n*t1时刻的帧,慢速播放则是新剪辑t1时刻的帧对应原剪辑t1/n时刻的帧,倒序播放则是将新剪辑t1时刻的帧对应原剪辑end-t1时刻的帧。web

在moviepy中,时间特效处理是经过方法fl_time来进行变换处理的,变换的函数则经过fl_time的参数t_func来传递。关于fl_time的详细介绍请参考《moviepy音视频剪辑:moviepy中的剪辑基类Clip的属性和方法详解》。app

t_func参数指定的函数要求一个入口参数t,返回一个通过函数处理后的新的时间值。ide

3、时间变换的坑

时间变换讲清楚之后,看起来很简单,但具体实现时会存在稍不留神就会被坑,咱们来看几个笔者遭遇的坑。svg

3.一、OSError: MoviePy error: failed to read the first frame of video file

在进行变换处理时报以下错误信息:函数

OSError: MoviePy error: failed to read the first frame of video file F:\video\WinBasedWorkHard_src.mp4. That might mean that the file is corrupted. That may also mean that you are using a deprecated version of FFMPEG. On Ubuntu/Debian for instance the version in the repos is deprecated. Please update to a recent version from the website.

之因此出现这个报错,估计是由于使用fl_time对时间变换时,从原剪辑的0-end时间段读取帧时,原剪辑end这个时间位置已经到视频结尾,可能没有有效的帧,致使读取视频时报错。解决方案就是将end位置稍微日后退一点,退一个帧就够了。学习

3.二、ValueError: Attribute ‘duration’ not set状况1

这是由于调用fl_time时,keep_duration默认值为False,只要该值为False,moviepy就会将duration设置为None,解决办法是设置keep_duration = True 或者手工设置剪辑的duration。ui

3.三、ValueError: Attribute ‘duration’ not set状况2

下面的案例是倍速播放,因为是倍速播放,视频的时长时间上只有原视频的一半,此时使用keep_duration=True已经不合适,只能自行设定duration的值。示例代码以下:spa

from  moviepy.editor import *
clipVideo = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4")
newclip = clipVideo.fl_time(lambda t:  2*t , apply_to=['mask'])
newclip.set_duration(clipVideo.duration/2)
newclip.write_videofile(r"F:\video\WinBasedWorkHard_new.mp4")

执行时仍是报错,这是由于剪辑的绝大多数set方法,基本上都不是对调用者的直接修改,而是对调用者进行浅拷贝后,对浅拷贝剪辑进行修改,且这些方法返回值都是一个剪辑。只须要将调用返回的剪辑记录下来做为后续处理才行。

3.四、OSError: Error in file xxxx, Accessing time

上面的案例没有调整音频只调整了视频,会致使视频播完以后,音频还只播放一半,要保持音频完整播放,有3个办法,一是不一样步改变音频,但视频duration保持不变,这时出来的效果就是视频播放到一半后,后续画面再也不变化,第二种是将音频同步变换duration减半,只是音频播放速度也翻倍了;第三种是保持duration不变但一样变换音频。前面两种方式处理都没有问题,但第三种方式会遇到问题。此时执行时会报以下错误:

OSError: Error in file F:\video\WinBasedWorkHard_src.mp4, Accessing time t=54.84-54.93 seconds, with clip duration=54 seconds,

这个报错信息应该是访问的音频超出了剪辑的时长致使,但若是不变换音频不会报错,且自动置为最后一个视频帧,而音频没有这样处理,且不停重复最后的音频感知很差。这种问题最好的解决是按前两种方式处理。

广告

老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只须要9.9元,本专栏《PyQt+moviepy音视频剪辑实战》文档的一样内容在付费专栏上也有相应内容,整体来讲付费专栏介绍更详细或案例更多。本节内容对应付费专栏的《moviepy音视频剪辑:使用fl_time进行诸如快播、慢播、倒序播放等时间特效处理的原理、代码实现以及须要注意的坑》。若是有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学5G!