思维导图

作者:Aaron Dean

1. FFmpeg 简介

FFmpeg 开始于 2000 年,是免费、开源的多媒体编辑和转换软件。

与其类似或相关的框架有:ImageMagick 和 MLT Framework。

总体架构(ARCHITECTURE):

FFmpeg 包含:命令行工具(fmpeg、 ffprobe、ffplay)和库(libavformat、 libavcodec、libavfilter …)。

  • libavformat:读写容器格式(AVI, MKV, MP4, …)
  • libavcodec:读写编码格式(H.264, H.265, VP9, …)
  • libavfilter :多种音视频滤镜

2. FFmpeg 安装

Homebrew 是 macOS(或 Linux)缺失的软件包的管理器。安装好 Homebrew后 ,通过查看 brew 版本可检查是否安装成功。

$ brew --version

接下来,使用 Homebrew 安装 FFmpeg。

$ brew install ffmpeg

输入 ffmpeg,看见版本信息即安装成功。

$ ffmpeg
#输出:ffmpeg version 4.2.2 ...

3. 三个基本概念

容器

视频文件是一个容器(container),包含视频、音频和字幕。

常见容器格式(后缀名):MP4、MKV、WebM、AVI。

安装好 FFmpeg 后,使用下列命令可查看 FFmpeg 支持的容器(container)

$ ffmpeg -formats

编码格式

经过编码的视频和音频才能保存成文件。不同编码格式有不同的压缩率,从而导致文件大小和清晰度的差异。编码后会损失一些细节,以换取压缩后较小的文件体积。常见的编码格式如下:

  • 视频编码格式(有版权,可免费使用):H262、H264、H265。
  • 视频编码格式(无版权):VP8、VP9、AV1。
  • 常用音频编码格式:MP3、AAC。

安装后可通过以下命令查看 FFmpeg 支持的编码格式(CODEC)(视频和音频):

$ ffmpeg -codecs

编码器

编码器(encoders)是实现某种编码格式的库文件。只有安装了某种格式的编码器,才能实现该格式视频/音频的编码和解码。下面的命令可以查看 FFmpeg 已安装的编码器。

$ ffmpeg -encoders

FFmpeg 内置的视频编码器:

  • libx264:最流行的开源 H.264 编码器
  • NVENC:基于 NVIDIA GPU 的 H.264 编码器
  • libx265:开源的 HEVC 编码器
  • libvpx:谷歌的 VP8 和 VP9 编码器
  • libaom:AV1 编码器

音频编码器:

  • libfdk-aac
  • aac

4. FFmpeg 的使用格式

$ ffmpeg {1} {2} -i {3} {4} {5}

#参数多时建议写成多行,便于查看
$ ffmpeg \
[全局参数] \
[输入文件参数] \
-i [输入文件] \
[输出文件参数] \
[输出文件]

常用命令行参数如下:

  • -c:指定编码器
  • -c copy:直接复制,不经过重新编码(较快)
  • -c:v:指定视频编码器
  • -c:a:指定音频编码器
  • -i:指定输入文件
  • -an:去除音频流
  • -vn: 去除视频流
  • -preset:指定输出的视频质量,会影响文件的生成速度。该参数的可用值 有 ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow。
  • -y:不经过确认,输出时直接覆盖同名文件。

示例:下面的命令将 mp4 文件转成 webm 文件。输入的 mp4 文件的音频编码格式是 aac,视频编码格式是 H.264;输出的 webm 文件的视频编码格式是 VP9,音频格式是 Vorbis。

$ ffmpeg \
-y \ # 全局参数
-c:a libfdk_aac -c:v libx264 \ # 输入文件参数
-i input.mp4 \ # 输入文件
-c:v libvpx-vp9 -c:a libvorbis \ # 输出文件参数
output.webm # 输出文件

未指明编码格式时FFmpeg 会自己判断输入文件的编码。故上述命令可简写为:

$ ffmpeg -i input.avi output.mp4

5. 常见用法

  • 查看文件信息
#查看视频文件的元信息(编码格式、比特率)
$ ffmpeg -i input.mp4

#只显示元信息,隐藏冗余信息
$ ffmpeg -i input.mp4 -hide_banner
  • 转换编码格式(transcoding): 将视频文件从一种编码转成另一种编码。
#转成 H.264 编码
$ ffmpeg -i [input.file] -c:v libx264 output.mp4

#转成 H.265 编码
$ ffmpeg -i [input.file] -c:v libx265 output.mp4
  • 转换容器格式(transmuxing):将视频文件从一种容器转到另一种容器。
#mp4 转 webm
$ ffmpeg -i input.mp4 -c copy output.webm
  • 调整码率(transrating):改变编码的比特率,一般用来将视频文件的体积变小。
#指定码率:最小964K,最大3856K,缓冲区大小 2000K
$ ffmpeg \
-i input.mp4 \
-minrate 964K -maxrate 3856K -bufsize 2000K \
output.mp4
  • 改变视频分辨率(transsizing):下面的示例将分辨率从 1080p 转为 480p 。scale值必须是偶数,-1表示保持长宽比。
$ ffmpeg \
-i input.mp4 \
-vf scale=480:-1 \
output.mp4
  • 从视频里提取音频(demuxing)
$ ffmpeg \
-i input.aac -i input.mp4 \
output.mp4
  • 截图

-vframes 1指定只截取一帧,-q:v 2表示输出的图片质量,一般是1到5之间(1 为质量最高)。

#从指定时间开始,连续对1秒钟的视频进行截图
$ ffmpeg \
-y \
-i input.mp4 \
-ss 00:01:24 -t 00:00:01 \
output_%3d.jpg

#指定只截取一帧,截一张图
$ ffmpeg \
-ss 01:23:45 \
-i input \
-vframes 1 -q:v 2 \
output.jpg
  • 裁剪(cutting):截取原始视频里面的一个片段,输出为一个新视频。可以指定开始时间(start)和持续时间(duration),也可以指定结束时间(end)。-c copy表示不改变音频和视频的编码格式,直接拷贝。
$ ffmpeg -ss [start] -i [input] -t [duration] -c copy [output]
$ ffmpeg -ss [start] -i [input] -to [end] -c copy [output]
  • 为音频添加封面:将音频文件,转为带封面的视频文件。
$ ffmpeg \
-loop 1 \
-i cover.jpg -i input.mp3 \
-c:v libx264 -c:a aac -b:a 192k -shortest \
output.mp4

两个输入文件:封面图片cover.jpg 和 音频文件input.mp3。

-loop 1参数:表示图片无限循环。

-shortest参数:表示音频文件结束,输出视频就结束。


参考资料:FFmpeg 视频处理入门教程 — 阮一峰

文档协议:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)