FFMPEG基础
FFmpeg介绍
FFmpeg 是一个可以处理音视频的软件,功能非常强大,主要包括,编解码转换,封装格式转换,滤镜特效。同时也支持 各种网络协议,支持 RTMP ,RTSP,HLS 等高层协议的推拉流,也支持更底层一点的TCP/UDP 协议推拉流。
在多平台系统方面,FFmpeg 的兼容性也优势显著,FFmpeg 可以在 windows,Linux,Mac,ios,android 等等操作系统上运行。
因此,可以说 FFmpeg 是音视频领域的瑞士军刀。在多个公司都有使用,例如 Google 的 chrome 里面就使用了 FFmpeg 的库。还有 Youtube,Facebook,以及国内的各种做音视频产品的公司,只要他做音视频,95% 都会用到 FFmpeg。
但是截止 2022 年,FFmpeg 还是只有 命令行,没有GUI 图像界面,所以对使用者有一定的门槛。
FFmpeg 是一个开源项目,起始于2000年,截止 2022 年,已经走过 22 年,在这过程中,FFmpeg 社区经历过一次分裂。2011年的时候,一群 FFmpeg 开发者由于对项目管理者(不是Fabrice Bellard)不满,而另立山头,创建了 Libav 项目。我个人觉得,他们可能是对 当时 的FFmpeg 代码混乱不满。Libav 的代码架构更清晰一些。不过那是很多年前的事情了。目前 FFmpeg 的代码架构还是很不错的。
Libav 项目经历了几年的发展,还是没有发展下去,最后 Libav 的成果代码,被合并到 FFmpeg 里面,git 提交记录保留了 Libav 开发者的名字。
FFmpeg 的 用户主要有 3 类。
- 社区开发者,直接写 FFmpeg 代码的,截止2022年,一共有100多个 Maintainer(主要开发者)。
- FFmpeg API 库使用者,FFmpeg 提供了很多的动态库给上层开发者调用。这类开发者主要是调 API,偶尔会提交一下代码反馈给 社区。
- FFmpeg 命令行使用者,这类用户通常不会写 C/C++,但是具备一点的电脑操作知识,主要在电影,电视台这些行业。这类用户只会使用 FFmpeg 的命令行,比较厉害的会写 shell脚本 跟 batch批处理 来 使用 FFmpeg。
FFmpeg安装
Windows10
在 windows 环境,FFmpeg 有两个网址可以下载安装包。
FFmpeg 里面有 3 个软件:
- ffmpeg.exe ,功能强大的 处理音视频文件的软件。
- ffplay.exe,播放器,可以播放音视频文件。
- ffprobe.exe,查看音视频文件的属性,在调试排查问题的时候非常有用。
FFmpeg封装格式转换
FLV 转 MP4:
ffmpeg -i juren.flv juren.mp4 |
FLV 转 TS:
ffmpeg -i juren.flv juren.ts |
MP4 转 FLV:
ffmpeg -i juren.mp4 juren.flv |
上面的命令是 封装格式之间的转换,但是实际上会进行编解码转换,例如 MP4 转 FLV,他会先解码 MP4 的数据,然后 选择 FLV的默认的编码格式进行重新编码,FLV 封装格式的默认编码是 H.264,juren.mp4 的编码格式也是 H.264,所以实际上编码格式没变,但是还是经过了编解码运算,所以上面那条转封装命令会运行很慢。ffmpeg.exe 运行的时候,会有一个日志输出,上图中的 speed 就是处理速度,现在速度是 5 倍,那就是5分钟的视频,处理完成需要1分钟的时间。
为了加快运行速度,我们可以加上 -c copy
参数,让 ffmpeg 不进行编解码运算,如下:
MP4 转 FLV (不进行编解码):
ffmpeg -i juren.mp4 -c copy juren.flv |
上面的命令,大家可以自行运行一下,在我的电脑里面 1秒钟都不用,所以 编解码的运算量是很大的,不进行 编解码之后,速度提高了60 倍以上。
上面的命令,ffmpeg 都是根据 文件的后缀名猜测出封装格式, 素材里面有个 juren-mp4,这个文件是没有后缀名,如果没有 后缀名,ffmpeg 就会 读取一部分的文件内容来判断文件格式。所以 ffmpeg 非常的智能,因为ffmpeg 也是给非开发人员使用的。
对于一些新型的封装格式,ffmpeg 猜测不对,可以指定 封装格式,如下:
ffmpeg -f flv -i juren.flv -c copy juren.mp4 |
FFmpeg命令参数类型
在继续讲其他的 ffmpeg 命令行用法之前,需要先讲 一下 ffmpeg 处理命令行参数的一些逻辑。ffmpeg 命令行 其实分为 6 个部分。如下图:
- 可执行文件 ,就是 ffmpeg 那个软件。
- 输入文件参数,在 -i 前面那些参数,全部都作用于当前的输入文件。
- 输入文件名, -i 指定输入文件。
- 输出文件参数,输出文件名 前面的那些参数 就是输出文件参数,全部都作用于当前的输出文件。
- 输出文件名,juren.ts 就是输出文件名,输出文件名前面的一个参数不是
-i
,也不是以-
开始的参数。 - 全局参数, -y 跟 -benchmark 这些跟输入输出文件无关的参数就是全局参数。
上面我为什么强调 当前 ,是因为 ffmpeg 是支持多个输入文件跟多个输出文件的,多个文件可以有各自的独立参数。多输入文件在复杂滤镜的场景经常使用。虽然ffmpeg有很多很多的命令参数,但是只要你记住 ffmpeg 的参数类型,就会很容易学会 其他 参数的使用。另外一点,ffmpeg 的命令行参数是没有先后顺序的,我上图是比较正确的写法,先是输入,再是输出,最后是全局参数。
FFmpeg编码格式转换
我们可以通过 命令 ffmpeg -codecs
查看 FFmpeg 支持的编解码标准。
上面的 D 代表 decodec (解码),E 代表 encodec(编码)。有些标准在 ffmpeg 里面只实现了 解码,没有实现 编码。
现在演示一下 H.264 转 H.265 的 命令行语法,由于 FLV 目前官方不支持 H265,只能通过扩展字段自己加H265,没有标准。所以本文用 MP4 格式来演示,MP4 对 H.265 的支持是有标准定义的。
ffmpeg -i juren.mp4 -c:v hevc -c:a copy juren-h265.mp4 |
上面的 -c
是指定编码格式 ,v 跟 a 分别代表 视频 跟 音频,视频以 hevc 编码,音频不变直接 copy 到输出文件即可。H.265 就是 hevc。
FFplay基本使用
fplay.exe 是一个播放器,可以执行以下命令播放一个 视频。
ffplay -x 400 -i juren.mp4 |
上面的命令中 我指定了 窗口宽度 是 400像素,高度会等比例拉伸。
FFprobe基本使用
ffprobe.exe 是一个分析工具,可以执行以下命令分析一个 音视频文件 的详细信息。
ffprobe -hide_banner -i juren.mp4 |
从上图中可以看出来,juren.mp4 文件有 两个流,一个是 音频流,一个是视频流。还有视频宽度,yuv 采样格式。编码相关的信息。