在 python 中进行视频 - 音频处理及合并

一、ffmpeg 组件

ffmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用 LGPL 或 GPL 许可证。它提供了录制、转换以及流化音视频的完整解决方案。

本次介绍 ffmpeg 的目的是:合并视频,合并音频,合并视频和音频。

它可以直接在命令行下直接调用;也可以通过 python 程序调用。

1.1 下载及配置环境变量

下载地址:https://ffmpeg.zeranoe.com/builds/

下载完直接解压即可,将文件放到合适位置。

然后在 path 中配置环境变量。

配置完需要重启电脑才能生效。

如在 CMD 下输入以下命令,若有反应,则说明环境变量配置成功。

C:\Users\Aloha>ffmpeg -version

1.2 在 python 中使用

1.2.1 视频音频合并

import subprocess  // 这个不用 pip 安装,自带的

def video_add_audio(video_file, audio_file):
    """
     视频添加音频
    :param file_name: 传入视频文件的路径
    :param mp3_file: 传入音频文件的路径
    :return:
    """
    outfile_name = file_name + '-txt.mp4'
    subprocess.call('ffmpeg -i ' + video_file
                    + ' -i ' + audio_file + ' -strict -2 -f mp4 '
                    + outfile_name, shell=True)

1.2.2 视频合并

方法一:FFmpeg concat 协议

对于 MPEG 格式的视频,可以直接连接:

ffmpeg -i "concat:input1.mpg|input2.mpg|input3.mpg" -c copy output.mpg

对于非 MPEG 格式容器,但是是 MPEG 编码器(H.264、DivX、XviD、MPEG4、MPEG2、AAC、MP2、MP3 等),可以包装进 TS 格式的容器再合并。在新浪视频,有很多视频使用 H.264 编码器,可以采用这个方法

ffmpeg -i input1.flv -c copy -bsf:v h264_mp4toannexb -f mpegts input1.ts
ffmpeg -i input2.flv -c copy -bsf:v h264_mp4toannexb -f mpegts input2.ts
ffmpeg -i input3.flv -c copy -bsf:v h264_mp4toannexb -f mpegts input3.ts
ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy -bsf:a aac_adtstoasc -movflags +faststart output.mp4

保存 QuickTime/MP4 格式容器的时候,建议加上 -movflags +faststart。这样分享文件给别人的时候可以边下边看。

方法二:FFmpeg concat 分离器

这种方法成功率很高,也是最好的,但是需要 FFmpeg 1.1 以上版本。先创建一个文本文件filelist.txt

file 'input1.mkv'
file 'input2.mkv'
file 'input3.mkv'

然后:

ffmpeg -f concat -i filelist.txt -c copy output.mkv

注意:使用 FFmpeg concat 分离器时,如果文件名有奇怪的字符,要在 filelist.txt 中转义。

1.3 用法总结

1.3.1 ffmpeg 命令

命令格式:

ffmpeg -i [输入文件名] [参数选项] -f [格式] [输出文件]
ffmpeg [[options][`-i' input_file]]... {[options] output_file}...
  • 参数选项:
    (1) -an: 去掉音频
    (2) -acodec: 音频选项, 一般后面加 copy 表示拷贝
    (3) -vcodec: 视频选项,一般后面加 copy 表示拷贝
  • 格式:
    (1) h264: 表示输出的是 h264 的视频裸流
    (2) mp4: 表示输出的是 mp4 的视频
    (3) mpegts: 表示 ts 视频流
  • 注意:如果没有输入文件,那么视音频捕捉(只在 Linux 下有效,因为 Linux 下把音视频设备当作文件句柄来处理)就会起作用。作为通用的规则,选项一般用于下一个特定的文件。如果你给 –b 64 选项,改选会设置下一个视频速率。对于原始输入文件,格式选项可能是需要的。缺省情况下,ffmpeg 试图尽可能的无损转换,采用与输入同样的音频视频参数来输出。

视频格式转换示例:

//H264 视频转 ts 视频流
ffmpeg -i test.h264 -vcodec copy -f mpegts test.ts

//ts 视频转 mp4
ffmpeg -i test.ts -acodec copy -vcodec copy -f mp4 test.mp4

//mp4 视频转 flv
ffmpeg -i test.mp4 -acodec copy -vcodec copy -f flv test.flv 

将视频转为音频:

def video2mp3(file_name):
    """
    将视频转为音频
    :param file_name: 传入视频文件的路径
    :return:
    """
    outfile_name = file_name.split('.')[0] + '.mp3'
    subprocess.call('ffmpeg -i ' + file_name
                    + ' -f mp3 ' + outfile_name, shell=True)
  • 分离视频:ffmpeg -i 1.mp4 1.avi
  • 分离音频:ffmpeg -i 1.mp4 1.mp3

二、流媒体 ts 与 m3u8

现在大部分视频网站为了反扒,会将视频切割成很多小段,形成后缀为.ts 的视频文件。用户在网站上播放视频时,会一步步从服务器加载.ts 视频进行播放。

Ts 文件视频编码主要格式 h264/mpeg4,音频位 aac/mp3

与此同时,还会存在一个.m3u8 文件,它是记录了一个索引纯文本文件,视频播放时,会根据 m3u8 的索引找到对应的音视频文件的网络地址进行在线播放。

原视频数据分割为很多个 TS 流,每个 TS 流的地址记录在 m3u8 文件列表中。

以下是 m3u8 文件的通常格式:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:13
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-KEY:METHOD=AES-128,URI=".20180125/key.key"  <-- 有这一行说明 ts 被加密了。
#EXTINF:12.5,
http://www.example.com/20180125/GBDYO3576000.ts   #<-- 这就是 ts 流视频的真实 url
#EXTINF:12.5,
http://www.example.com/20180125/GBDYO3576001.ts
#EXTINF:12.5,
http://www.example.com/20180125/GBDYO3576002.ts
……………………
#EXT-X-ENDLIST

2.1 无加密

在.m3u8 文件中,若无 #EXT-X-KEY……一行字样,说明没有加密。

2.1.1 m3u8 下载合并

有了 m3u8 文件,可以直接使用 ffmpeg 进行下载,合并。

注意这里的 m3u8 文件地址可以是网络 url,也可以是本地 ts 文件路径。

ffmpeg -i file.m3u8 -c copy new.mp4

若报错: Protocol ‘http’ not on whitelist ‘file,crypto,data’!

则执行下面这个:

ffmpeg -allowed_extensions ALL -protocol_whitelist "file,http,crypto,tcp" -i index.m3u8 -c copy out.mp4

2.1.2 ts 合并

当我们已经直接把 .ts 文件下载到本地了,可以按照以下方法合并。

CMD 下执行一下命令:

copy/b D:\temp\*.ts D:\temp\output.ts

D:\temp\*.ts 意思是 D:\temp 目录下所有的 .ts 文件。

2.2 有加密

在.m3u8 文件中,若存在 #EXT-X-KEY……一行字样,说明.ts 有加密。

#EXT-X-KEY:METHOD=AES-128,URI="key 的地址 "   

只要这一行有说明 key 的地址(不论本地,还是网络 url),就可以直接执行:

ffmpeg -i file.m3u8 -c copy new.mp4

欢迎各位看官及技术大佬前来交流指导呀,可以邮件至 jqiange@yeah.net