1.FFmpeg介绍
FFmpeg
的全称是"Fast Forward Moving Picture Expert Group
",组件由命令行应用程序和函数库两部分组成。通俗概括来说,FFmpeg 是一个免费的开源程序库,一个多媒体音视频处理分析工具软件,且提供命令行方式调用,专门用来编辑处理各种音视频或图像。它的源码是由 C 语言编写的,基于 Linux 系统中开发,不过在其它操作系统中都可以运行,跨平台性良好。
A complete, cross-platform solution to record, convert and stream audio and video !
-
ffmpeg
:功能强大的处理音视频文件的软件,可以实现音视频的录制、转码、剪辑、合成等功能。 -
ffplay
:FFmpeg自带的播放器工具,基于 SDL 与 ffmpeg 库实现,提供了音视频显示和播放相关的图像信息和音频波形信息等,可以播放本地文件或者网络流媒体。 -
ffprobe
:FFmpeg自带的多媒体信息检测工具,可以获取多媒体文件的音频视频容器参数的详细信息,如分辨率、编码格式、时长等。
2. FFmpeg 转码与转封装
FFmpeg
通过以下步骤实现输出转码转封装:
-
解封装(
Demuxing
):在解封装阶段,FFmpeg 会读取输入文件的容器格式(例如 MP4、AVI、FLV 等),解析其中的音视频流数据和元数据信息。它会提取出音频流和视频流,并将它们拆分成独立的音频和视频数据。 -
解码(
Decoding
):解码阶段是将音频和视频数据从原始的压缩格式(如 H.264、AAC 等)解码为未压缩的原始数据。FFmpeg使用适当的解码器来解析压缩的音频和视频数据,并将其还原为原始的音频样本和视频帧。 -
编码(
Encoding
):在编码阶段,FFmpeg 使用选定的编码器将已解码的音频和视频数据重新编码为新的压缩格式。编码器将原始数据压缩并应用所选的编码算法,以减小文件大小并保持一定的图像质量和音频保真度。 -
封装(
Muxing
):在封装阶段,FFmpeg 将重新编码的音频和视频数据合并到指定的输出容器格式中,生成最终的转码文件。输出容器格式可以是各种常见格式,如 MP4、AVI、MKV 等。封装过程还会添加必要的元数据(例如文件标签、时间戳等)以及其他附加信息。
这四个过程通常是连续进行的,每个阶段的输出将作为下一个阶段的输入。这其中需要经过6个步骤:读取输入内容、音视频解封装、解码每一帧音视频数据、编码每一帧音视频数据、音视频重新封装、输出到目标。
FFmpeg
提供了一系列命令行选项和库函数来实现这些过程,并允许用户根据需求自定义设置参数,以满足不同的转码需求。一般我们用 FFmpeg
是以"输入→处理→输出"的流程来理解并书写命令行的。
3.常用命令
powershell
#查看FFmpeg支持的编码器
ffmpeg configure -encoders
#查看FFmpeg支持的解码器
ffmpeg configure -decoders
#查看FFmpeg支持的通信协议
ffmpeg configure -protocols
#查看FFmpeg所支持的音视频编码格式、文件封装格式与流媒体传输协议
ffmpeg configure --help
#播放视频
ffplay input.mp4
#播放完自动退出
ffplay -autoexit input.mp4
#设置视频的屏幕高宽比
ffmpeg -i input.mp4 -aspect 16:9 output.mp4
#编码格式转换
#MPEG4编码转成H264编码
ffmpeg -i input.mp4 -strict -2 -vcodec h264 output.mp4
#H264编码转成MPEG4编码
ffmpeg -i input.mp4 -strict -2 -vcodec mpeg4 output.mp4
4.视频压缩
powershell
ffmpeg -i 2020.mp4 -vcodec h264 -vf scale=640:-2 -threads 4 2020_conv.mp4
ffmpeg -i 1579251906.mp4 -strict -2 -vcodec h264 1579251906_output.mp4
#参数解释:
-i 2020.mp4 #输入文件,源文件
2020_conv.mp4 #输出文件,目标文件
-vf scale=640:-2
#改变视频分辨率,缩放到640px宽,高度的-2是考虑到libx264要求高度是偶数,所以设置成-2,让软件自动计算得出一个接近等比例的偶数高
-threads 4 #4核运算
其他参数:
-
-s 1280x720
设置输出文件的分辨率,w*h。
-
-b:v
输出文件的码率,一般500k左右即可,人眼看不到明显的闪烁,这个是与视频大小最直接相关的。
-
-preset
指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow。
与 veryslow相比,placebo以极高的编码时间为代价,只换取了大概1%的视频质量提升。这是一种收益递减准则:slow 与 medium相比提升了5%~10%;slower 与 slow相比提升了5%;veryslow 与 slower相比提升了3%。
针对特定类型的源内容(比如电影、动画等),还可以使用-tune参数进行特别的优化。
-
-an
去除音频流。
-
-vn
去除视频流。
-
-c:a
指定音频编码器。
-
-c:v
指定视频编码器,libx264,libx265,H.262,H.264,H.265。
libx264:最流行的开源 H.264 编码器。
NVENC:基于 NVIDIA GPU 的 H.264 编码器。
libx265:开源的 HEVC 编码器。
libvpx:谷歌的 VP8 和 VP9 编码器。
libaom:AV1 编码器。
-
-vcodec copy
表示不重新编码,在格式未改变的情况采用。
-
-re
以源文件固有帧率发送数据。
-
-minrate 964K -maxrate 3856K -bufsize 2000K
指定码率最小为964K,最大为3856K,缓冲区大小为 2000K。
-
-y
不经过确认,输出时直接覆盖同名文件。
-
-crf
参数来控制转码,取值范围为 0~51,其中0为无损模式,18~28是一个合理的范围,数值越大,画质越差。
5.视频拼接
powershell
#将4个视频拼接成一个很长的视频(无声音)
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0][1:0] [2:0][3:0] concat=n=4:v=1 [v]' -map '[v]' output.mp4
#将4个视频拼接成一个很长的视频(有声音)
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0][0:1] [1:0][1:1] [2:0][2:1] concat=n=3:v=1:a=1 [v][a]' -map '[v]' -map '[a]' output.mp4
#参数解释:
[0:0][0:1] [1:0][1:1] [2:0][2:1]
分别表示第1个输入文件的视频、音频,第2个输入文件的视频、音频,第3个输入文件的视频、音频。
concat=n=3:v=1:a=1
表示有3个输入文件,输出一条视频流和一条音频流。
[v][a]
得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。
powershell
#横向拼接2个视频
ffmpeg -i 0.mp4 -i 1.mp4 -filter_complex "[0:v]pad=iw*2:ih*1[a];[a][1:v]overlay=w" out.mp4
参数解释:
pad
将合成的视频宽高,这里iw代表第1个视频的宽,iw*2代表合成后的视频宽度加倍,ih为第1个视频的高,合成的两个视频最好分辨率一致。
overlay
覆盖,[a][1:v]overlay=w,后面代表是覆盖位置w:0。
powershell
#竖向拼接2个视频
ffmpeg -i 0.mp4 -i 1.mp4 -filter_complex "[0:v]pad=iw:ih*2[a];[a][1:v]overlay=0:h" out_2.mp4
#横向拼接3个视频
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]pad=iw*3:ih*1[a];[a][1:v]overlay=w[b];[b][2:v]overlay=2.0*w" out_v3.mp4
#竖向拼接3个视频
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]pad=iw:ih*3[a];[a][1:v]overlay=0:h[b];[b][2:v]overlay=0:2.0*h" out_v4.mp4
#4个视频2x2方式排列
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h" out.mp4
参考文章: