前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【FFmpeg】Filter 过滤器 ⑥ ( 九宫格画面拼接 | nullsrc 过滤器 | setpts 过滤器 | scale 过滤器 | 内置输入/输出流表示 )

【FFmpeg】Filter 过滤器 ⑥ ( 九宫格画面拼接 | nullsrc 过滤器 | setpts 过滤器 | scale 过滤器 | 内置输入/输出流表示 )

作者头像
韩曙亮
发布2024-05-24 10:20:10
860
发布2024-05-24 10:20:10
举报

在本博客中 , 通过一个九宫格案例 , 学习如何进行视频画面拼接 ;

九宫格画面拼接效果 :

博客资源下载地址 : 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 ;

然后进入命令行模式 , 进入上述目录 , 执行如下命令 , 即可生成九宫格画面拼接效果 ;’

代码语言:javascript
复制
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 命令 , 播放生成的 九宫格视频 文件 ;

二、命令涉及的过滤器简介


1、nullsrc 过滤器

nullsrc 过滤器 是 用于生成 空白视频帧 或者 指定大小的黑色视频帧 的 特殊过滤器 ;

一般使用场景是 :

  • 创建空白的视频片段
  • 作为视频合成中的一个空白源

在 九宫格画面拼接 命令中 , 使用 nullsrc=size=900x900[base] 参数 , 创建了一个 900x900 像素大小的 空白画布 , 将该画布命名为 base , 这个命名是一个任意字符串 , 也可以起其它的名字 ;

下面命令的作用是 , 创建一个 900x900 大小的空白黑色视频 , 视频时长是 10 秒 ;

代码语言:javascript
复制
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 输出文件 ,

2、setpts 过滤器

setpts 过滤器 是 用于调整视频帧的时间戳 的过滤器 ;

通过使用 setpts 过滤器 , 可以设置 视频播放 加速 , 减速 , 视频次序翻转效果 ;

setpts 过滤器 语法如下 :

代码语言:javascript
复制
setpts=expression
  • expression 参数值 是一个表达式 , 该表达式的作用是 计算新的时间戳 ;

上述 使用 表达式 , 计算新的时间戳时 , 可使用 内置参数 , 常用的 时间戳相关的内置参数变量有 :

  • PTS 内置参数 : 表示 每个 视频帧 的原始时间戳 ;
  • STARTPTS 内置参数 : 表示 第一个输入的视频帧的时间戳 ;

设置 setpts=0.5*PTS 过滤器参数值 , 其所用是将 当前的 每个视频帧的 原始时间戳 乘以 0.5 , 也就是原来 10 秒播放的视频 , 将要在 5 秒内播放完毕 , 其作用是 2 倍速度播放视频 ;

在 九宫格画面拼接 命令中 , 使用 [0:v]setpts=PTS-STARTPTS 参数 ,

  • [0:v] 表示 第一个输入文件的视频流 , 第一 对应的索引值就是 0 , 输入文件的索引值排序是从 0 开始的 ;
  • setpts=PTS-STARTPTS 参数值 表示 PTS ( 每个 视频帧 的原始时间戳 ) 减去 STARTPTS ( 第一个输入的视频帧的时间戳 ) , 得到一个插值 ;
  • 该设置 的 作用是 将 所有的 视频帧 的时间戳 都从 第一个视频帧的时间戳 开始计算 ;
  • 这样的计算方式 , 在 多个视频 合成 一个视频 时 , 可以确保合成后的视频中 , 每个视频画面的时间戳是连续的 ;

3、scale 过滤器

scale 过滤器 的 作用是 调整 视频帧大小 , 使用该过滤器 可以将视频帧的分辨率调整为指定的大小 ,

视频帧 的大小 , 可以放大 , 也可以缩小 ;

scale 过滤器 语法 :

代码语言:javascript
复制
scale=w:h
  • w 表示 要调整的 目标宽度 ;
  • h 表示 要调整的 目标高度 ;
  • w 和 h 的值 可以是 具体的像素值 , 也可以设置为 -1 , 设置为 -1 就会自动计算指定的 宽高值 , 自动保持宽高比 ;
  • 设置 scale=400:400 值 , 将视频的宽高设置为 400x400 像素 ;

将其中的一个值设置为 具体的像素值 , 另一个值设置为 -1 ;

  • 设置 scale=-1:400 值 , 是将高度设置为 400 像素 , 宽度设置为 -1 , 自动根据宽高比 和 高度 400 像素 计算出 对应的 宽度 ;

4、内置输入/输出流表示

在之前的 overlay 过滤器 中 , 使用到 [in] 表示输入文件 , 使用到 [out] 表示输出文件 ;

[0:v] 表示 第一个输入文件的视频流 , 该输入文件索引值为 0 ;

[1:v] 表示 第二个输入文件的视频流 , 该输入文件索引值为 1 ;

三、命令解析


1、命令分解

上述命令看似很多 , 但是可以分解成如下几个部分 :

第一部分 : ffmpeg 命令 , 所有的 ffmpeg 命令必须有的可执行程序名称 ;

代码语言:javascript
复制
ffmpeg 

第二部分 : 输入文件 , 设置了 9 个输入文件 , 这也是九宫格的组成部分 ;

代码语言:javascript
复制
-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 参数设置的 滤镜链 , 又称为 过滤器链 , 这是一个复杂的 过滤器 , 由多个过滤器组成 ; 将上述过滤器命令行代码按行分隔开 , 可分为如下四个部分 ;

代码语言:javascript
复制
-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

第四部分 : 输出文件 , 这个很简单 ;

代码语言:javascript
复制
output.mp4

上述命令中 , 只有第三部分的 滤镜链 , 比较复杂 , 其它命令参数都很简单 ;

2、设置输入文件 -i 参数

上述命令中 , -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 参数 , 是 本命令中最核心的内容 ;

3、设置复杂过滤器参数 -filter_complex 参数

ffmpeg 命令中的 -filter_complex 参数 用来 设置 一个由 " 多个过滤器 " 组成的 " 复杂过滤器 " , 又称为 " 过滤器链 / 滤镜链 " ,

该 " 过滤器链 " 可以在单行命令中同时应用多个过滤器效果 ,

在本示例 中 , 九个 视频流数据 在这些 过滤器之间 进行数据传递 , 实现了 九个视频画面 拼接成一个视频画面的效果 ;

在本示例中 , 该 " 过滤器链 " 使用了如下几个过滤器 :

  • nullsrc 过滤器 : 用于生成 空白视频帧 或者 指定大小的黑色视频帧 的 特殊过滤器 ;
  • setpts 过滤器 : 用于调整视频帧的时间戳 的过滤器 ;
  • scale 过滤器 : 用于调整 视频画面帧 大小的过滤器 ;
  • overlay 过滤器 : 用于 拼接 / 叠加 视频 / 图片 的过滤器 , 这也是本命令中的核心过滤器 ;

nullsrc=size=900x900[base]; 参数 表示 创建 900x900 像素的画布 , 命名为 base , 这是一个自定义字符串 ;

[0:v]setpts=PTS-STARTPTS,scale=300x300[vedio0] 参数 的作用 是

  • 将第 0 个输入文件的 视频流 的 每个视频帧 的 时间戳设置成 PTS ( 每个 视频帧 的原始时间戳 ) 减去 STARTPTS ( 第一个输入的视频帧的时间戳 ) , 确保多个视频文件的 时间戳 保持一致 ;
  • 将 视频帧 画面 转为 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] 是 叠加合成后的视频流 , 这是一个自定义名称 ;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、九宫格画面拼接
  • 二、命令涉及的过滤器简介
    • 1、nullsrc 过滤器
      • 2、setpts 过滤器
        • 3、scale 过滤器
          • 4、内置输入/输出流表示
          • 三、命令解析
            • 1、命令分解
              • 2、设置输入文件 -i 参数
                • 3、设置复杂过滤器参数 -filter_complex 参数
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档