FFmpeg

来自 ArchWiki

来自项目 主页

FFmpeg 是一个完整的跨平台解决方案,用于记录、转换和流式传输音频和视频。它包括 libavcodec - 领先的音频/视频编解码器库。

安装

注意: 您可能会遇到 FFmpeg 的分支,如 libavavconv,请参阅 FFmpeg/Libav 情况 这篇博客文章,了解有关项目差异和 FFmpeg 当前状态的信息。

安装 ffmpeg 软件包。

对于开发版本,请安装 ffmpeg-gitAUR 软件包。还有 ffmpeg-fullAUR,它构建时启用了尽可能多的可选功能。

编码示例

注意
  • 重要的是,参数要以正确的顺序指定(例如,输入、视频、过滤器、音频、输出)。 否则可能会导致参数被跳过或阻止 FFmpeg 执行。
  • FFmpeg 应该会自动选择可用的 CPU 线程数。 但是,您可能希望通过参数 -threads number 强制指定可用线程数。

请参阅 FFmpeg 编码 Wikiffmpeg(1) § 示例

屏幕捕获

FFmpeg 包括 x11grabALSA 虚拟设备,可以捕获整个用户显示和音频输入。

要截取屏幕截图 screen.png

$ ffmpeg -f x11grab -video_size 1920x1080 -i $DISPLAY -vframes 1 screen.png

其中 -video_size 指定要捕获的区域大小。

要录制无损编码且没有音频的屏幕录像 screen.mkv

$ ffmpeg -f x11grab -video_size 1920x1080 -framerate 25 -i $DISPLAY -c:v ffvhuff screen.mkv

这里使用了 Huffyuv 编解码器,它速度很快,但会产生巨大的文件大小。

要录制有损编码且带有音频的屏幕录像 screen.mp4

$ ffmpeg -f x11grab -video_size 1920x1080 -framerate 25 -i $DISPLAY -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac screen.mp4

这里,使用了 x264 编解码器,并使用了最快的编码速度。 可以使用其他编解码器; 如果写入每个帧太慢(由于磁盘性能不足或编码速度慢),则会丢帧,并且视频输出会断断续续。

如果视频流不应保存为文件,而是用作屏幕共享的虚拟网络摄像头,请参阅 v4l2loopback#使用 FFmpeg 投射 X11

另请参阅 官方文档

录制网络摄像头

FFmpeg 包括 video4linux2ALSA 输入设备,可以捕获网络摄像头和音频输入。

以下命令将从网络摄像头录制视频 webcam.mp4,不带音频,假设网络摄像头在 /dev/video0 下被正确识别

$ ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -c:v libx264 -preset ultrafast webcam.mp4

其中 -video_size 指定网络摄像头允许的最大图像尺寸。

以上操作会产生静音视频。 要从带有音频的网络摄像头录制视频 webcam.mp4

$ ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -f alsa -i default -c:v libx264 -preset ultrafast -c:a aac webcam.mp4

这里,使用了 x264 编解码器,并使用了最快的编码速度。 可以使用其他编解码器; 如果写入每个帧太慢(由于磁盘性能不足或编码速度慢),则会丢帧,并且视频输出会断断续续。

另请参阅 官方文档

VOB 转任何容器格式

将所需的 VOB 文件连接成单个流,并将它们混合到 MPEG-2 中

$ cat f0.VOB f1.VOB f2.VOB | ffmpeg -i - out.mp2

x264

无损

ultrafast 预设将提供最快的编码,并且对于快速捕获(例如屏幕录制)非常有用

$ ffmpeg -i input -c:v libx264 -preset ultrafast -qp 0 -c:a copy output

与预设频谱的另一端相反的是 veryslow,它的编码速度比 ultrafast 慢,但会提供更小的输出文件大小

$ ffmpeg -i input -c:v libx264 -preset veryslow -qp 0 -c:a copy output

这两个示例都将提供相同的质量输出。

提示: 如果您的计算机能够实时处理 -preset superfast,您应该使用它而不是 -preset ultrafast。 Ultrafast 的压缩效率远低于 superfast。

恒定速率因子

当您想要特定的质量输出时使用。 一般用法是使用仍然提供可接受质量的最高 -crf 值。 值越低质量越高; 0 是无损的,18 是视觉上无损的,23 是默认值。 一个合理的范围在 18 到 28 之间。 使用您有耐心等待的最慢的 -preset。 有关更多信息,请参阅 x264 编码指南

$ ffmpeg -i video -c:v libx264 -tune film -preset slow -crf 22 -x264opts fast_pskip=0 -c:a libmp3lame -aq 4 output.mkv

-tune 选项可用于 匹配正在编码的媒体的类型和内容

双Pass(极高质量)

音频已停用,因为在多次 Pass 运行的第一次运行中仅记录视频统计信息

$ ffmpeg -i video.VOB -an -vcodec libx264 -pass 1 -preset veryslow \
-threads 0 -b:v 3000k -x264opts frameref=15:fast_pskip=0 -f rawvideo -y /dev/null

容器格式会自动检测并从输出文件扩展名 (.mkv) 混合到其中

$ ffmpeg -i video.VOB -acodec aac -b:a 256k -ar 96000 -vcodec libx264 \
-pass 2 -preset veryslow -threads 0 -b:v 3000k -x264opts frameref=15:fast_pskip=0 video.mkv

视频稳定

使用 vid.stab 插件进行视频稳定需要两个 Pass。

第一Pass

第一Pass 将稳定参数记录到文件和/或用于视觉分析的测试视频。

  • 仅将稳定参数记录到文件
    $ ffmpeg -i input -vf vidstabdetect=stepsize=4:mincontrast=0:result=transforms.trf -f null -
  • 将稳定参数记录到文件并创建测试视频“output-stab”以进行视觉分析
    $ ffmpeg -i input -vf vidstabdetect=stepsize=4:mincontrast=0:result=transforms.trf output-stab
第二Pass

第二Pass 解析从第一Pass 生成的稳定参数,并将它们应用于生成“output-stab_final”。 您将希望在此处应用任何其他过滤器,以避免后续转码以尽可能保留视频质量。 以下示例除了视频稳定之外还执行以下操作

  • vid.stab 的作者推荐使用 unsharp。 这里我们只是使用 5:5:1.0:5:5:1.0 的默认值
  • 提示: fade=t=in:st=0:d=4
    从文件开头开始,在四秒钟内从黑色淡入
  • 提示: fade=t=out:st=60:d=4
    从视频开始的第六十秒开始,在四秒钟内淡出为黑色
  • -c:a pcm_s16le XAVC-S 编解码器以 pcm_s16be 格式录制,该格式无损转码为 pcm_s16le
$  ffmpeg -i input -vf vidstabtransform=smoothing=30:interpol=bicubic:input=transforms.trf,unsharp,fade=t=in:st=0:d=4,fade=t=out:st=60:d=4 -c:v libx264 -tune film -preset veryslow -crf 8 -x264opts fast_pskip=0 -c:a pcm_s16le output-stab_final

x265

示例命令显示在不带任何参数调用 libx265 时的默认值(恒定速率因子编码)

ffmpeg -i input -c:v libx265 -crf 28 -preset medium -c:a libvorbis output.mp4

有关更多信息,请参阅 FFmpeg H.265/HEVC 视频编码指南

单Pass MPEG-2(接近无损)

允许 FFmpeg 自动设置 DVD 标准化参数。 以 ~30 FPS 编码为 DVD MPEG-2

$ ffmpeg -i video.VOB -target ntsc-dvd output.mpg

以 ~24 FPS 编码为 DVD MPEG-2

$ ffmpeg -i video.VOB -target film-dvd output.mpg

字幕

提取

嵌入在容器文件(如 MPEG-2 和 Matroska)中的字幕可以提取并转换为 SRT、SSA、WebVTT 等字幕格式 [1]

  • 检查文件以确定它是否包含字幕流
$ ffprobe -hide_banner foo.mkv
...
Stream #0:0(und): Video: h264 (High), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
  Metadata:
  CREATION_TIME   : 2012-06-05 05:04:15
  LANGUAGE        : und
Stream #0:1(und): Audio: aac, 44100 Hz, stereo, fltp (default)
 Metadata:
 CREATION_TIME   : 2012-06-05 05:10:34
 LANGUAGE        : und
 HANDLER_NAME    : GPAC ISO Audio Handler
Stream #0:2: Subtitle: ssa (default)
  • foo.mkv 具有嵌入式 SSA 字幕,可以将其提取到独立文件中
$ ffmpeg -i foo.mkv foo.ssa

添加 -c:s srt 以将字幕保存为所需的格式,例如 SubRip

$ ffmpeg -i foo.mkv -c:s srt foo.srt

在处理多个字幕时,您可能需要使用 -map key:stream 参数指定需要提取的流

$ ffmpeg -i foo.mkv -map 0:2 foo.ssa

硬字幕

(说明基于 FFmpeg Wiki 上的 HowToBurnSubtitlesIntoVideo

硬字幕 需要将字幕与视频合并。 硬字幕无法禁用,也无法切换语言。

  • 使用 foo.ssa 中的字幕覆盖 foo.mpg
$ ffmpeg -i foo.mpg -vf subtitles=foo.ssa out.mpg

音量增益

音量增益可以通过 ffmpeg 的过滤器功能进行修改。 首先使用 -af-filter:a 选择音频流,然后选择 volume 过滤器,后跟您要更改流的数值。 例如

$ ffmpeg -i input.flac -af volume=1.5 ouput.flac

这里 volume=1.5 提供 150% 的音量增益,而不是 1.5,例如使用 0.5 将音量减半。 音量过滤器还可以采用分贝测量值,使用 volume=3dB 将音量增加 3dB,或使用 volume=-3dB 将音量降低 3dB。

注意: 将文件的音量增益加倍,与将其音量加倍不同。 您将需要进行实验才能找到合适的音量。
提示: 要了解文件的当前平均音量和峰值音量,可以使用 volumedetect 过滤器: ffmpeg -i input.flac -af volumedetect -f null -。 然后,可以将目标级别和当前级别之间的差异提供给 volume 过滤器,以达到所需的级别。

音量标准化

也可以使用 loudnorm 过滤器通过标准化来实现给定的平均音量和峰值音量。 要使用 fmpeg 的默认值(目标平均响度、峰值和范围响度分别为 -24 LUFS、-2 dBTP 和 7 LU)来标准化文件的感知响度,请使用

$ ffmpeg -i input.flac -af loudnorm output.flac

要获得不同的响度配置文件,请使用过滤器的 itplra 参数分别指示integrated(集成)、true peak(真峰值)和 loudness range(响度范围)。 例如,对于比默认值更高的感知响度,请使用

$ ffmpeg -i input.flac -af loudnorm=i=-16:tp=-1.5:lra=11:print_format=summary output.flac

在本例中,还添加了 print_format=summary 以显示音频文件的输入和输出响度值。

注意: 该过滤器还支持双Pass模式,从第一次运行中提取测量的响度值,并在第二次运行中使用它们来执行线性标准化。 有关更多信息,请参阅 ffmpeg loudnorm 文档
提示: 要了解文件的当前响度测量值,请使用 ffmpeg -i input.flac -af loudnorm=print_format=summary -f null -

提取音频

$ ffmpeg -i video.mpg output.ext
...
Input #0, avi, from 'video.mpg':
  Duration: 01:58:28.96, start: 0.000000, bitrate: 3000 kb/s
    Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 1:1 DAR 16:9], 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0.1: Audio: ac3, 48000 Hz, stereo, s16, 384 kb/s
    Stream #0.2: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
    Stream #0.3: Audio: dts, 48000 Hz, 5.1 768 kb/s
...

完全按照多路复用到文件中的方式提取第一个 (-map 0:1) AC-3 编码音频流

$ ffmpeg -i video.mpg -map 0:1 -acodec copy -vn video.ac3

将第三个 (-map 0:3) DTS 音频流转换为 AAC 文件,比特率为 192 kb/s,采样率 为 96000 Hz

$ ffmpeg -i video.mpg -map 0:3 -acodec aac -b:a 192k -ar 96000 -vn output.aac

-vn 禁用视频流的处理。

提取特定时间间隔的音频流

$ ffmpeg -ss 00:01:25 -t 00:00:05 -i video.mpg -map 0:1 -acodec copy -vn output.ac3

-ss 指定起始点,-t 指定持续时间。

去除音频

  1. 复制第一个视频流 (-map 0:0) 以及第二个 AC-3 音频流 (-map 0:2)。
  2. 将 AC-3 音频流转换为双声道 MP3,比特率为 128 kb/s,采样率为 48000 Hz。
$ ffmpeg -i video.mpg -map 0:0 -map 0:2 -vcodec copy -acodec libmp3lame \
-b:a 128k -ar 48000 -ac 2 video.mkv
$ ffmpeg -i video.mkv
...
Input #0, avi, from 'video.mpg':
  Duration: 01:58:28.96, start: 0.000000, bitrate: 3000 kb/s
    Stream #0.0: Video: mpeg4, yuv420p, 720x480 [PAR 1:1 DAR 16:9], 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s
注意: 删除不需要的音频流可以为提高视频质量分配更多比特。

分割文件

您可以使用 copy 编解码器对文件执行操作,而无需更改编码。 例如,这允许您轻松地将任何类型的媒体文件拆分为两个

$ ffmpeg -i file.ext -t 00:05:30 -c copy part1.ext -ss 00:05:30 -c copy part2.ext

硬件视频加速

使用 硬件加速 API 可以提高编码/解码性能,但是只允许使用特定类型的编解码器,并且/或者当使用软件编码时,可能并不总是产生相同的结果。

VA-API

VA-API 可用于在 Intel CPU 上进行编码和解码(需要 intel-media-driverlibva-intel-driver)以及在使用开源 AMDGPU 驱动程序时,在某些 AMD GPU 上进行编码和解码(需要 mesa)。 有关可用参数和支持平台的信息,请参阅 FFmpeg 文档

使用受支持的 H.264 编解码器进行编码的示例

$ ffmpeg -threads 1 -i file.ext -vaapi_device /dev/dri/renderD128 -vcodec h264_vaapi -vf format='nv12|vaapi,hwupload' output.mp4
注意: VA-API 通常在构建时由 ffmpeg 的自动检测功能启用,只要它检测到包含在 libva 中的相应标头和库即可,libva 应该是 FFmpeg 软件包的依赖项。

对于快速参考,可以使用以下方法实现恒定质量编码

$ ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 -vf 'format=nv12,hwupload' -c:v hevc_vaapi -f mp4 -rc_mode 1 -qp 25 output.mp4

如果使用 hevc_vaapi,请在 25(视觉上相同)和更高(28 开始出现非常小的视觉损失)之间调整 -qp。 如果使用 h264_vaapi,请在 18(视觉上相同)和更高(20 开始出现非常小的视觉损失)之间调整。 此外,hevc_vaapi 的编码速度似乎比 h264_vaapi 快 50%。

NVIDIA NVENC/NVDEC

当使用专有的 NVIDIA 驱动程序并安装 nvidia-utils 软件包时,NVENCNVDEC 可用于编码/解码。 最低支持的 GPU 来自 600 系列,有关详细信息,请参阅 硬件视频加速#NVIDIA

这个旧的 gist 提供了一些技巧。 NVENC 有点类似于 CUDA,因此即使从终端会话也可以工作。 根据硬件的不同,NVENC 比 Intel 的 VA-API 编码器快几倍。

要打印可用选项,请执行(hevc_nvenc 也可能可用)

$ ffmpeg -help encoder=h264_nvenc

使用示例

$ ffmpeg -i source.ext -c:v h264_nvenc -rc constqp -qp 28 output.mkv

Intel QuickSync (QSV)

Intel® Quick Sync Video 使用 Intel GPU 的媒体处理能力来快速解码和编码,使处理器能够完成其他任务并提高系统响应速度。

这需要安装 libmfx 运行时实现。 libmfx 是一个调度程序库,它根据底层硬件平台在运行时加载实现。

当在 Iron Lake (Gen5) 到 Ice Lake (Gen10) GPU 下运行时,它将加载 intel-media-sdk 作为运行时实现。

当在 Tiger Lake (Gen11) 和更新的 GPU 下运行时,libmfx 将加载 vpl-gpu-rt。 另请参阅 vpl-gpu-rt 系统要求

在具有单个 Intel GPU 的系统上,运行时实现无法更改或选择,并且应按照将在其上运行的硬件安装相应的实现。

未能安装所述运行时将导致如下错误

[AVHWDeviceContext @ 0x558283838c80] Error initializing an MFX session: -3.
Device creation failed: -1313558101.

QuickSync 的使用在 FFmpeg Wiki 中进行了描述。 建议使用 VA-API [2] 以及 iHDi965 驱动程序,而不是直接使用 libmfx,请参阅 FFmpeg Wiki 部分 Hybrid transcode 以获取编码示例,并参阅 硬件视频加速#配置 VA-API 以获取驱动程序说明。

AMD AMF

AMD 通过 AMD 视频编码引擎(GPU 编码)为 Linux 添加了对仅 H264 视频编码的支持,并使用 AMDGPU PRO 专有软件包,并且 ffmpeg 添加了对 AMF 视频编码的支持,因此为了使用 h264_amf 视频编码器进行编码,需要 amf-amdgpu-proAUR。 您可能需要链接到 AMDGPU PRO 软件包提供的 ICD 文件作为变量,否则 ffmpeg 可能会使用开放 AMDGPU 的 ICD 文件并且无法使用此视频编码器。 以下是编码命令示例

$ VK_DRIVER_FILES=/usr/share/vulkan/icd.d/amd_pro_icd64.json ffmpeg -hwaccel auto -vaapi_device /dev/dri/renderD128 -i input.mkv -c:v h264_amf -rc 1 -b:v 8M h264_amf_8M.mp4

对于快速参考,可以使用以下方法实现恒定质量编码

$ VK_DRIVER_FILES=/usr/share/vulkan/icd.d/amd_pro_icd64.json ffmpeg -hwaccel auto -vaapi_device /dev/dri/renderD128 -i input.mp4 -c:v h264_amf -f mp4 -rc 0 -qp_b 22 -qp_i 22 -qp_p 22 -quality 2 output.mp4

一起调整三个 -qp_(b|i|p),18 为视觉上相同,22 为开始出现非常小的视觉损失。

动画 GIF

虽然动画 GIF 通常由于图像质量差、文件大小相对较大且缺乏音频支持而成为视频格式的糟糕选择,但它们仍然在网络上频繁使用。 以下命令可用于将视频转换为动画 GIF

$ ffmpeg -i input.mp4 -vf "fps=10,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop -1 output.gif

有关使用调色板过滤器生成高质量 GIF 的更多信息,请参阅 https://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html

预设文件

使用默认 预设文件 填充 ~/.ffmpeg

$ cp -iR /usr/share/ffmpeg ~/.ffmpeg

创建新的和/或修改默认预设文件

~/.ffmpeg/libavcodec-vhq.ffpreset
vtag=DX50
mbd=2
trellis=2
flags=+cbp+mv0
pre_dia_size=4
dia_size=4
precmp=4
cmp=4
subcmp=4
preme=2
qns=2

使用预设文件

在声明所需的 -vcodec 后启用 -vpre 选项

libavcodec-vhq.ffpreset

  • libavcodec = vcodec/acodec 的名称
  • vhq = 要调用的特定预设的名称
  • ffpreset = FFmpeg 预设文件类型后缀

技巧和窍门

减少冗余输出

使用以下选项的组合将冗余输出减少到所需的级别

  • -hide_banner:阻止 ffmpeg 输出其版权声明、构建选项和库版本
  • -loglevel:调节冗余级别(可以使用微调选项),例如 -loglevel warning
  • -nostats:禁用打印编码进度/统计信息

输出视频时长

$ ffprobe -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 file.ext

以 JSON 格式输出流信息

$ ffprobe -v quiet -print_format json -show_format -show_streams file.ext

每隔 X 帧创建视频截图

$ ffmpeg -i file.ext -an -s 319x180 -vf fps=1/100 -qscale:v 75 %03d.jpg

参见