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

一、引言

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

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

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

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

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

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

三、时间变换的坑

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

3.1、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.2、ValueError: Attribute ‘duration’ not set情况1

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

3.3、ValueError: Attribute ‘duration’ not set情况2

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

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.4、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, 

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

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

关于收费专栏

老猿的付费专栏《使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,付费专栏《moviepy音视频开发专栏》详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,两个专栏加起来只需要19.9元,都适合有一定Python基础但无相关专利知识的小白读者学习。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》从零开始学习Python。

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

跟老猿学Python、学5G!

posted on 2020-06-01 18:35  老猿Python  阅读(446)  评论(0编辑  收藏  举报