背景
最近在准备面试,为了方便学习和复习,需要把一段长音视频剪成一些小片段。
本文介绍如何用Python实现,把音视频中的某一些片段剪出来。
实践步骤
- 寻找合适的Python库(安装是否麻烦、使用是否简便、执行会不会太久)
moviepy
音视频库。分析需要用的API:代码示例
- 定义输入输出
- 输入:一个音视频文件的地址,需要剪出来的时间段
- 输出:剪辑片段的文件
- 设计执行流程并一步步实现(定义函数,与使用具体API相关)
- 读入并创建clip对象。
- 剪辑subclip,输入时间参数可以是时间格式的字符串。
- 导出write_videofile。
- 结论:时间太久,片段多长就花了多久的时间;CPU全跑满了。
- stackoverflow Concat videos too slow using Python MoviePY 里面有个答案说,调用包里封装的ffmpeg函数会快一些:
You have some functions that perform direct calls to ffmpeg:
https://github.com/Zulko/moviepy/blob/master/moviepy/video/io/ffmpeg_tools.py
And are therefore extremely efficient, for simple tasks such as yours.
- stackoverflow Concat videos too slow using Python MoviePY 里面有个答案说,调用包里封装的ffmpeg函数会快一些:
- 重新设计和实现,直接使用
moviepy.video.io.ffmpeg_tools
里的函数:ffmpeg_extract_subclip(源音视频文件,起,止,输出名)
。- 这个函数中输入的起止时间参数只能是数字,不能是字符串,而库基本使用的接口函数传入的是字符串。看源码发现是有个把时间字符串转换成数字的装饰器的,一步步找就可以找到那个转换的函数了。
- 结论:时间快了很多,几乎是几秒内就完成。
- 但并不明白为什么快了这么多
- 优化:一次处理多个时间段
- 输入由一个起止时间,变为一组起止时间
- 循环处理每一组起止时间
- 输出的文件名按顺序拼接
- 优化:每段时间配上名字
- 输入除了每一组的起止时间,还有后缀名
- 文件名+后缀得到输出的文件名
- 优化:输入输出的合法性校验
- 校验输入地址是合法文件
- 校验时间段(没什么必要)
- 不可以小于0
- 不可以大于视频时间
- 起小于止
完整代码
需要pip install moviepy
1 | import os |
参考
- moviepy的文档
- 博文:用moviepy将视频剪掉一段
- stack overflow Concat videos too slow using Python MoviePY