FFmpeg
来自项目主页
- FFmpeg是一个完整、跨平台的音频和视频录制、转换和流媒体解决方案。它包含了libavcodec——领先的音频/视频编解码器库。
安装
安装ffmpeg软件包。一个值得注意的变体是ffmpeg-fullAUR,它被构建为尽可能多地启用可选功能。
编码示例
- 参数的指定顺序至关重要(例如,输入、视频、滤镜、音频、输出)。否则可能会导致参数被跳过或阻止FFmpeg执行。
- FFmpeg应自动选择可用的CPU线程数。但是,您可以通过参数
-threads number强制指定可用线程数。
请参阅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值。值越低质量越高;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从视频的第六十秒开始,持续四秒钟淡出到黑色。
-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的DVDMPEG-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维基上的如何将字幕刻入视频)
硬字幕是指将字幕与视频合并。硬字幕无法禁用,也不能切换语言或自定义字体大小,因此有时被认为是不推荐的。如有疑问,请使用软字幕而不是硬字幕。
- 用
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滤镜也可以接受分贝度量,使用volume=3dB增加3dB的音量,或volume=-3dB减少3dB的音量。
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
要获得不同的响度配置文件,请使用滤镜的i、tp和lra参数来分别指示集成的、真实峰值和响度范围。例如,为了获得比默认值更高的感知响度,请使用:
$ 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.ext -t 00:05:30 -c copy part1.ext -ss 00:05:30 -c copy part2.ext
硬件视频加速
通过使用硬件加速API可以提高编码/解码性能,但是只允许特定种类的编解码器,并且/或者在使用软件编码时可能不会总是产生相同的结果。
VA-API
VA-API可用于Intel iGPU及其专用Arc GPU上的编码和解码(需要intel-media-driver用于较新的Intel专用GPU和iGPU,或libva-intel-driver用于较旧的iGPU),以及在使用开源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
为了快速参考,使用以下命令可以实现恒定质量编码:
$ 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,请将-qp设置为18(视觉上相同)到更高(20开始有非常小的视觉损失)。此外,hevc_vaapi的编码速度似乎比h264_vaapi快50%。
NVIDIA NVENC/NVDEC
在使用专有的NVIDIA驱动程序并安装nvidia-utils软件包时,可以使用NVENC和NVDEC进行编码/解码。支持的最低GPU是GeForce 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]配合iHD或i965驱动程序,而不是直接使用libmfx,有关编码示例,请参阅FFmpeg Wiki的混合转码部分,有关驱动程序说明,请参阅硬件视频加速#配置VA-API。
AMD AMF
AMD通过AMD Video Coding Engine(GPU编码)在Linux上添加了对H264视频编码的支持,并附带了开放驱动程序的专有附加组件,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:禁用编码进度/统计信息的打印。
输出视频时长
$ 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)提供更多导出格式:默认、紧凑/csv、平面、ini、json和xml。
参见
- FFmpeg文档 - 官方文档
- FFmpeg Wiki - 官方维基
- 使用x264编解码器编码 - MEncoder文档
- H.264编码指南 - Avidemux维基
- 使用FFmpeg - Linux how to 页面
- 支持的音频和视频流列表。