FFmpeg
来自项目 主页
- FFmpeg 是一套完整的、跨平台的音频和视频录制、转换和流媒体解决方案。它包含 libavcodec——领先的音频/视频编解码库。
安装
此外,一个值得注意的变体是 ffmpeg-fullAUR,它尽可能多地启用了可选功能。
编码示例
- 参数必须按正确顺序指定(例如:输入、视频、滤镜、音频、输出),这一点非常重要。如果不这样做,可能会导致参数被跳过,或阻止 FFmpeg 执行。
- FFmpeg 通常会自动选择可用的 CPU 线程数。但您也可以使用
-threads 数量参数来强制指定线程数。
请参阅 FFmpeg 编码维基 和 ffmpeg(1) § EXAMPLES。
屏幕截图
FFmpeg 包含 x11grab 和 ALSA 虚拟设备,能够捕获整个用户屏幕和音频输入。
进行截图 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 包含 video4linux2 和 ALSA 输入设备,能够捕获摄像头和音频输入。
以下命令将录制摄像头视频 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"。此时您可能希望应用任何额外的滤镜,以避免后续转码,从而尽可能保持视频质量。以下示例在进行视频防抖的同时执行了以下操作
unsharp是 vid.stab 作者推荐的滤镜。这里我们简单地使用默认值 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_s16leXAVC-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
音频转录
whisper 未在 ffmpeg 中配置,因此我们需要 ffmpeg-whisperAUR 或 ffmpeg-fullAUR,以及安装在 /usr/share/whisper.cpp-model-* 的 AUR 中的 whisper 模型 之一。
用于更好地检测麦克风流中何时有人在说话的 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 维基上的 如何将字幕刻录进视频)
硬字幕嵌入意味着将字幕合并到视频中。硬字幕无法禁用、无法切换语言也无法自定义字体大小,因此有时不被推荐。如有疑问,请优先使用软字幕。
- 将
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 音量。
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
要获得不同的响度配置文件,请使用滤镜的 i, tp 和 lra 参数,分别表示 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 -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 音频流转换为比特率为 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 指定持续时间。
去除音频
- 复制第一个视频流(
-map 0:0)以及第二个 AC-3 音频流(-map 0: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 驱动的特定 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
作为快速参考,固定质量编码可以通过以下方式实现
$ 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
NVENC 和 NVDEC 可以在使用私有 NVIDIA 驱动且安装了 nvidia-utils 软件包时用于编码/解码。最低支持的 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 [3] 搭配 iHD 或 i965 驱动,而不是直接使用 libmfx。请参阅 FFmpeg Wiki 的 Hybrid transcode 章节获取编码示例,并参阅 视频硬件加速#配置 VA-API 获取驱动程序说明。
AMD AMF
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
请参阅 https://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html 以获取有关使用调色板滤镜生成高质量 GIF 的更多信息。
预设文件
使用默认的 预设文件 填充 ~/.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 使用第二个文件的元数据(索引从 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
参见
- FFmpeg 文档 - 官方文档
- FFmpeg Wiki - 官方维基
- 使用 x264 编解码器编码 - MEncoder 文档
- H.264 编码指南 - Avidemux 维基
- 使用 FFmpeg - Linux 使用页面
- 受支持的音频和视频流 列表