梳理下 FFmpeg 的一些有用的命令
最近在探索图像处理类应用端到端耗时如何量化,最终方案是:
录视频 -> FFmpeg 分帧 -> 根据帧数量化耗时。
另外,平时自己从网上爬取 m3u8
视频,也会用到 FFmpeg。
所以,这里梳理下 FFmpeg 的一些比较有用的命令。
图片
格式转换
jpg -> yuv
ffmpeg -y -i x.jpg -pix_fmt nv21 x.yuv
yuv -> jpg
ffmpeg -f rawvideo -video_size 720x1280 -pix_fmt nv21 -i x.yuv x.jpg
编辑
缩放
ffmpeg -i in.jpg -vf scale=320:240 out.png
如果需要宽/高自适应缩放,传入 -1
即可;
背景透明
ffmpeg -i mask.png -vf 'colorkey=0xFFFFFF:similarity=0.5:blend=0' out.png
similarity
: 相似度,范围 [0, 1];0 表示仅匹配前面指定的颜色,1 表示匹配一切颜色;(一般 0.5 效果较好)blend
: 混合度,范围 [0, 1];0 表示要么完全透明,要么完全不透明;更高的值表示会有半透明的像素;
详见 colorkey
滤镜;
音频
调整音频参数
调整音频音量
ffmpeg -i input.wav -filter:a "volume=1.5" output.wav
调整音频码率
ffmpeg -i input.mp3 -b:a 400k output.mp3
调整音频采样率
ffmpeg -i input.mp3 -ar 44100 output.mp3
其他
音频截取
ffmpeg -i in.mp3 -ss 00:01:30 -to 00:02:30 -c copy out.mp3
给音频添加封面
ffmpeg -i input.mp3 -i cover.png -c copy -metadata:s:v title="Album cover" -metadata:s:v comment="Cover.." out.mp3
音频 -> 波形图
ffmpeg -i x.mp3 -filter_complex "showwavespic=s=640x240:split_channels=1" -frames:v 1 wave.png
动画
GIF
图片序列 -> gif
ffmpeg -f image2 -framerate 5 -i x-%3d.jpg x.gif
x-%3d
表示 jpg 图片名都是x-
前缀,后跟三位数字。
视频 -> gif
ffmpeg -i x.mp4 -r 15 drawtext="enable='between(t,10,5*60)': text='我是字幕': x=(w-text_w)/2: y=(h-text_h-10) fontfile=/usr/share/fonts/xxx.ttf fontcolor=white: fontsize=15: shadowcolor=black@0.5: shadowx=2: shadowy=2:" x.gif
-r 15
:帧率,跟动画连续性、文件大小都正相关;enable='between(t,10,5*60)'
:从第 10 秒开始,5 分钟结束;x=(w-text_w)/2: y=(h-text_h-10)
:文字位置(水平居中,距底部 10 像素);
视频
视频合成
图片序列 -> 视频
ffmpeg -r 5 -i x-%3d.jpg -c:v libx264 -vf fps=25 -pix_fmt yuv420p xxx.mp4
图片序列+音频 -> 视频
ffmpeg -loop 1 -t 6 -i x-%3d.jpg -i x.mp3 -c:v libx264 -c:a aac -b:a 192k -shortest xxx.mp4
音频与视频混合
ffmpeg -i xxx.wav -i xxx.avi xyz.mp4
视频序列合并
ffmpeg -f concat -i list.txt -c copy x.mp4
list.txt 每行记录一个视频:
file ‘1.mp4’
file ‘2.mp4’
file ‘3.mp4’
...
视频提取图
视频 -> 图片序列
ffmpeg -t 10 -i x.mp4 -r 15 -s 272x352 -f image2 x-%03d.jpg
截取视频某时刻的帧
ffmpeg -i x.mp4 -ss 00:00:03.210 -vframes 1 x.png
同时使用 blackframe
滤镜可过滤黑色的帧:
ffmpeg -ss 0 -i input.mp4 -vframes 1 -f image2 -vf "blackframe=0,metadata=select:key=lavfi.blackframe.pblack:value=50:function=less" out.jpg
视频每秒截取一帧
ffmpeg -i x.mp4 -vf fps=1 x-%d.png
视频提取音频
去除视频里的音频
ffmpeg -i input.mp4 -an output.mp4
导出视频里的音频
ffmpeg -i xxx.avi -vn -ar 44100 -ac 2 -ab 192k -f mp3 xxx.mp3
视频提取视频
视频片段截取
ffmpeg -i x.mp4 -ss 00:00:03 -t 00:00:08 -async 1 xxx.mp4
注意:
t
是时长,不是结束时间!
视频裁剪
ffmpeg -i input.mp4 -filter:v "crop=w:h:x:y" output.mp4
视频参数修改
调整视频分辨率
ffmpeg -i input.mp4 -s 320x240 output.mp4
调整视频码率
ffmpeg -i input.mp4 -b:v 400k output.mp4
调整视频中音频播放速度
ffmpeg -i input.mp4 -filter:a "atempo=2.0" -vn output.mp4
atempo
取值为 0.5-2.0;
调整视频播放速度
ffmpeg -i video.mpg -vf "setpts=0.5*PTS" highspeed.mpg
- PTS 倍数 < 1 表示加速;
视频水印
给视频添加静态水印
添加水印主要是使用 overlay
滤镜:
ffmpeg -i x.mp4 -i logo.png -filter_complex "overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2" xxx.mp4
mian_w
、main_h
表示视频宽高;overlay_w
、overlay_h
表示水印图宽高;通过
enable='between(t,0,20)'
可指定水印出现的时间;
给视频添加移动水印
ffmpeg -i x.mp4 -i logo.png -filter_complex "overlay='if(gte(t,1), -w+(t-1)*200, NAN)':'if(gte(t,1), -h+(t-1)*200, NAN)'" xxx.mp4
去掉视频的水印
去水印主要是使用 delogo
滤镜,enable
可以指定运用的时间范围:
ffmpeg -i input.mp4 -vf "delogo=x=12:y=34:w=353:h=93:enable='between(t,5,10)'" -c:a copy output.mp4
也可以同时指定多个区域,声明多个 delogo
滤镜即可:
ffmpeg -i input.mp4 -vf "delogo=x=56:y=78:w=353:h=93:enable='between(t,5,10)',delogo=x=100:y=24:w=100:h=72:enable='between(t,15,20)'" -c:a copy output.mp4
视频背景音乐
给视频添加背景音乐
ffmpeg -i input.mp4 -i bg.mp3 -filter_complex "[1:a]aloop=loop=-1:size=2e+09[out];[out][0:a]amix" -t 10 out.mp4
替换原视频中的音频
ffmpeg -i video.mp4 -i audio.wav -map 0:v -map 1:a -c:v copy -shortest output.mp4
-map
:选择 input 中的哪条流进入 output;-shortest
:输出时长以输入时长最小的为准;
给视频添加背景音乐
ffmpeg -i video.mkv -i audio.mp3 -map 0 -map 1:a -c:v copy -shortest output.mkv
绿幕视频
绿幕合成
ffmpeg -i origin.mp4 -i green_bg.mp4 -filter-complex "[1:v]chromakey=Green:0.5:0.2[ckout];[0:v][ckout]overlay[out]" output.mp4
绿幕合成就是将 alpha 为 0 的像素替换为特定颜色(一般为绿色),ffmpeg -colors
可查询 FFmpeg 支持的颜色。
这里核心是 chromakey
滤镜,参数与 colorkey
滤镜类似;
这个滤镜除了能处理视频,还能处理单张 YUV 图。
如果是 RGB 的图,需要用 colorkey
滤镜。
绿幕剔除
ffmpeg -i input.mp4 -vf 'colorkey=0x00FF00:similarity=0.5:blend=0.3' -c copy -c:v vp9 -f webm output.webm
跟图片透明背景类似,这里同样使用 colorkey
滤镜,相关参数不再赘述;
输出格式指定为 webm
,是因为它支持 alpha 通道视频。
视频特效
淡入淡出
fade
滤镜可以实现视频淡入淡出的特效,而 afade
滤镜则用于音频:
ffmpeg -i x.mov -vf "fade=t=in:st=0:d=2, fade=t=out:st=6:d=2" -af "volume=2.0, afade=t=in:st=0:d=2, afade=t=out:st=6:d=2" -c:v libx264 -c:a aac -b:a 128k xxx.mp4
t=in
表示淡入特效,t=out
表示淡出特效;st=0
表示特效开始时间,d=2
表示特效持续时长;
流媒体处理
m3u8 下载
ffmpeg -protocol_whitelist file,http,https,tcp,tls,crypto -i "http://abc.com/xxx.m3u8" -c copy xxx.mp4
格式转换
VCD -> mp4
ffmpeg -i x.VOB x.mp4
.
.
.
广告时间
通过组合上面的命令,可实现一些小工具,如:自制表情包,小视频下载,视频提取音乐、视频编辑等。
有兴趣的可以参考下我的 Videa 项目。