FFMPEG命令
本文是我学习ffmpeg命令时,整理的笔记,所以摘抄居多。
常用参数
- -y (global) : 直接覆盖输出文件
- -n (global) : 如果指定的输入文件已经存在,不要覆盖输出文件,直接退出
合并视频和音频
这里的合并意思是要保留视频的原始声音。
方法一:混合到一起
ffmpeg -i input.mp4 -i input.wav -filter_complex "amix=inputs=2:duration=shortest:dropout_transition=2" -f mp4 remix.mp4
解释:
- -i代表输入参数
- -filter_complex
- amix是混合多个音频到单个音频输出
- inputs=2代表是2个音频文件,如果更多则代表对应数字
- duration 确定最终输出文件的长度:longest(最长)|shortest(最短)|first(第一个文件)
- dropout_transition 转换时间,以秒为单位,在输入流结束时用于重新格式化卷。缺省值是2秒。
- -f mp3 输出文件格式
方法二:
视频缩放
任意分辨率缩放
- vf表示视频过滤器(video filter)
ffmpeg -i input.mp4 -vf scale=w=200:h=100 out.mp4
指定原宽高进行缩放
该操作中由于宽高比和原来的视频不同,会造成像素的宽高比不同
如果想要保持原来的宽高比,可以传递-1作为参数,使用iw
(input width)和ih
分别表示原来视频的宽度和高度。
如下指令生成的视频的宽度为原来的1.5倍,但是限制视频的最大宽度为5000像素。
# 宽度为原先的1.5倍数,高度指定为1280
ffmpeg -i input.mp4 -vf scale=w='iw*1.5':h=1280 out.mp4
# 宽度放大2倍,高度等比缩放
ffmpeg -i input.mp4 -vf scale=w='iw*2':h=-1 out.mp4
视频裁剪
裁剪的意思就是从原来的视频中截取矩形区域生成新视频,需要用到crop过滤器
- iw表示输入视频的宽度
- ih表示输入视频的高度
- ow表示输出视频的宽度
- oh表示输出视频的高度
- x表示水平位置,默认数值为(ih - oh) / 2
- y表示竖直位置,默认数值为(ih - oh) / 2
它可以把视频从指定的x、y位置裁剪成指定的w、h。坐标系是基于左上点开始的。·
# 宽500,高500,左上角从(120,340)
ffmpeg -i input.mp4 -vf crop=w=500:h=500:x=120:y=340 out_crop.mp4
文字水印
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100:text='HELLO WORLD':x=20:y=20" out_text.mp4
也可以指定字体文件
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100:fontfile=FreeSerif.ttf:text='HELLO WORLD':x=20:y=20" out_text.mp4
指定文字颜色背景
ffmpeg -i input.mp4 -vf "drawtext=fontsize=100:text='HELLO WORLD':x=20:y=20:fontcolor=blue:box=1:boxcolor=yellow" out_text.mp4
复杂滤镜
FFMPEG滤镜Filter的参数排列方式为:
[输入流或标记名]滤镜参数[临时标记名];[输入流或标记名]滤镜参数[临时标记名]···
比如说:输入两个文件,一个视频input.mp4,一个图片logo.png,将logo进行缩放,然后放在视频的左上角:
ffmpeg -i input.mp4 -i logo.png -filter_complex "[1:v]scale=100:100[logo];[0:v][logo]overlay=x=0:y=0" output.mp4
将logo.png的图像流缩放为176×144的分辨率,然后定义一个临时标记名logo,最后将缩放后的图像[logo]铺在输入的视频input.mp4的视频流[0:v]的左上角。
- 针对简单滤镜图的选项:
-vf
等同-filter:v
,-af
等同-filter:a
- 针对复杂滤镜图的选项:
-lavfi
等价于-filter_complex
ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
上例中 split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2
是复杂滤镜图,由三个滤镜链构成(分号分隔)
- 第二个滤镜链
[tmp] crop=iw:ih/2:0:0, vflip [flip]
由两个滤镜构成(逗号分隔)。 - 第一个滤镜链中:滤镜 split 产生两个输出 [main] 和 [tmp]
- 第二个滤镜链中:[tmp] 作为 crop 滤镜的输入,[flip] 作为 vflip 滤镜的输出,crop 滤镜输出连接到 vflip 滤镜的输入;
- 第三个滤镜链中:[main] 和 [flip] 作为 overlay 滤镜的输入。
整行命令实现的功能是:将输入分隔为两路,其中一路经过裁剪和垂直翻转后,再与另一路混合,生成输出文件。示意图如下所示:
input --> split ----------------------> overlay --> output
| ^
| [tmp] [flip] |
+------> crop --> vlip --------+
滤镜图中的连接标号
在滤镜图中可以使用连接标号(link lable),连接标号表示特定滤镜/滤镜链的输入或输出
例如,我们想要把一个经过降噪处理后的输出文件与输入原文件进行比较,如果不使用带连接标号的滤镜图,我们需要至少两条命令:
hqdn3d
视频降噪
ffmpeg -i input.mp4 -vf hqdn3d,pad=2*iw output.mp4`
ffmpeg -i output.mp4 -i input.mpg -filter_complex overlay=w compare.mp4
如果使用带有连接标号的滤镜图,则一条命令就可以了:
ffmpeg -i input.mp4 -vf "split[a][b];[a]pad=2*iw[A];[b]hqdn3d[B];[A][B]overlay=w" compare.mp4
图片水印
ffmpeg -i input1.mp4 -vf "movie=logo.png[wm];[in][wm]overlay=30:10[out]" out_pic_mask.mp4
画面叠加 overlay
图片水印,也可以通过画面叠加overlay实现,不过overlay还可以实现只展示一部分时间的水印。
overlay技术又称视频叠加技术。overlay视频技术使用非常广泛,常见的例子有,电视屏幕右上角显示的电视台台标,以及画中画功能,画中画是指在一个大的视频播放窗口中还存在一个小播放窗口,两个窗口不同的视频内容同时播放。
overlay技术中涉及两个窗口,通常把较大的窗口称作背景窗口,较小的窗口称作前景窗口,背景窗口或前景窗口里都可以播放视频或显示图片。FFmpeg中使用overlay滤镜可实现视频叠加技术。
overlay滤镜说明如下:
描述:前景窗口(第二输入)覆盖在背景窗口(第一输入)的指定位置。
语法:overlay[=x:y[[:rgb={0, 1}]] 参数x和y是可选的,默认为0。rgb参数是可选的,其值为0或1,默认为0。
参数说明:
x 从左上角的水平坐标,默认值为0
y 从左上角的垂直坐标,默认值为0
rgb 值为0表示输入颜色空间不改变,默认为0;值为1表示将输入的颜色空间设置为RGB
变量说明:如下变量可用在x和y的表达式中
main_w或W 主输入(背景窗口)宽度
main_h或H 主输入(背景窗口)高度
overlay_w或w overlay输入(前景窗口)宽度
overlay_h或h overlay输入(前景窗口)高度
overlay命令行基本格式如下:
ffmpeg -i input1 -i input2 -filter_complex overlay=x:y output
直接叠加图标
- 将图标叠加于视频右上角
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w:0 -max_muxing_queue_size 1024 video_with_logo.mp4
- 将图标叠加于视频右下角
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w:H-h -max_muxing_queue_size 1024 video_with_logo.mp4
- 延时叠加图标
如下,背景窗口播放3.5秒后,图标开始显示。注意-itsoffset 3.5
作为第二个输入文件的输入选项,参数位置不能放错。
ffmpeg -i input.mp4 -itsoffset 3.5 -i logo.png -filter_complex overlay=W-w:0 -max_muxing_queue_size 1024 video_with_logo_delay.mp4
视频中叠加视频——画中画
视频中叠加视频即为画中画功能。
注意两个视频仅图像部分会叠加在一起,声音是不会叠加的,有一个视频的声音会消失。
ffmpeg -re -i main.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay[out]" pic_in_pic.mp4
-re 参数控制读取 AVpacket 的速度,按照帧率速度读取文件 AVpacket。如果有多个流,以最慢的帧率为准。
还可以指定叠加的视频在背景视频的位置
ffmpeg -re -i main.mp4 -vf "movie=sub.mp4,scale=480x320[test];[in][test]overlay=x=main_w-480:y=main_h-320[out]" pic_in_pic.mp4
视频多宫格处理
ffmpeg -re -i input1.mp4 -re -i input2.mp4 -re -i input3.mp4 -re -i input4.mp4 -filter_complex "nullsrc=size=640x480[base];[0:v]setpts=PTS-STARTPTS,scale=320x240[upperleft];[1:v]setpts=PTS-STARTPTS,scale=320x240[upperright];[2:v]setpts=PTS-STARTPTS,scale=320x240[lowerleft];[3:v]setpts=PTS-STARTPTS,scale=320x240[lowerright];[base][upperleft]overlay=shortest=1[temp1];[temp1][upperright]overlay=shortest=1:x=320[temp2];[temp2][lowerleft]overlay=shortest=1:y=240[tmp3];[tmp3][lowerright]overlay=shortest=1:x=320:y=240" -c:v libx264 four_in_one.mp4
可通过nullsrc创建一个overlay画布,画布的大小为宽640像素、高480像素,使用[0:v]
/[1:v]
/[2:v]
/[3:v]
将输入的4个视频流去除,分别进行缩放处理,处理为宽320、高240的视频,然后基于nullsrc生成的画布进行视频平铺
其他示例
- 将overlay绘制在主视频的右下角
overlay=main_w-overlay_w-10:main_h-overlay_h-10
- 视频上有两张不同的透明背景图片
ffmpeg -i input.mp4 -i logo1.png -i logo2.png -filter_complex 'overlay=x=10:y=H-h-10,overlay=x=W-w-10:y=H-h-10' two_images.mp4
- 将原视频与增加晃动特效的原视频并排合成
ffmpeg -i input.mp4 -vf 'split[a][b]; [a]pad=iw*2:ih[src]; [b]deshake[filt]; [src][filt]overlay=w' shake_video.mp4
音视频变速
在音视频处理中,常见的处理还包括音视频的倍速处理,如2倍速播放、4倍速播放,常见的处理方式包含跳帧播放与不跳帧播放,两种处理方式FFmpeg均可支持,跳帧处理方式的用户体验稍差一些,
本节将重点介绍不跳帧的倍速播放,例如音频倍速播放将会很平滑、很快速或者很慢速地播放音频,视频倍速播放将会很快速地播放视频或者很慢速地播放视频而非丢帧
修改视频速率
变速视频原理:修改视频的pts,dts
- 视频变为2倍速
ffmpeg -i input.mp4 -an -filter:v "setpts=0.5*PTS" output.aac
增加an可以去掉视频
注意:
- 调整速度倍率范围
[0.25, 4]
- 如果只调整视频的话最好把音频禁掉
- 对视频进行加速时,如果不想丢帧,可以用
-r
参数指定输出视频FPS
修改音频速率
变速音频原理:简单的方法是调整音频采样率,但是这种方法会改变音色,一般采用通过对原音进行冲采样,差值等方法
ffmpeg -i input.mp4 -filter:a "atempo=2.0" -vn output.mp4
注意:
- 倍率调整范围为[0.5, 2.0]
如果需要调整4倍可采用以下方法:
ffmpeg -i input.mp4 -filter:a "atempo=2.0,atempo=2.0" -vn output.mp4
音频视频同时变速
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4
绘制音频波形
- 绘制单声道波形
ffmpeg -i input.wav -filter_complex "showwavespic=s=640x120" -frames:v 1 audio_wave.png
- 绘制多声道波形
ffmpeg -i input.wav -filter_complex "showwavespic=s=640x240:split_channels=1" -frames:v 1 multi_out.mp4
视频背景替换
背景颜色可以根据ffmpeg -colors查询颜色支持,这个背景颜色为绿色,那么可以设置透明色部分为绿色,下面使用chromakey滤镜将绿色背景中的人物抠出来,然后贴到以input.mp4为背景的视频中:
ffmpeg -i input1.mp4 -i input_2.mp4 -filter_complex "[1:v]chromakey=Green:0.1:0.2[ckout];[0:v][ckout]overlay[out]" - map "[out]" green_back.mp4
定时截图
视频播放时,经常会看到一个功能,那就是将鼠标移动到播放器进度条上时,播放器中会弹出一个与进度条的进度相对应的缩略图;还有一个场景,当在主播平台中打开首页时,会列出主播当前窗口的缩略图;还有一个比较符合实际场景的应用的功能,例如鉴黄,当主播在直播视频时,定期截取主播窗口的当前图像,并将图像转为图片上传至鉴黄系统进行鉴别等。以上场景均要用到截图功能。
ffmpeg里最常用到的截图方法是使用vframe
参数和fps
滤镜。
vframes截取一张图片
ffmpeg -i input1.mp4 -ss 00:00:07 -vframes 1 one_frame.png
fps滤镜当时获得图片
在直播场景中,需要定义每隔一段时间就从视频中截取图像生成图片以作他用,例如上传至鉴黄中心,例如为进度条做缩略图等.
# 每秒钟截一张图
ffmpeg -i input1.mp4 -vf fps=1 frame_%d.png
ffmpeg -i input1.mp4 -vf fps=1/5 frame_%d.png
查看媒体信息工具probe
- 通过
ffprobe -of flat -show_streams input.flv
输出FLAT格式: - 通过
ffprobe -of json -show_packets input.flv
输出JSON格式 - 通过
ffprobe -of csv -show_packets input.flv
输出CSV格式
通过各种格式的输出,可以使用对应的绘图方式绘制出可视化图形。CSV格式输出后可使用Excel打开表格形式,将表格中的数据以图形的方式绘制出来。
参考
- 使用ffmpeg进行放大和缩小视频用的是scale过滤器
- FFmpeg使用基础(音视频开发入门)
- FFmpeg中overlay滤镜用法-水印及画中画
- overlay
- ffmpeg音视频加速
- 利用FFmpeg合并音频和视频