ffmpeg处理视频真的好用,丰俭由君

ffmpeg处理视频真的好用,丰俭由君

转码和编辑视频

我进入ffmpeg官网下载了Win64版本,下载速度很快,下载下来就是一个压缩包,解压后就是工具本体了,不过它没有任何UI界面,在Windows下你只能进入bin目录,然后Shift+鼠标右键打开命令窗口,使用ffmpeg的指令进行操作。

环境配置

压缩ffmpeg-release-essentials.zip到指定目录,进入bin目录,里面有三个文件

ffmpeg.exe ffplay.exe ffprobe.exe

ffplay.exe可以直接播放视频,后面跟视频路径既可以,也可以指定播放参数
ffprobe.exe用于显示视频文件的具体属性

其中我们经常使用到的就是 ffmpeg.exe,此时在目录中可以执行 ffmpeg version显示ffmpeg的版本号、编译选项、版本库

ffmpeg version 7.0.1-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 13.2.0 (Rev5, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil      59.  8.100 / 59.  8.100
libavcodec     61.  3.100 / 61.  3.100
libavformat    61.  1.100 / 61.  1.100
libavdevice    61.  1.100 / 61.  1.100
libavfilter    10.  1.100 / 10.  1.100
libswscale      8.  1.100 /  8.  1.100
libswresample   5.  1.100 /  5.  1.100
libpostproc    58.  1.100 / 58.  1.100

下面分析网上搜集的ffmpeg简单用法,可以进行很多基础的视频编辑。

先来个进阶玩法,视频转码(硬件转码)并保留多音轨

这里考虑了多音轨的同时使用了硬件转码,实际上这并不是最佳实践
最佳实践应该是转码是转码,多音轨应该是使用混流(也可以混流和转码同时)
这里的硬件转发以N卡为例,其他硬件的支持详见后面章节
实际使用并不局限于此列,可以根据上下文及实际需求自由组合,这才是ffmpeg的精髓

-i input.mkv 指输入文件为input.mkv

-map 0:v是指第0个input文件的视频流转到output

-map 0:a:0就是第0个文件的第0个音频流映射到输出文件

-map 0:a:1就是第0个文件的第1个音频流映射到输出文件

-vcodec h264_nvenc 视频流使用nvenc的硬件编码转为h264_nvenc,也可以用h264_qsv使用Intel核显编码

c:a copy 音频流直接copy

还可以在-i之前加上 -hwaccels auto 使用硬件解码(自动)

ffmpeg -i input.mkv -map 0:v -map 0:a:0 -map 0:a:1 -vcodec h264_nvenc -c:a copy out.mp4

ffmpeg的简单用法

转码

最简单命令如下:

ffmpeg -i out.ogv -vcodec h264 out.mp4
ffmpeg -i out.ogv -vcodec mpeg4 out.mp4
ffmpeg -i out.ogv -vcodec libxvid out.mp4
ffmpeg -i out.mp4 -vcodec wmv1 out.wmv
ffmpeg -i out.mp4 -vcodec wmv2 out.wmv

-i 后面是输入文件名。-vcodec 后面是编码格式,h264 最佳,但 Windows 系统默认不安装。如果是要插入 ppt 的视频,选择 wmv1 或 wmv2 基本上万无一失。

附加选项:-r 指定帧率,-s 指定分辨率,-b 指定比特率;于此同时可以对声道进行转码,-acodec 指定音频编码,-ab 指定音频比特率,-ac 指定声道数,例如

ffmpeg -i out.ogv -s 640x480 -b 500k -vcodec h264 -r 29.97 -acodec libfaac -ab 48k -ac 2 out.mp4

剪切

用 -ss 和 -t 选项, 从第 30 秒开始,向后截取 10 秒的视频,并保存:

ffmpeg -i input.wmv -ss 00:00:30.0 -c copy -t 00:00:10.0 output.wmv
ffmpeg -i input.wmv -ss 30 -c copy -t 10 output.wmv

达成相同效果,也可以用 -ss 和 -to 选项, 从第 30 秒截取到第 40 秒:

ffmpeg -i input.wmv -ss 30 -c copy -to 40 output.wmv

值得注意的是,ffmpeg 为了加速,会使用关键帧技术, 所以有时剪切出来的结果在起止时间上未必准确。 通常来说,把 -ss 选项放在 -i 之前,会使用关键帧技术; 把 -ss 选项放在 -i 之后,则不使用关键帧技术。 如果要使用关键帧技术又要保留时间戳,可以加上 -copyts 选项:

ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy -copyts cut.mp4

合并

把两个视频文件合并成一个。

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
 
$ ffmpeg -f concat -i mylist.txt -c copy output

转成中间格式再合成:

ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi

手动将视频文件和音频文件合并为MP4

ffmpeg -loglevel quiet -i video.m4s -i audio.m4s -c copy -y out.mp4

调整播放速度

加速四倍:

ffmpeg -i TheOrigin.mp4 -vf  "setpts=0.25*PTS" UpTheOrigin.mp4

四倍慢速:

ffmpeg -i TheOrigin.mp4 -vf "setpts=4*PTS" DownTheOrigin.mp4

帧率设置

使用-r选项
语法是:

ffmpeg -i input -r fps output

例如:

ffmpeg -i input.avi -r 30 output.mp4

使用fps filter

另一个设置帧率是用fps filter,特别是在filterchains使用时非常有用。
例如:修改输入文件的帧率到25

ffmpeg -v clip.mpg -vf fps=fps=25 clip.webm

比特率设置

比特率也是一个决定音视频总体质量的参数。他决定每个时间单位处理的bit数。
设置比特率:

比特率决定处理1s的编码流需要多少bits,设置用-b选项。区分音视频用-b:a和-b:v
例如:设置整体1.5Mbit每秒

ffmpeg -i file.avi -b 1.5M file.mp4

ffmpeg -i input.avi -b:v 1500K output.mp4

CBR设置

CBR设置一般用作直播流,比如视频会议。为输出设置CBR,有三个参数必须设置为同一个值。
bitrate(-b option), minimal rate(-minrate), maximal rate(-maxrate)。maximal rate需要设置-bufsize选项。例如设置CBR为0.5Mbit/s。

ffmpeg -i in.avi -b 0.5M -minrate 0.5M -maxrate 0.5M -bufsize 1M output.mkv

设置输出文件的最大size

用-fs选项。
例如设置输出文件的最大的size为10M

ffmpeg -i input.avi -fs 10MB output.mp4

文件大小计算

文件的大小是是音视频流大小的和。
视频流的大小的方程式是(除以8是由bits到bytes的转换):

video_size = video_bitrate * time_in_seconds / 8;

如果音频是解压缩的,计算公式是:

audio_size = smpaling_rate * bit_depth * channels * time_in_second / 8;

例如:计算10分钟的视频, 1500kbits/s 视频比特率和 128kbits/s的音频比特率,用下面的计算方法:

file_size = video_size + audio_size;
file_size = (video_bitrate + audio_bitrate) * time_in_seconds / 8;
file_size = (1500 kbits/s + 128kbits/s) * 600s
file_size = 1628kbits/s * 600s
file_size = 976800kb = 976800000 b / 8 = 122100000 B / 1024 = 119238.28125KB
file_size = 119238.28125 KB / 1024 = 116.443634033203125MB = 116.44M

固定质量模式

之前的转码都是恒定码率模式,很不科学。hevc_nvenc没有crf参数,这可咋办呢?好在找到了替代方案。通过将 -rc:v 设置为 vbr或者 vbr_hq,从而启用VBR模式,然后设置 -cq:v-qmin-qmax。这里最好把它们设置成一个数值,否则没有多大意义。这个数值接类似于crf参数。

ffmpeg -hwaccel cuvid -c:v hevc_cuvid -resize 1280x720  -i input.mkv -c:a copy  -vf "hwdownload,format=p010le"  -c:v hevc_nvenc -pix_fmt yuv420p -rc:v vbr -cq:v 20 -qmin 20 -qmax 20 output.mkv

批量转换

cd /d 
for /r %%a in (*.ts) do ffmpeg -threads 6 -i "%%~a" -codec copy -f mp4 "%%~dpna.mp4"
pause

音视频合并

D:\tsToMP4\ffmpeg -loglevel quiet -i video.m4s -i audio.m4s -c copy -y out.mp4

多音轨/字幕操作

很多电影有多个音轨或者字幕。例如这里有一个mkv文件,含有2个音轨,都是ac3。

我们将mkv转mp4,其中视频流部分我们直接copy(节省时间),音频的编码很快不用copy。

$ ffmpeg -i in.mkv -c:v copy out.mp41.

从log中我们发现,只有stream0:0stream0:1被转换了,这俩是原来的视频和其中一个音频流。stream0:1是指输入文件的第0个文件中的第1个流,因为我们input就只有一个文件,所以第一位一直是0。

即,默认情况下,视频的转换会只转换一个视频流和一个音频流,如果有多个音频流的话,只会转换第一个,同时默认情况下,字幕流不会被转换。

这是本来有字幕的视频

转换完,没有了字幕

如何保留多个音轨、字幕,一般可以使用map参数,-map 0:v是指第0个input文件的视频流转到output,-map 0:a:0就是第0个文件的第0个音频流搞过来,这样就把俩音轨都搞过来了。

$ ffmpeg -i input.mkv -map 0:v -map 0:a:0 -map 0:a:1 -c:v copy -c:a copy output.mp41.

更具体的我们还可以分别对每个音轨指定编码和比特率

$ ffmpeg -i input.mkv \
-map 0:v -c:v copy \
-map 0:a:0 -c:a:0 libmp3lame \
-map 0:a:1 -c:a:1 libvorbis -b:a:1 128k  \
-map 0:s:0 -c:s:0 srt \
output.mp41.2.3.4.5.6.

当然我们需要注意,新的容器得能支持对应的格式和功能,尤其是字幕功能,很多容器的支持是比较有限的,如果从mkv这种很强的字幕支持度,到比较弱的格式需要有些调整。

显卡加速即硬编解码

软硬编解码的区分:
  • 软编码:使用CPU进行编码

  • 硬编码:使用非CPU进行编码,如显卡GPU、专用的DSP、FPGA、ASIC芯片等

软硬编解码的区别:
  • 软编码:实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。

  • 硬编码:性能高,低码率下通常质量低于软编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。

简单来说硬解码就是 内存 - codec 电路 - 内存/显示 的过程所以速度会比软件编解码快

安装CUDA驱动

CUDA是一个驱动程序,可以让GPU进行相关运算,因为我们开发应用程序一般不直接操控GPU,而是通过驱动来操作。

首先确定自己的电脑是否支持CUDA

Video Encode and Decode GPU Support Matrix

命令相关

ffmpeg支持的硬件
硬件加速方式

通过命令 ffmpeg -hwaccels 可以查询系统支持的硬件加速器。

ffmpeg -hwaccels
----------------------------------------------
cuda
dxva2
qsv
d3d11va
opencl
vulkan

PS:以上输出代表系统所支持的硬件加速方式,后续会用到

硬编码后缀解释
  • qsv:intel显卡的快速视频同步技术(quick sync video)
  • nvenc:nvidia显卡的硬件视频编码器(nvidia hardware video encoder)
  • cuvid:nvdec的旧称,只有解码端。
  • cuda: 同上
  • amf:amd显卡的amf硬件编码器(amd hardware encoder)

基本上所有的Intel 电脑都支持qsv方式。

编解码器支持
ffmpeg -codecs

查询编码器

ffmpeg -codecs

后面可以跟 findstr命令查询所需的编码,例如: ffmpeg -codecs | findstr nvenc

ffmpeg -codecs | findstr nvenc
---------------------------------------------------------------
DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_qsv h264_cuvid ) (encoders:
 libx264 libx264 libx264rgb h264_amf h264_nvenc h264_qsv )
 DEV.L. hevc                 H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_qsv hevc_cuvid ) (encoder
s: libx265 hevc_amf hevc_nvenc hevc_qsv )

查询系统支持的编解码格式,需要用到 ffmpeg -decoders ffmpeg -encoders 两个命令。

查询编解码器选项

查询编码器hevc_nvenc的选项

ffmpeg -h encoder=hevc_nvenc

查询解码器 h264_qsv 的详细信息

ffmpeg -h decoder=h264_qsv
ffmpeg -decoders

下面以h264作为测试

ffmpeg -decoders | findstr  h264
------------------------------------------------------
VFS..D h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
V....D h264_qsv             H264 video (Intel Quick Sync Video acceleration) (codec h264)
V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)

PS:h264_qsvh264_cuvidh264 :就是支持的解码方式

findstr :作用相当于linux中的grep

h264_qsv:英特尔硬解码

h264_cuvid:英伟达硬解码

ffmpeg -encoders

同解码格式查询

ffmpeg -encoders | findstr h264
 --------------------------------------------------------
 V..... libx264              libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (codec h264)
 V..... libx264              libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (codec h264)
 V..... libx264rgb           libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB (codec h264)
 V....D h264_amf             AMD AMF H.264 Encoder (codec h264)
 V....D h264_nvenc           NVIDIA NVENC H.264 encoder (codec h264)
 V..... h264_qsv             H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (Intel Quick Sync Video acceleration) (codec h26)

findstr :作用相当于linux中的grep

如以上有类似输出则证明是支持硬解码或者硬编码的。

硬件加速命令
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:v h264_nvenc -b:v 2048k -s 1920x1080 output.mp4
常用命令参数解释
  • -hwaccel cuvid:使用cuvid进行硬件加速
  • -c:v h264_cuvid:使用h264_cuvid进行解码
  • -c:v h264_nvenc:使用h264_nvenc进行编码(nvidia硬件加速x265)
  • -b:v 2000k:比特率,值越大约清晰。
  • -s 1920x1080:分辨率
  • -b:v 3500K :视频平均比特率为 3500K
  • -bufsize 6000K:缓存区大小 6000K,建议设定为 当前码率帧率5,也许这里的2pass是针对缓冲区的,缓存未来5s
  • -maxrate 5000K:最大码率为 5000K,每帧的最高码率不超过这个数值
  • -preset slow:预设方案是 slow,slow已经是最好的选项了
  • -pix_fmt p010le:输出的像素格式是 p010le 也就10bit,只有新的硬件支持

参考

NVIDIA FFmpeg 转码指南

ffmpeg-with-nvidia-gpu

posted @ 2024-08-12 14:55  Is_Nothing  阅读(194)  评论(0)    收藏  举报