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:0和stream0: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_qsv,h264_cuvid,h264:就是支持的解码方式
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,只有新的硬件支持

浙公网安备 33010602011771号