Introduction to FFmpeg
简介
一直以来就想介绍一下FFmpeg这个强大的多媒体工具。官方介绍为"A complete, cross-platform solution to record, convert and stream audio and video. "
FFmpeg包含三个部分:ffmpeg, ffplay和ffprobe,分别用于转换、播放和查看信息。当然查看信息用MediaInfo更加方便,文件右键即可。而播放,相信大家都有自己偏好的播放器,不会去用命令行工具播放。说句题外话,我目前用PotPlayer,另外K-Lite、VLC也不错。接下来主要就介绍ffmpeg。
很多播放器都用ffmpeg来软解码(与硬件解码相对),但除此之外,ffmpeg还可以用来转码,简单的剪辑,修改视频分辨率。使用各种库可以支持很多常见的编码操作。ffmpeg是命令行工具,方便批处理,还提供库以供再开发,完全开源。
ffmpeg的版本迭代很快,我一般用稳定版。由于GPL的限制,不包含非开源的内容,所以有一定的欠缺。可以自己编译非自由版本,但是难度很大,可能要花半天。我以前也试过,但现在已经放弃了,转而用自由版本。Windows可以直接获取二进制文件;一般的发行版都提供ffmpeg,可能版本比较旧,但其实影响不大。
多媒体基础
一个视频文件,一般包括视频(Video)、音频(Audio),可能还包含字幕(Subtitle)、章节等文本信息,甚至包含附件。所以这个包装方式称为容器(Container),或一般称为格式,与文件后缀有关。
一个容器中可以包含多个视频、音频、字幕流,而这些流的格式称为编码,相当于不同的压缩算法。编码方式可以分为有损和无损编码,一般视频不会使用无损编码。
格式(容器)
一些简单的、并不专业的介绍。
Matroska
Matroska是较新的流行格式,开源,支持几乎所有编码,几乎什么都可以塞进去。但是比较旧的播放器可能不支持。推荐用MKVToolnix混流,而不是ffmpeg,前者输出文件的兼容性更好。我推荐自己制作或转码的视频用这个容器。
MPEG-4
MPEG-4也比较常见,大多数播放器都支持。可以使用的编码相比Matroska少,但能满足常见的需要。
AVI
AVI(Audio Video Interleave)是一种相当古老的格式,由微软设计,所以在Windows下支持很好。从Windows 3.1开始的Video for Windows就用这种格式。较新的编码也能支持,但是播放器就不一定了。不应该再使用这种格式。
FLV
FLV(Flash Video)是网络视频常见的格式,支持的编码很有限。
WMV
WMV(Windows Media Video)是微软的另一种容器,现在也已经比较少见了。不过Windows 7自带的视频Wildlife.wmv很经典。其使用的编码是专有的,因此无法用ffmpeg实现编码。
视频编码
H.264(AVC)
H.264是目前使用最为广泛的视频编码,也比较先进,在很多设备上有完善的硬件解码,有些还提供快速的硬件编码。适合1080p及以下,而2160p(4K)就会差些。
HEVC(H.265)
HEVC是较新的视频编码,压缩更为先进高效,但是并不普及。较新的硬件可能支持硬件解码,但是编码一般较慢。在4K上会大大超过H.264,较低的分辨率下也很理想。
VP9
Google开发的与HEVC竞争的视频编码,开源且免费,但是硬件支持可能不如前两个。
AV1(VP10)
宣称是HEVC的下一代视频编码,而且开源免费,效率全面超过以前的编码。但不久前发布,支持很少。优势也需要在4K以上。新的ffmpeg已经提供支持,可以去体验。
音频编码
AAC
与AVC一样流行的音频编码,超过前代的MP3。没有特殊要求一般都用AAC编码音频。
MP3
较为古老但仍然常见的音频编码,在视频中用的已经较少,但单独的容器还很常见。建议用AAC取代。
Opus
更先进的开源音频编码,但是很罕见。可以作为研究,但可能实际意义不大。
FLAC
常见的无损音频编码,同样开源,比raw的WAV要节约空间。如果需要无损音频主要考虑FLAC。
WAV
未压缩的音频数据,只是演示及作为中间状态,应该很少实际应用。
使用
最简单的转换只要ffmpeg -i input.mp4 output.avi
,其中-i
表示输入文件,后面表示输出文件。ffmpeg会自动选择合适的方法转换,但很可能不是最佳的。
ffmpeg的工作流程:
在实际使用中,有时可以跳过若干个步骤。
下面介绍一些常用的参数。
显示类
参数 | 解释 |
---|---|
-version | 显示版本 |
-formats | 显示支持的格式(容器) |
-decoders | 显示支持的解码器 |
-encoders | 显示支持的编码器 |
-filters | 显示支持的过滤器 |
-h encoder=xxx | 显示xxx编码器有关的信息,其他类型也可以 |
流复制
这是最简单的一种处理,也就是只改一下容器。此时,不用解码或编码,只要复制流即可。
示例:下载了input.flv
,但是播放器不支持,需要转换成MP4容器。
命令:ffmpeg -i input.flv -c copy output.mp4
解释:-c
指定输出编码,copy
表示直接复制输入编码即可。
简单重编码
需要重新编码?也很简单。
示例:一个巨大的input.mp4
,只包含一个视频流和一个音频流。要求压缩这个文件,视频用HEVC编码,音频直接复制(一般相比视频,音频占的空间不大)。
命令:ffmpeg -i input.mp4 -c:v libx265 -crf 20 -c:a copy output.mkv
解释:-c:v|a
可以指定针对视频/音频编码,如果有多个视频/音频流,ffmpeg会自动选择质量最高的那个输出。-crf
指HEVC用固定质量编码,质量为20。
H.264/HEVC都用CRF来指定固定质量,CRF越小质量越高,但也越大。H.264默认为-crf 23
,HEVC默认为-crf 28
,注意两者没有直接可比性,要根据实际需要确定CRF。使用CRF模式无法确定输出文件大小,因此适用于空间限制不高的情况。
关于适当CRF的选择,可以参考视频编码质量测试。