使用Python+FFMPEG实现视频分割与合并

前言

日常中偶尔会遇到需要简单剪辑处理视频的场景,以前我可能会拿出PR来剪辑一下,(别跟我说国产那些软件,剪辑完视频强制加上广告片头片尾恶心的一批),但是PR毕竟太重量级,剪个简单的视频都要花不少时间,直到我发现了FFmpeg……

这个FFmpeg真的是神器,免费开源功能强大,好像很多软件都是基于这个开发的,它本身提供了命令行接口就已经能满足我们日常的简单视频处理需求,我用来简单处理视频分割、合并,真的很香。

不过命令行用来处理一两个还行,如果是要处理多个视频,或者是服务端有视频处理的需求(如转码、加水印这类),就需要有一种方便的方法在代码里运用FFmpeg,于是本文打算介绍python和FFmpeg间的无缝接入调用~

ffmpy

首先FFmpeg是一个可执行文件,要在Python中调用FFmpeg并且监控它的状态,需要使用类似os.system()或者是subprocess模块来创建子进程,需要自己处理很多工作,比较麻烦……

ffmpy库就是帮我们解决这个问题的,完美整合FFmpeg,把子进程管理封装好了,我们直接输入好参数调用就完事了

代码

本文只是简单介绍python中调用ffmpeg的方法,FFmpeg的功能很强大,限于篇幅本文不能一一介绍FFmpeg的功能,想深入了解FFmpeg的同学可以查看最后的参考资料~

视频分割

例子是最简单的从一个视频中分割出一个片段的用法,并且使用了-vcodec copy -acodec copy参数,表示音频和视频都不转码提高处理视频的速度。

操作看下面的代码就知道了,输入输出,安排得明明白白,输入和输出都是字典类型,文件名是key,参数是value。

import ffmpy

ff = ffmpy.FFmpeg(
    inputs={'input.mp4': None},
    outputs={'output.mp4': [
        '-ss', '00:01:20',
        '-t', '02:00:00',
        '-vcodec', 'copy',
        '-acodec', 'copy'
    ]}
)

ff.run()

在执行ff.run()之前,可以先用print(ff.cmd)把命令打印出来看看。

上述的视频分割操作,对应的FFmpeg命令是:

ffmpeg -i input.mp4 -ss 00:01:20 -t 02:00:00 -vcodec copy -acodec copy output.mp4

视频合并

视频合并就比较麻烦了,如果直接用FFmpeg命令输入多个视频文件,输出一个的话,需要转码过程,这样速度就很慢了,失去了合并的意义。

我找了资料,只有使用文件列表的方式来合并视频是可以直接合并不转码的,不过这要求先创建一个文件用来保存视频列表,在Python中,我们可以通过创建临时文件来实现。

代码如下:

import os
import tempfile
import ffmpy

# 创建临时文件
temp_dir = tempfile.mktemp()
os.mkdir(temp_dir)
concat_file = os.path.join(temp_dir, 'concat_list.txt')

with open(concat_file, 'w', encoding='utf-8') as f:
    f.write('\n'.join([
        'file C:/1.mp4',
        'file C:/2.mp4',
        'file C:/3.mp4',
    ]))

ff = ffmpy.FFmpeg(
    global_options=['-f', 'concat'],
    inputs={concat_file: None},
    outputs={'output.mp4': ['-c', 'copy']}
)

ff.run()

搞定!

参考资料

发布于 2021-03-26 22:30