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 类。

  1. 社区开发者,直接写 FFmpeg 代码的,截止2022年,一共有100多个 Maintainer(主要开发者)。
  2. FFmpeg API 库使用者,FFmpeg 提供了很多的动态库给上层开发者调用。这类开发者主要是调 API,偶尔会提交一下代码反馈给 社区。
  3. FFmpeg 命令行使用者,这类用户通常不会写 C/C++,但是具备一点的电脑操作知识,主要在电影,电视台这些行业。这类用户只会使用 FFmpeg 的命令行,比较厉害的会写 shell脚本 跟 batch批处理 来 使用 FFmpeg。

FFmpeg安装

Windows10

​ 在 windows 环境,FFmpeg 有两个网址可以下载安装包。

  1. gyn FFmpeg build
  2. BtbN FFmpeg-Builds

​ FFmpeg 里面有 3 个软件:

  1. ffmpeg.exe ,功能强大的 处理音视频文件的软件。
  2. ffplay.exe,播放器,可以播放音视频文件。
  3. 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 个部分。如下图:

  1. 可执行文件 ,就是 ffmpeg 那个软件。
  2. 输入文件参数,在 -i 前面那些参数,全部都作用于当前的输入文件。
  3. 输入文件名, -i 指定输入文件。
  4. 输出文件参数,输出文件名 前面的那些参数 就是输出文件参数,全部都作用于当前的输出文件。
  5. 输出文件名,juren.ts 就是输出文件名,输出文件名前面的一个参数不是 -i,也不是以 - 开始的参数。
  6. 全局参数, -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 采样格式。编码相关的信息。