OpenGL 实现视频编辑中的转场效果
转场介绍
转场效果是什么?
转场效果,简单来说就是两段视频之间的衔接过渡效果。
现在拍摄 vlog 的玩家越来越多,要是视频没有一两个炫酷的转场效果,都不好意思拿出来炫酷了。
那么如何在视频编辑软件中实现转场效果呢?
这里提供使用 OpenGL 实现视频转场的一个小示例,我们可以通过自定义 GLSL 来实现不同的转场效果。
以在 Android 平台上作为演示,但其实不管是 Android 还是 iOS,实现的原理都是一样的。
首先要有两段视频,视频 A 和视频 B,先播放视频 A 后播放视频 B,中间有一段过程称为 C ,C 就是视频 A、B 做转场动画的时间段。
如下所示:
播放器按照时间顺序,从 A -> C -> B 的播放,这样就有了转场的效果。
视频转场,首先就得有视频,直接从视频 A、B 中解码出当前帧并通过 OpenGL 显示到屏幕上就好了,如果你对这个操作不熟悉的话,可以查看我的公众号【纸上浅谈】历史文章,都有写过相关内容。
这里以图片来替代视频 A、B 中解码出来的帧。
最终效果如下:
实现讲解
模拟视频渲染播放
模拟 fps 为 30 的视频,用 RxJava 每间隔 30 ms 就触发一次 OpenGL 渲染。
Observable
.interval(30, TimeUnit.MILLISECONDS)
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe {
mGLSurfaceView.requestRender()
}
另外,如果在视频 A 播放阶段不断地改变图片,也就是更新纹理内容,就相当于在真实的解码视频进行播放了。
当然这些操作只是为了让这个小例子更加贴近真正的视频转场,重要的还是在于如何实现转场的 Shader 效果。
首先转场的时候要有两个纹理作为输入,那么肯定要定义两个 sampler2D
进行采样了。
varying vec2 vTextureCoord;//接收从顶点着色器过来的参数
uniform sampler2D sTexture1;
uniform sampler2D sTexture2;
其中 sTexture1
对应于视频 A 内容,sTexture2
对应于视频 B 内容。
vTextureCoord
对应于顶点着色器传递过来的纹理坐标,视频 A 和 视频 B 都需要用到这个纹理坐标。
这个时候,只要调用 texture2D 方法就能得到视频 A 和 视频 B 的内容了。
// 得到视频 A 的内容
texture2D(sTexture1,vTextureCoord)
// 得到视频 B 的内容
texture2D(sTexture2,vTextureCoord)
要注意的是这里说得到视频 A/B 的内容,是得到纹理坐标对应的图像内容。也就是说如果纹理坐标是 [0,1] 范围内,那么可以得到视频 A/B 的全部图像内容。如果坐标是 [-0.5,0.5] 那么只能采样得到一半内容了。
转场效果实现
混合函数 mix
由于转场效果是需要视频 A 和视频 B 进行叠加混合的,而 GLSL 内嵌了 mix
函数进行调用。
对于 GLSL 中有哪些内嵌的函数可以直接调用的,可以参考写过的文章记录:
mix
函数的声明如下:
genType mix(genType x,genType y,float a) // 其中 genType 泛指 GLSL 中的类型定义
它的主要功能是使用因子 a 对 x 与 y 执行线性混合,既返回 x * (1-a) + y * a
。
现在,通过 texture2D 能得到视频帧内容,通过 mix 能进行视频帧混合叠加,那么就可以得到最后转场视频帧了。
vec4 color = mix(texture2D(sTexture1,vTextureCoord),texture2D(sTexture2,vTextureCoord),a);
渲染进度控制
似乎到这里就可以大功告成了,实际上才刚刚完成了一半~~~
要知道转场效果是随着时间来播放的,就上面的例子中,转场时间内,一开始都是视频 A 的内容,然后视频 A 逐渐减少,视频 B 逐渐增多,到最后全是视频 B 内容,在我们的 Shader 中也要体现这个时间变化的概念。
在 Shader 中定义 progress
变量,代表转场的播放进度,进度为 0 ~ 1.0 之间。
uniform float progress;
同时在每一次渲染时更新 progress
变量的值。
GLES20.glUniform1f(muProgressHandle, mProgress);
当 progress
为 0 时代表转场刚刚开始,当 progress
为 1 时代表转场已经结束了。
if (mProgress >= 1.0f) {
mProgress = 0.0f;
} else {
mProgress += 0.01;
}
这里 progress
每次递增 0.01,完成一次转场就需要 100 次渲染,每次渲染间隔 30ms,那么一次转场动画就是 3000ms 了,当然这个可以自己调节的。
画面绘制
再回到 mix
函数的参数 a
,这个参数起到了随时间调节转场混合程度的作用。当 a = 0 时,全是视频 A 的内容, 当 a = 1 时,全是视频 B 的内容。
如上图所示,在转场动画的某一帧,左侧是视频 A 的内容,因为此时 a = 0,右侧是视频 B 的内容,此时 a = 1 。
可以看到在一次渲染绘制内 a 既要能等于 0 ,还要能等于 1 ,这个是怎么实现的呢?
事实上我们说的一次渲染绘制,通常指 OpenGL draw 方法的一次调用,但是在这一次调用里,还是有很多步骤要执行的。
OpenGL 渲染管线会先执行顶点着色器,然后光栅化,再接着就是片段着色器,片段着色器会根据纹理坐标采样纹理贴图上的像素内容进行着色,因此片段着色器在管线中会多次执行,针对每个像素都要进行着色。
上面图像的小方块就好比一个像素,每个像素都要执行一个片段着色器。
首先,肯定所有的像素都要进行着色的。左侧方块采样视频 A 的纹理进行着色,右侧方块采样视频 B 的纹理进行着色。
回到如下代码:
mix(texture2D(sTexture1,vTextureCoord),texture2D(sTexture2,vTextureCoord),a);
只要保证绘制左侧时 a = 0,绘制右侧时 a = 1 就行了。这里可以通过移动纹理坐标来控制 a 的值。
vec2 p = vTextureCoord + progress * sign(direction);
float a = step(0.0,p.y) * step(p.y,1.0) * step(0.0,p.x) * step(p.x,1.0);
OpenGL 中定义纹理坐标范围是 [0 ~ 1] ,可以将范围右移 0.5 ,从而变成 [0.5 ~ 1.5] ,此时纹理坐标一半位于规定范围内,一半超出界外了。
这样就可以通过对当前像素小方格对应的纹理坐标的 x,y 值运用 step
函数进行判断是否在界内,就可以决定是采样视频 A 还是视频 B 的图像了。
当每次刷新 progress 时,就向右移一小段距离,视频 A 随着右移而变少,视频 B 变多,这样就是实现了转场效果。
不知道这个简单的例子有没有让你想到些什么?
对的,没错,就是升职加薪,走向巅峰必备的 PPT 技能,这种视频转场的实现效果就和我们在编辑 PPT 动画时添加的一样。
而且这还是比较简单的,想要做一些花里胡哨的转场特效,缺少灵感就可以参考 PPT 里面的动画了。
另外,我们还可以对转场效果做一些总结分类,比如示例中用的是图片,可以理解成视频 A 的最后一帧显示与视频 B 的第一帧显示做转场效果,这种转场效果实际使用的人比较少,大多数是视频 A 的最后一帧与视频 B 的前一段时间的视频做转场效果。
因此也可以对转场效果做个分类:
- 视频 A 最后一帧与视频 B 第一帧做转场动画
- 视频 A 最后一帧与视频 B 前一段时间视频做转场动画
- 视频 A 最后一段时间视频 与视频 B 第一帧做转场动画
- 视频 A 最后一段时间视频 与视频 B 前一段时间视频做转场动画
这四个分类的实现原理其实都差不多,如果是一段视频的话,那么就在视频播放时更新对应纹理。
以上就在关于使用 OpenGL 在视频编辑中实现转场效果的讲解,通过这篇文章希望大家可以掌握转场的基本实现原理。
文中用到的代码示例,可以关注我的微信公众号【纸上浅谈】,回复 “转场” 即可~~~
推荐阅读
技术交流,欢迎加微信好友~~
欢迎关注微信公众号【纸上浅谈】,看更多音视频、OpenGL、多媒体开发文章
OpenGL 实现视频编辑中的转场效果的更多相关文章
- 如何用Vegas完成视频编辑中的自动跟踪换图
Vegas作为一款专业的视频剪辑软件,剪辑速度快捷,拥有各种实用工具和特效,同样也可以为用户实现视频换图的需求.今天小编就为大家讲解,如何利用Vegas自动跟踪进行换图,让视频能够更加便捷的呈现. 本 ...
- 如何让照片中的人物笑起来?HMS Core视频编辑服务一键微笑功能,让人物笑容更自然
最近一键"露齿笑"席卷全网,无论是短视频用户还是社交App用户都在使用这项黑科技.当三两好友聚会拍集体照留念时,为了处理个别人的表情"瑕疵",让大家都尽量保持微 ...
- 视频编辑SDK---我们只提供API,任你自由设计炫酷的功能
面对相对复杂的视频编辑处理技术,你是否束手无策? 在短视频应用中,有一定技术难度的视频编辑技术中,我们提出了一种全新的解决方法:画板和画笔.短视频处理,用画板和画笔,就够了! 我们设计了极其简单易懂的 ...
- android平台短视频技术之 视频编辑的经验分享.
android平台短视频技术之 视频编辑的经验分享. 提示一: 各位看官,这里分享的是视频编辑,即剪切/拼接/分离/合并/涂鸦/标记/叠加/滤镜等对视频的编辑操作.不是流媒体网络播放等功能,请注意. ...
- 马蜂窝视频编辑框架设计及在 iOS 端的业务实践
(马蜂窝技术公众号原创内容,ID: mfwtech) 熟悉马蜂窝的朋友一定知道,点击马蜂窝 App 首页的发布按钮,会发现发布的内容已经被简化成「图文」或者「视频」. 长期以来,游记.问答.攻略等图文 ...
- 用视频编辑软件打不开jpg格式的图片的解决方法
有时候我们把PSD.JPG等图片导入到素材库中会发现EDIUS视频编辑软件根本就不支持,显示黑屏状态.可是当我们把图片导入EDIUS NX支持下的premierepro里却能够正常显示.这是什么原因呢 ...
- LanSoEditor_advance1.8.0 视频编辑的高级版本
------------------------------------------2017年1月11日11:18:33------------------------------------- 我们 ...
- Android平台 视频编辑的高级版本
基本覆盖了秒拍,美拍,快手等视频编辑的大部分功能. 增加了44种滤镜,基本覆盖市面上大部分APP中的滤镜效果. 可以实现视频和视频, 视频和图片,视频和您的UI界面叠加. 在叠加的过程中:支持任意时间 ...
- LanSoEditor_common ---android平台的视频编辑SDK
当前版本是LanSoEditor-v1.4 主要使用在音视频的: 裁剪,剪切,分离,合并,转换,拼接,水印,叠加,混合,转码等场合; 我们是针对android平台对ffmpeg做了硬件加速优化,经过多 ...
随机推荐
- KVC解析
• 阅读 valueForKey (总体规划,先找相关方法,再找相关变量) 1.先是找相关方法,如果方法找不到 2.那么去判断 1 2 3 + (BOOL)accessInstanceVariab ...
- 花生壳的ddns 关键时刻又掉链子,准备迁到阿里万网
https://www.oray.com/news/affiche/?aid=628 免费版花生壳服务故障 因免费版机房线路节点负荷突然暴增,导致花生壳免费版登录缓慢或异常,或出现域名指向到127.0 ...
- ORs-5-OR Subgenomes Variation among Birds, Sea Turtle and Alligator
OR Subgenomes Variation among Birds, Sea Turtle and Alligator 由 该图数据计算每种鸟的relative percentage,得到下图: ...
- python使用geopandas和shapely处理shp文件
一.环境搭建 所需库:geopandas (以及前置库) doc:http://geopandas.org/ shapely(以及前置库) doc: 二.数据预处理 1.将shp文件进行切片 2. ...
- javaweb三大框架SSH
1.MVC三层架构:模型层,控制层和视图层.模型层,用Hibernate框架让来JavaBean在数据库生成表及关联,通过对JavaBean的操作来 对数据库进行操作:控制层,用Struts框架来连接 ...
- 使用httpclient必须知道的参数设置及代码写法、存在的风险
转发地址:http://jinnianshilongnian.iteye.com/blog/2089792 结论: 如果使用httpclient 3.1并发量比较大的项目,最好升级到httpclien ...
- HLS图像处理总结(一)
HLS工具 以个人的理解,xilinx将HLS(高层次综合)定位于更方便的将复杂算法转化为硬件语言,通过添加某些配置条件HLS工具可以把可并行化的C/C++的代码转化为vhdl或verilog,相比于 ...
- [LC] 379. Design Phone Directory
Design a Phone Directory which supports the following operations: get: Provide a number which is not ...
- Android开发之《制作自己的su文件》
目录结构 ─ hello ├── jni ├── Android.mk └── hello.c 编译步骤: # cd hello # export NDK_PROJECT_PATH=`pwd` # ...
- C++走向远洋——60(项目四、立体类族共有的抽象类)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...