在本博客中 , 通过一个九宫格案例 , 学习如何进行视频画面拼接 ;
九宫格画面拼接效果 :
博客资源下载地址 : https://download.csdn.net/download/han1202012/89320137 , 本博客的视频资源 ;
准备 9 个输入文件 , 分别命名为 1.mp4 , 2.mp4 , 3.mp4 , 4.mp4 , 5.mp4 , 6.mp4 , 7.mp4 , 8.mp4 , 9.mp4 ;
然后进入命令行模式 , 进入上述目录 , 执行如下命令 , 即可生成九宫格画面拼接效果 ;’
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -i 5.mp4 -i 6.mp4 -i 7.mp4 -i 8.mp4 -i 9.mp4 -filter_complex "nullsrc=size=900x900[base];[0:v]setpts=PTS-STARTPTS,scale=300x300[vedio0];[1:v]setpts=PTS-STARTPTS,scale=300x300[vedio1];[2:v]setpts=PTS-STARTPTS,scale=300x300[vedio2];[3:v]setpts=PTS-STARTPTS,scale=300x300[vedio3];[4:v]setpts=PTS-STARTPTS,scale=300x300[vedio4];[5:v]setpts=PTS-STARTPTS,scale=300x300[vedio5];[6:v]setpts=PTS-STARTPTS,scale=300x300[vedio6];[7:v]setpts=PTS-STARTPTS,scale=300x300[vedio7];[8:v]setpts=PTS-STARTPTS,scale=300x300[vedio8];[base][vedio0]overlay=shortest=1:x=0:y=0[tmp1];[tmp1][vedio1]overlay=shortest=1:x=0:y=300[tmp2];[tmp2][vedio2]overlay=shortest=1:x=0:y=600[tmp3];[tmp3][vedio3]overlay=shortest=1:x=300:y=0[tmp4];[tmp4][vedio4]overlay=shortest=1:x=300:y=300[tmp5];[tmp5][vedio5]overlay=shortest=1:x=300:y=600[tmp6];[tmp6][vedio6]overlay=shortest=1:x=600:y=0[tmp7];[tmp7][vedio7]overlay=shortest=1:x=600:y=300[tmp8];[tmp8][vedio8]overlay=shortest=1:x=600:y=600" output.mp4
执行效果如下 : 上述命令 , 将九个 输入 视频文件 , 拼接到了一个输出文件中 , 执行效果如下图所示 ;
左侧命令行窗口中就是执行的命令 , 另起一个窗口 , 执行 ffplay output.mp4
命令 , 播放生成的 九宫格视频 文件 ;
nullsrc 过滤器 是 用于生成 空白视频帧 或者 指定大小的黑色视频帧 的 特殊过滤器 ;
一般使用场景是 :
在 九宫格画面拼接 命令中 , 使用 nullsrc=size=900x900[base]
参数 , 创建了一个 900x900 像素大小的 空白画布 , 将该画布命名为 base , 这个命名是一个任意字符串 , 也可以起其它的名字 ;
下面命令的作用是 , 创建一个 900x900 大小的空白黑色视频 , 视频时长是 10 秒 ;
ffmpeg -f lavfi -i nullsrc=900x900 -t 10 output.mp4
-f lavfi
参数的作用是 指定输入文件的格式为 lavfi 输入设备 , 该设备是 FFmpeg 的内置滤镜 ;-i nullsrc=900x900
参数的作用是 指定 lavfi 输入设备 的参数 , 这里设置为 画面分辨率为 900x900 像素 ;-t 10
参数 指定 lavfi 输入设备 生成 10 秒的 黑色视频 ;执行上述命令后 , 生成一个 output.mp4 输出文件 ,
setpts 过滤器 是 用于调整视频帧的时间戳 的过滤器 ;
通过使用 setpts 过滤器 , 可以设置 视频播放 加速 , 减速 , 视频次序翻转效果 ;
setpts 过滤器 语法如下 :
setpts=expression
上述 使用 表达式 , 计算新的时间戳时 , 可使用 内置参数 , 常用的 时间戳相关的内置参数变量有 :
设置 setpts=0.5*PTS
过滤器参数值 , 其所用是将 当前的 每个视频帧的 原始时间戳 乘以 0.5 , 也就是原来 10 秒播放的视频 , 将要在 5 秒内播放完毕 , 其作用是 2 倍速度播放视频 ;
在 九宫格画面拼接 命令中 , 使用 [0:v]setpts=PTS-STARTPTS
参数 ,
[0:v]
表示 第一个输入文件的视频流 , 第一 对应的索引值就是 0 , 输入文件的索引值排序是从 0 开始的 ;setpts=PTS-STARTPTS
参数值 表示 PTS ( 每个 视频帧 的原始时间戳 ) 减去 STARTPTS ( 第一个输入的视频帧的时间戳 ) , 得到一个插值 ;scale 过滤器 的 作用是 调整 视频帧大小 , 使用该过滤器 可以将视频帧的分辨率调整为指定的大小 ,
视频帧 的大小 , 可以放大 , 也可以缩小 ;
scale 过滤器 语法 :
scale=w:h
scale=400:400
值 , 将视频的宽高设置为 400x400 像素 ;将其中的一个值设置为 具体的像素值 , 另一个值设置为 -1 ;
scale=-1:400
值 , 是将高度设置为 400 像素 , 宽度设置为 -1 , 自动根据宽高比 和 高度 400 像素 计算出 对应的 宽度 ;在之前的 overlay 过滤器 中 , 使用到 [in]
表示输入文件 , 使用到 [out]
表示输出文件 ;
[0:v]
表示 第一个输入文件的视频流 , 该输入文件索引值为 0 ;
[1:v]
表示 第二个输入文件的视频流 , 该输入文件索引值为 1 ;
上述命令看似很多 , 但是可以分解成如下几个部分 :
第一部分 : ffmpeg 命令 , 所有的 ffmpeg 命令必须有的可执行程序名称 ;
ffmpeg
第二部分 : 输入文件 , 设置了 9 个输入文件 , 这也是九宫格的组成部分 ;
-i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -i 5.mp4 -i 6.mp4 -i 7.mp4 -i 8.mp4 -i 9.mp4
第三部分 : 使用 -filter_complex
参数设置的 滤镜链 , 又称为 过滤器链 , 这是一个复杂的 过滤器 , 由多个过滤器组成 ; 将上述过滤器命令行代码按行分隔开 , 可分为如下四个部分 ;
-filter_complex
nullsrc=size=900x900[base];
[0:v]setpts=PTS-STARTPTS,scale=300x300[vedio0];
[1:v]setpts=PTS-STARTPTS,scale=300x300[vedio1];
[2:v]setpts=PTS-STARTPTS,scale=300x300[vedio2];
[3:v]setpts=PTS-STARTPTS,scale=300x300[vedio3];
[4:v]setpts=PTS-STARTPTS,scale=300x300[vedio4];
[5:v]setpts=PTS-STARTPTS,scale=300x300[vedio5];
[6:v]setpts=PTS-STARTPTS,scale=300x300[vedio6];
[7:v]setpts=PTS-STARTPTS,scale=300x300[vedio7];
[8:v]setpts=PTS-STARTPTS,scale=300x300[vedio8];
[base][vedio0]overlay=shortest=1:x=0:y=0[tmp1];
[tmp1][vedio1]overlay=shortest=1:x=0:y=300[tmp2];
[tmp2][vedio2]overlay=shortest=1:x=0:y=600[tmp3];
[tmp3][vedio3]overlay=shortest=1:x=300:y=0[tmp4];
[tmp4][vedio4]overlay=shortest=1:x=300:y=300[tmp5];
[tmp5][vedio5]overlay=shortest=1:x=300:y=600[tmp6];
[tmp6][vedio6]overlay=shortest=1:x=600:y=0[tmp7];
[tmp7][vedio7]overlay=shortest=1:x=600:y=300[tmp8];
[tmp8][vedio8]overlay=shortest=1:x=600:y=600
第四部分 : 输出文件 , 这个很简单 ;
output.mp4
上述命令中 , 只有第三部分的 滤镜链 , 比较复杂 , 其它命令参数都很简单 ;
上述命令中 , -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -i 5.mp4 -i 6.mp4 -i 7.mp4 -i 8.mp4 -i 9.mp4
部分 , 设置了 9 个输入文件 , 这九个输入文件就是对应的 九宫格 中的 9 个拼接视频的文件 , 也是目录下的 9 个视频文件 ;
在本博客的绑定资源中 , 可以下载这九个文件 , 这些文件的分辨率都是 500x500 , 因此将其尺寸压缩成 300x300 , 宽高比也不会失衡 ;
在 后面的 -filter_complex 参数 , 是 本命令中最核心的内容 ;
ffmpeg 命令中的 -filter_complex 参数 用来 设置 一个由 " 多个过滤器 " 组成的 " 复杂过滤器 " , 又称为 " 过滤器链 / 滤镜链 " ,
该 " 过滤器链 " 可以在单行命令中同时应用多个过滤器效果 ,
在本示例 中 , 九个 视频流数据 在这些 过滤器之间 进行数据传递 , 实现了 九个视频画面 拼接成一个视频画面的效果 ;
在本示例中 , 该 " 过滤器链 " 使用了如下几个过滤器 :
nullsrc=size=900x900[base];
参数 表示 创建 900x900 像素的画布 , 命名为 base , 这是一个自定义字符串 ;
[0:v]setpts=PTS-STARTPTS,scale=300x300[vedio0]
参数 的作用 是
[base][vedio0]overlay=shortest=1:x=0:y=0[tmp1]
参数的作用是 将视频进行叠加 ,
[base][vedio0]
表示 将 base 画布 与 vedio0 视频流 进行合并 , vedio0 视频流 在 画布的上方 ;shortest=1
表示只要有一个视频流播放完毕 , 整体视频就会暂停 ;x=0:y=0
表示 vedio0 的 叠加 位置 在 base 画布的 (0, 0) 位置 ;[tmp1]
是 叠加合成后的视频流 , 这是一个自定义名称 ;