梳理下 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 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 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

视频每秒截取一帧

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 表示加速

视频水印

在视频指定位置添加静态水印

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_wmain_h 表示视频宽高;

  • overlay_woverlay_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

去掉视频指定位置的水印

ffmpeg -i xxx.mp4 -vf delogo=x=80:y=800:w=100:h=100 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.1:0.2[ckout];[0:v][ckout]overlay[out]" output.mp4

其实绿幕就是将 alpha 为 0 的像素替换为特定颜色(一般为绿色),ffmpeg -colors 可查询 FFmpeg 支持的颜色。

这里核心是 chromakey 滤镜,三个参数分别为:

  • color: 绿幕背景色;

  • similarity: 相似度,范围 0 ~ 1;0 表示仅匹配前面指定的颜色,1 表示匹配一切颜色;

  • blend: 混合度,范围 0 ~ 1;0 表示要么完全透明,要么完全不透明;更高的值表示会有半透明的像素;

这个滤镜除了能处理视频,还能处理单张 YUV 图。

如果是 RGB 的图,需要用 colorkey

流媒体处理

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 项目。