在上章我们学习了ffmpeg命令行帮助以及选项查找
本章我们来深入学习ffmpeg命令转码规则、过滤器介绍、手动流map选项
参考链接: ffmpeg Documentation
1.ffmpeg命令行转码流程
ffmpeg命令行转码流程如下图所示:
对应中文则是:
步骤如下所示:
- ffmpeg调用libavformat库(包含解复用器)来读取输入文件并从中获取编码数据包。
- 编码数据包随后被传递到解码器, 然后获取到解码后的未压缩的帧(原始视频/PCM音频/...)
- 通过filter进行原始音频和视频处理(见下一节)
- 过滤后的每一帧被传送到编码器,编码器对其进行编码并输出编码后的数据包。
- 最后被传递给多路复用器(多个输入文件产生一个输出文件),多路复用器将编码后的信息包写入到输出文件。
示例如下所示:
ffmpeg -i 1920x1080.mp4 -acodec copy -vcodec libx264 -s 1280x720 1280x720.flv
// -acodec copy : 音频编解码采用流复制模式,速度非常快,不需要解码和编码,没有质量损失,唯一缺点就是在过滤器不能使用,因为过滤器必须需要进行解码和编码
// -vcodec libx264 : 视频编码采用libx264
// -s : scale调整视频输出大小
流复制copy参数-介绍如下所示:
2.filter简单过滤
filter过滤分为简单过滤和复杂过滤
简单过滤器和复杂过滤器可以通过-filters参数查看, 也可以通过官网查找:
然后通过-filter filter_graph来设置过滤器, 如果要分开设置视频和音频的过滤器,则通过-vf和-af实现:
-vf filter_graph // 设置video filter
-af filter_graph // 设置audio filter
一个简单的过滤器如下所示:
其中scale则是调整输出视频的范围
其中deinterlace表示隔行滤镜(也就是去除拉丝效应,去锯齿),比如有拉丝的如下图所示:
FFmpeg支持deinterlace的视频过滤器有:
- bwdif("Bob Weaver Deinterlacing Filter")
- estdif("Edge Slope Tracing Deinterlacing Filter")
- yadif("yet another deinterlacing filter")
- w3fdif("Weston 3 Field Deinterlacing Filter")
现在给大家做个初步了解,后面会专门出滤波器相关文章后,再来添加文章链接
示例如下所示:
ffmpeg -i input.mov -vf yadif -s 200x120 out.mov
//采用yadif,参数使用默认参数:
//mode=send_frame : 对于每帧以帧扫描的方式输出
// parity =-1 : 自动检测场奇偶校验
// deint = all : 对所有帧进行反交错
3.filter复杂过滤
如下图所示:
比如将多个输入视频文件进行过滤,产生一个视频文件(比如在主视频上面叠加添加一个广告视频)
复杂过滤通过-filter_complex选项实现,该选项是全局,可以通过该选项来设置每个文件参数
注意: -lavfi和-filter_complex作用一样,是-filter_complex的别名,如下图所示:
复杂过滤器示例
复杂滤波器图的一个简单例子是overlay滤波器,它的音频对应部分是amix过滤器。
overlay滤波器(覆盖滤波器)介绍如下所示:
他需要两个输入视频、 会将一个视频叠加在另一个视频上产生一个输出视频
其中第一个输入视频是第二个输入视频覆盖的“主”视频。参考: https://www.cnblogs.com/leisure_chn/p/10434209.html
假设有以下三个输入文件:
input file 'A.avi'
stream 0: video 640x360
stream 1: audio 2 channels
input file 'B.mp4'
stream 0: video 1920x1080
stream 1: audio 2 channels
stream 2: subtitles (text) // 文本字幕流
stream 3: audio 5.1 channels
stream 4: subtitles (text)
input file 'C.mkv'
stream 0: video 1280x720
stream 1: audio 2 channels
stream 2: subtitles (image) // 图像字幕流
示例如下所示:
ffmpeg -i A.avi -i C.mkv -i B.mp4 -filter_complex "overlay" out1.mp4 out2.srt
out1.map4
这里使用了overlay覆盖过滤器,由于没有指定视频流,所以默认会将第二个视频(C.mkv)覆盖在第一个视频(A.avi)上, 由于C.mkv尺寸比A.avi大,所以会显示C.mkv左上角部分.由于没有指定输出流,所以默认生成给第一个输出视频out1.mp4, 由于没有指定音频流,所以会使用A.avi和C.mkv其中最多的音频通道数,也就是默认选择B.mp4的steam3音频流. 由于mp4默认没有字幕流,而且用户没有指定字幕,所以没有字幕
out2.srt
由于out2.srt文件是一个文本形式的字幕流文件,所以只会会默认选择文本形式的第一个字幕流,也就是B.mp4的steam2,即便C.mkv排在最前面也不行,因为C.mkv的字幕是图像类型的
4.自动流
设置输出文件没有选项的情况下,ffmpeg会自动选择视频、音频或字幕,它将根据以下标准进行选择:
- 对于视频,如果没有选择比如overlay这种滤波器,那么默认选择最高分辨率的流
- 对于音频,默认选择最多通道的音频流
- 对于字幕,默认找到第一个字幕流,但会出现警告。
5.手动流选择
通过-map选项实现,-map使用方式如下所示:
- -map 0:0 第一个输入文件的第一个流
- -map 1:3 第二个输入文件的第四个流
- -map 1:a 第二个输入文件的所有音频流( v视频, a音频, s字幕, m元数据)
- -map 0:v:0 第一个输入文件的第一个视频流( v视频, a音频, s字幕, m元数据)
- -map 1:a:2 第二个输入文件的第三个音频流( v视频, a音频, s字幕, m元数据)
- -map 1:s:1 第二个输入文件的第二个字幕流( v视频, a音频, s字幕, m元数据)
假设有以下三个输入文件:
input file 'A.avi'
stream 0: video 640x360
stream 1: audio 2 channels
input file 'B.mp4'
stream 0: video 1920x1080
stream 1: audio 2 channels
stream 2: subtitles (text) // 文本字幕流
stream 3: audio 5.1 channels
stream 4: subtitles (text)
input file 'C.mkv'
stream 0: video 1280x720
stream 1: audio 2 channels
stream 2: subtitles (image) // 图像字幕流
示例如下所示:
ffmpeg -i A.avi -i B.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov
输出文件有三个: out1.mkv、out2.wav、 out3.mov
out1.mkv:
是一个Matroska容器文件,接受视频、音频和字幕流,所以ffmpeg将尝试选择每种类型。
对于视频,它将选择所有输入视频流中具有最高的分辨率, 也就是B.mp4的stream0
对于音频,它将选择最多的通道数,也就是B.mp4的stream3
对于字幕,它将默认选择所有文件的第一个字幕,也就是B.mp4的stream2
out2.wav:
是一个无损压缩的音频文件,因此选择最多的音频通道数,也就是B.mp4的stream3
out3.mov:
由于有-map选项,所以所有流不能进行自动选择,这里指定了-map 1:a,所以会选择第2个输入文件的所有音频(播放的时候支持2通道,也可以支持5.1通道).由于没有指定视频流,所以不会包含其他流
由于指定了-c:a copy,所以out3.mov的音频流编解码器进行流复制.等价于-acodec copy
"-c:a copy"介绍
在官网"5.4 主要选项"有介绍,如下图所示:
这里-c等价于-codec编解码器,冒号后面是流选择,比如-c:a表示音频编解码器,等价于-acodec
-c:v表示视频编解码器,等价于-vcodec
本章我们主要学习ffmpeg命令如何转码,规则介绍, 后面我们再来详细讲解ffmpeg各种选项和各种过滤器使用(裁剪、画中画、文字水印等)