跳转至内容

FFmpeg

来自 ArchWiki

来自项目 主页

FFmpeg 是一个完整的、跨平台的解决方案,用于记录、转换和流式传输音频和视频。它包含 libavcodec——领先的音视频编解码库。
注意: 您可能会遇到对 libav 和 avconv 等 FFmpeg 分支的引用。这些分支现已被 废弃;如果您对历史感兴趣,请参阅 The FFmpeg/Libav situation

安装

安装 ffmpeg 软件包,它应涵盖大多数使用场景。

或者,一个值得注意的变体是 ffmpeg-fullAUR,它构建时启用了尽可能多的可选功能。

编码示例

  • 务必按正确的顺序指定参数(例如:输入、视频、滤镜、音频、输出)。否则可能会导致参数被跳过,或者 FFmpeg 无法执行。
  • FFmpeg 通常会自动选择可用的 CPU 线程数。不过,您也可以通过参数 -threads number 强制指定线程数。

参阅 FFmpeg 编码维基ffmpeg(1) § EXAMPLES

屏幕截图

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#Casting X11 using FFmpeg

另请参阅 官方文档

录制摄像头

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)

用于需要特定输出质量的场景。常规做法是使用能提供可接受质量的最高 -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 选项来 匹配编码媒体的内容类型

二次编码 (超高质量)

禁用音频,因为在多次编码的第一遍中仅记录视频统计信息

$ 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 插件进行视频防抖需要两遍编码。

第一遍

第一遍记录防抖参数到文件和/或生成用于视觉分析的测试视频。

  • 仅将防抖参数记录到文件
    $ 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
第二遍

第二遍解析第一遍生成的防抖参数并应用它们以生成 "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
    在视频第 60 秒开始淡出,持续四秒
  • -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 视频编码指南

单遍 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 未配置 whisper,因此我们需要 ffmpeg-whisperAURffmpeg-fullAUR,以及 AUR 中的 whisper 模型 之一,它们会安装到 /usr/share/whisper.cpp-model-*

用于更好地检测麦克风流中何时有人讲话的 Vad 模型目前未打包,请使用 download-vad-model.sh

模型均为多语言模型,除非模型名称包含 .en。以 -q5_0 结尾的模型已 量化(需要更少的内存和磁盘空间,且根据硬件不同,处理效率更高)。以 -tdrz 结尾的模型支持使用 tinydiarize 进行本地说话人区分(标记发言者切换)。有关模型的更多信息,请参阅 上游 (openai/whisper)[2]

$ ffmpeg -i input.mp4 -vn -af "whisper=model=/usr/share/whisper.cpp-model-large-v3/ggml-large-v3.bin\
:language=en\
:queue=3\
:destination=output.srt\
:format=srt" -f null -

硬压字幕

(说明基于 FFmpeg 维基上的 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%,使用例如 0.5 代替 1.5 可将音量减半。volume 滤镜也可以接受分贝单位,使用 volume=3dB 可将音量增加 3dB,使用 volume=-3dB 可将其减少 3dB。

注意: 将文件的音量增益加倍并不等同于将音量加倍。您需要进行实验以找到合适的音量。
提示: 要获知文件当前的平均音量和峰值音量,可以使用 volumedetect 滤镜:ffmpeg -i input.flac -af volumedetect -f null -。然后,将目标音量与当前音量之间的差值提供给 volume 滤镜即可达到所需音量。

音量标准化

也可以通过使用 loudnorm 滤镜进行标准化来实现给定的平均音量和峰值音量。要使用 ffmpeg 的目标平均值、峰值和范围响度默认值(分别为 -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 以显示音频文件的输入和输出响度值。

注意: 该滤镜还支持两遍模式,从第一遍运行中提取测量到的响度值,并在第二遍中使用它们来进行线性标准化。有关更多信息,请参阅 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:1AC-3 编码音频流

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

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

$ 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 -t 00:05:30 -c copy part1 -ss 00:05:30 -c copy part2

硬件视频加速

编码/解码性能可以通过使用 硬件加速 API 来提高,但只有特定类型的编解码器才被允许,且在使用软件编码时结果可能不完全相同。

VA-API

VA-API 可用于 Intel iGPU 及其独立 Arc GPU(较新的 Intel 独立 GPU 和 iGPU 需要 intel-media-driver,较旧的 iGPU 需要 libva-intel-driver),以及在使用开源 AMDGPU 驱动程序(需要 mesa)的特定 AMD GPU 上使用。参阅 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(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,请将 -qp 调整在 25(视觉相同)及以上(28 开始出现极小的视觉损失)。如果使用 h264_vaapi,请将该值调整在 18(视觉相同)及以上(20 开始出现极小的视觉损失)。此外,hevc_vaapi 的编码速度似乎比 h264_vaapi 快 50%。

NVIDIA NVENC/NVDEC

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

此旧文 提供了一些技巧。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 Video Processing Library (Intel VPL) 合并。

注意: 此内容并非 ffmpeg 所特有(请在 Talk:FFmpeg 中讨论)

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 维基 中。建议使用 VA-API [3] 并搭配 iHDi965 驱动程序,而不是直接使用 libmfx。有关编码示例,请参阅 FFmpeg 维基的 Hybrid transcode 章节;有关驱动程序说明,请参阅 硬件视频加速#Configuring VA-API

AMD AMF

本文或本章节已过时。

原因: AMD Media Framework 的最新版本不再需要开源驱动程序的专有附加组件,但 AUR 软件包尚未更新,也没有上传依赖于开源 AMDGPU 驱动程序的新 amf 软件包。(请在 Talk:FFmpeg 中讨论)

AMD 通过开源驱动程序的专有插件增加了对 Linux 上仅 H264 视频编码(GPU 编码)的支持,并且 ffmpeg 也增加了对 AMF 视频编码的支持,因此要使用 h264_amf 视频编码器,需要 amf-amdgpu-proAUR。您可能需要将链接指向专有软件包提供的 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:禁用打印编码进度/统计信息

环境变量 SVT_LOG(默认为 3,即 INFO,非常详细)可用于静默 svt-av1 (libsvtav1) 的输出,此输出完全不受上述任何选项的影响。或者,如果需要,可以使用 SVT_LOG_FILE 将输出重定向到单独的文件。[4][5]

输出视频时长

$ 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

修改元数据

FFmpeg 无法在单个命令中直接修改元数据,但您可以手动提取并重新应用这些属性。

将现有(全局)元数据提取到文本文件中

$ ffmpeg -i 'song.mp3' -f ffmetadata song_metadata.txt

使用文本文件中的元数据创建新文件

$ ffmpeg -i 'song.mp3' -f ffmetadata -i new_metadata.txt -map_metadata 1 -id3v2_version 4 song_new.mp3

-map_metadata 1 告诉 ffmpeg 使用第 2 个文件的元数据(索引从 0 开始)。

除了全局元数据,每个流也可以拥有自己的元数据,例如使用 -map_metadata:s:v 0:s:v-map_metadata:s:a 0:s:a 进行导出。

ffprobe(同样来自 ffmpeg)提供了更多导出格式:default、compact/csv、flat、ini、json 和 xml。

减少转换伪影

有时,在编解码器之间转换视频(例如 h264 到 AV1)时,尽管源文件没有伪影,您仍可能会得到轻微的伪影。许多编解码器都有 preset 选项,通过增加编码计算时间来控制质量。[6] 将预设更改为更高质量的值可能会消除这些伪影。

例如 -c:v libsvtav1

-svtav1-params preset=5

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.