Windows 软件之 FFmpeg
前言
FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。
1 FFmpeg 视频处理
为方便测试,我们首先使用 winget install MediaArea.MediaInfo 命令安装一下 mediainfo 命令(可以方便地查看视频信息),然后创建 mediainfo.ps1 文件,并输入附录1中的内容。
这里我以周董稻香 mv 视频为例。视频信息如下:
1.1 编解码
可通过转换分辨率、视频编码转换为 H265 等方式来压缩视频大小。
- 1)转换编码(压缩)
ffmpeg -hwaccel cuda -i .\周杰伦-稻香.mp4 -vf scale=720:480 -c:v libx265 -crf 18 .\周杰伦-稻香C.mp4 -hwaccel 可选择 cpu 或 gpu 加速 -i 输入的视频文件 -vf scale 视频分辨率(宽x高) -c:v libx265 选择视频编码为 H265 -crf Constant Rate Factor, 0~51,默认 28,20 以下时视觉上无损
- 2)转换结果:大小减少 20.8%。
当然,原视频分辨率为 720x480,也可以指定为 2560×1440 的 2K 分辨率,不过视频大小就会大大增加了。
1.2 其它视频编辑命令
# (1)调整视频的分辨率
ffmpeg -i input.mp4 -vf scale=640:360 output.mp4
# (2)调整视频的码率
ffmpeg -i input.mp4 -b:v 512k output.mp4
# (3)使用更高效的视频编码格式
ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4
# (4)截取前 10 秒视频
ffmpeg -i input.mp4 -ss 00:00:00 -to 00:00:10 -c copy output.mp4
# (5)视频合并(fps、分辨率不同的视频合并会出现问题)
# 5.1 创建文件 1.txt 后输入以下内容(有多少视频就输入多少行):
file '视频名'
# 5.2 命令行执行以下命令进行合并
ffmpeg.exe -f concat -safe 0 -i .\1.txt -c copy -y '1.mp4'
# (6)将图片设置为视频封面
ffmpeg -i input_video.mp4 -i input_image.png \
-map 0 -map 1 \
-c copy -c:v:1 png \
-disposition:v:1 attached_pic \
output_video.mp4
1.3 视频抽帧
# (1)抽取视频关键帧(IPB)
ffmpeg -i video.mp4 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 2 -s 320x240 thumb-%02d.png
# (2)抽取视频场景转换帧
ffmpeg -i video.mp4 -f image2 -vf "select=gt(scene\,.4)" -vsync vfr %03d.png
# (3)均匀抽帧:-r 指定抽取的帧率,即从视频中每秒钟抽取图片的数量。1代表每秒抽取一帧。
ffmpeg -i video.mp4 -r 1 -q:v 2 -f image2 ./%08d.000000.jpg
# (4)抽取指定时间帧
ffmpeg -ss 00:00:30 -i video.mp4 -vframes 1 0.jpg # 耗时短(使用关键帧进行索引)
ffmpeg -i video.mp4 -ss 00:00:30 -vframes 1 0.jpg # 耗时长
# (5)抽帧制作缩略图
ffmpeg -i video.mp4 -vf 'fps=1/95:round=zero,scale=480x360,tile=8x6' M%03d.jpg
# -vf 表示指定过滤器。多个过滤器用 ',' 隔开;一个过滤器的多个参数使用 ':' 分开
# fps=1/95 表示 95 秒输出一张图
# round=zero 表示时间戳向 0 取整
# scale=480x360 表示图片分辨率大小
# tile=5x5 表示将截图使用 8x6 组合起来
制作缩略图:ffmpeg -i .\周杰伦-稻香C.mp4 -vf 'fps=1/11:round=zero,scale=720x480,tile=5x4' M%03d.jpg
也可以使用 PotPlayer 来创建缩略图:右键 -> 视频 -> 图像截取 -> 创建缩略图
- 参考:
- FFmpeg视频抽帧那些事:https://zhuanlan.zhihu.com/p/85895180
- FFmpeg 制作视频预览缩略图:https://zhuanlan.zhihu.com/p/570453447
- https://www.coder.work/article/3458321
2 FFmpeg 音频处理
# 1 提取音频 mp3
ffmpeg.exe -i .\周杰伦-稻香.mp4 -vn -c:a libmp3lame -q:a 1 .\周杰伦-稻香.mp3
# 2 音频格式由 mp3 转换为 ogg
ffmpeg.exe -i .\周杰伦-稻香.mp3 .\周杰伦-稻香.ogg
批量转换批处理见:
audio-converter.bat: https://gitee.com/luyaocf/dev_ops_scripts.git
官方说明:https://ffmpeg.org/ffmpeg.html#Audio-Options
3 FFmpeg 图片处理
3.1 编解码
- 1)批量转换编码
# ffmpeg -i in.jpg -vf scale=width:height out.png
set a=!cd!
for /f "delims=" %%i in ('dir /b /s "%a%\*png*"') do (
echo %%~nxi %%~ni_c.png
ffmpeg -i %%~nxi -vf scale=iw/2:ih/2 %%~ni_c.png
)
3.2 拼接图片
ffmpeg -i 1.jpg -i 2.jpg -filter_complex vstack out.jpg
3.3 图片合成视频
ffmpeg -r 1 -f image2 -i '(%d).jpg' -c:v libx265 -vf scale=-1:1280 -crf 17 -y o.mp4
-
-r 调整帧率:默认 25 帧,即每秒拼接 25 张图片。
-
-b:v 4M 调整视频码率:码率指每秒播放的数据量(bit)。如果图片比较大,则生成的视频较大;改变码率会影响到视频清晰度;h265 编码可以用更小的码率生成 h264 同等的视频质量。
-
-crf 调整视频质量:用来平衡视频质量和文件大小的参数。取值范围 0~51,默认 23,建议 17~28。
-
-c:v libx265 调整视频的编码格式:默认 h264。可以使用 h265 生成更小的。
- 可以使用 -c:v libvpx 或 -c:v libvpx-vp9 生成 v8 和 v9 编码的 webm 文件(默认低质量)
-
-vf scale=宽x高 调整视频分辨率:将宽或高设置为 -1 可以将其等比例缩放。
附录1:mediainfo.ps1
<##
# 通过 ffmpeg 查看视频信息
#>
# Clear-Variable 删除变量的值。
# Compare-object 比较两组对象。
# ForEach-Object 对输入对象集合中的每个项目执行操作。
# Get-childItem 在一个或多个指定位置获取项目和子项目。
# Invoke-commands 在本地和远程计算机上执行命令。
# Set-variable 设置变量的值。
# Start-Job 启动 Windows PowerShell 的后台作业。
# [Math] | Get-Member -Static 获取 Math 类中的静态方法
<##
# 安装 mediainfo 命令:
# winget search mediainfo
# winget install MediaArea.MediaInfo
#>
# $arg 表示命令行参数集合
foreach($arg in $args) {
# Write-Host $arg
$param = "
General; \n
Complete name : '%CompleteName%' \n
File size : %FileSize/String4%
"
$param = $param -replace '\r?\n?'
mediainfo --Inform=$param "$arg"
$param = "
Video;
Codec ID : %CodecID% \n
Codec ID/Info : %CodecID/Info% \n
Aspect ratio : %DisplayAspectRatio/String% \n
Width : %Width% \n
Height : %Height% \n
Frame rate : %FrameRate% \n
Duration : %Duration% \n
Duration : %Duration/String1%; \n
"
$param = $param -replace '\r?\n?'
mediainfo --Inform=$param "$arg"
$duration = mediainfo --Inform="Video;%Duration%" "$arg"
$frame_rt = mediainfo --Inform="Video;%FrameRate%" "$arg"
$frame = [Math]::Floor($duration / 1000 * $frame_rt)
Write-Host "Frame : $frame"
}