咱们好,我是苍王。
上一篇给咱们介绍了咱们近来开发视频特效结构YYEVA项目。这编给咱们持续深化介绍一下。

YYEVA(YY Effect Video Animate)是一个开源的支撑可刺进动态元素的MP4动效播映器解决计划,包含规划资源输出的AE扩展,客户端烘托引擎,在线预览工具。

比照传统的序列帧的动画播映方法,具有更高的紧缩率,硬解码效率更高的长处,一起支撑刺进动态的事务元素;比照SVGA、Lottie等播映器,支撑更多的特效支撑,如复杂3D作用、描边、粒子作用等,达到所见即所得的作用。

咱们发布项目现已有数月,也有许多朋友加入了咱们的社群提出一些优化计划,咱们连续在支撑。也欢迎咱们到 github给咱们点个⭐⭐⭐,您的Star是对咱们最大的支撑。

从这篇开始,咱们连续会发布四篇文章,别离给咱们介绍下,YYEVA-SDK是怎么解析YYEVA资源,并结合动态元素烘托到屏幕上的。现在,就让咱们开始YYEVA烘托之旅吧。

out.gif

YYEVA-Android 接入

  • 运用Gradle装置依赖:
allprojects {
	repositories {
		maven { url 'https://jitpack.io' }
	}
}
  • 对应的Module添加:
dependencies {
	implementation 'com.github.yylive.YYEVA-Android:yyeva:1.0.17'
}
// 2.0.0-beta版别
dependencies {
    implementation 'com.github.yylive.YYEVA-Android:yyeva:2.0.0-beta'
}

稳定版最新版别是1.0.17,新加入了一些如加快播映,列表播映示例。

beta版别仍是2.0.0-beta版别,支撑多进程播映,可是暂时还没兼容稳定版的一些新功能。

假如想看到Android端对应的源码能够点击这儿。

YYEVA-Android 完成之旅

RGB+Alpha混合原理

MP4视频以H264方法编码视频,MPEG-4的颜色采样标准是YUV,YUV是亮度和色度的分量叠加,不支撑alpha通道,
因此,怎么让MP4视频支撑通明度,业界常用的方法是运用两个通道别离进行 存储视频的RGB数据和Alpha数据。

image.png

规划师能够运用咱们AE插件生成以上特别的mp4资源,左面是RGB部分,右边是Alpha部分。然后经过设置不同的拉伸形式,能够在客户端正常展现份额。

为了用户带来更大的全屏特效的震撼感,咱们基本选择竖屏运用ASPECT_FIT,横屏

image.png
这个图能够更好的了解咱们RGB和Alpha区域的排布和转换。

vec3 rgb = texture2D(texture,vec2(vUx.x/2,vUv.y))).rgb
vec alpha = texture2D(texture,vec2(0.5 + vUx.x/2,vUv.y))).r 
gl_FragColor=vec4(rgb,alpha)

Android里边opengles的扩展库现已协助咱们将解析器上yuv的数据直接转换为rgba通道,咱们只需求将纹理极点区域指定好。

rgb区域是在左面二分之一的方位,alpha的数据实际仅仅占rgb区域右边挨着的八分之一大小区域。

意思便是alpha区域实际是rgb区域的四分之一。这儿这样处理是人眼对alpha区域并不是十分敏感,能够缩小来紧缩mp4空间。

image.png

YYEVA客户端烘托

YYEVA完成动态元素的计划,是在通明MP4的基础上,结合Alpha区域的混合,将需求刺进的动态元素信息,提前解析并保存在一个Json数据中,一起经过编码、紧缩处理,写入MP4的Metadata段。客户端在解析的时分,别离提取音视频轨信息和描绘信息。

yyeva架构.png
以上是整个YYEVA的基本架构 ,在咱们的工程里能够别离对应上类名来进行检索学习。

数据解析.png
前面说过YYEVA会将json数据封装到mp4的metadata当中,但是metada是经过ffmpeg进行封装的,Android端并没有封装好能够直接读取metadata数据的工具。这儿只能用比较笨的方法,对整个mp4文件进行遍历读取,读取带有yyeffectmp4josn[[]]yyeffectmp4json的字符串。然后再进行base64,zip解密,那么才能得咱们需求的整个数据。

Android的MediaMetaData类和ffmpeg解封并不等同,所以然并卵。IOS端却是能够经过遍历的方法获取到ffmepg封装的metadata box。

假如有大佬能做个相关内容,能够不引证ffmpeg,获取到metadata的box的能力,也是私聊小弟,让咱们的结构愈加高效完善。

描绘信息

经过上面几个图,咱们发现,有一个比较要害的信息,便是Json描绘信息,这个描绘信息咱们在运用插件解析规划师图层的时分,现已经过编码紧缩,写入到了Metadata类。客户端拿到这个Json类,能够知道每一个动态元素,每一帧的烘托大小、方位以及形状。

{
	"descript": {                          //视频的描绘信息
		"width": 1808,                     //输出视频的宽
		"height": 1008,                    //输出视频的高
		"isEffect": 1,                     //是否为动态元素视频
		"version": 1,                      //插件的版别号
		"rgbFrame": [0, 0, 900, 1000],     //rgb方位信息
		"alphaFrame": [900, 0, 450, 500]   //alpha方位信息
	},
	"effect": [
         {  //动态元素的遮罩描绘信息 : 文字类型
		"effectWidth": 700,        //动态元素宽
		"effectHeight": 1049,      //动态元素高
		"effectId": 1,             //动态元素索引id
		"effectTag": "nickName",   //动态元素的tag,事务运用的时分,表明的key
		"effectType": "txt",       //动态元素类型 有 txt和img 2种
        "fontColor":"#ffffff",     //当为txt类型的时分才存在 假如规划侧未指定,由烘托端自行指定默认值
        "fontSize":13,             //当为txt类型的时分才存在 假如规划侧未指定,由烘托端自行指定默认值
	},{  //动态元素的遮罩描绘信息    : 图片类型
        "effectWidth": 300,  //同上
        "effectHeight": 400,//同上
        "effectId": 2,       //同上
        "effectTag": "user_avatar",   //同上
        "effectType": "img",  //同上
        "scaleMode":"aspectFill",  //当为img类型的时分才存在 假如规划侧未指定,由烘托端自行指定默认值
    }...],
	"datas": [{                                      //每一帧的动态元素方位信息
		"frameIndex": 0,                             //帧索引
		"data": [{       
			"renderFrame": [x1, y1, w1, h1],         //在画布上的方位
			"effectId": 1,                           //标志是哪个动态元素
			"outputFrame": [x1`, y1`, w1`, h1`]      //在视频区域的方位
		},{       
            "renderFrame": [x2, y2, w2, h2],         //在画布上的方位
            "effectId": 2,                           //标志是哪个动态元素
            "outputFrame": [x2`, y2`, w2`, h2`]      //在视频区域的方位
         } ... ]
}
仿制代码

Json数据 包含三层:descript/effect/datas

  1. descript: 描绘该资源的全体信息
  2. effect : 描绘 该资源下的所有遮罩相关信息
  3. datas : 描绘 每一帧遮罩的方位信息

经过这个描绘信息,在烘托每一个动态元素的时分,能够知道该动态元素在每一frameIndex的遮罩方位outputFrame,以及在画布上的方位renderFrame

该Json信息,在客户端烘托SDK中,会模态化成对应的Descript, Effect Datas目标,由于数据运用削减反射,咱们java和C++层都解析了目标。
C++中运用了parson库,这个比较轻量推荐咱们运用。

YYEVA烘托流程

image.png
YYEVA整个烘托的流程能够经过上图流程完美出现出来,烘托的代码都是在Native层。

image.png

以上是整个流程的简略类逻辑。

image.png
这是通明mp4组成的逻辑,经过rgb区域和极点扩大的alpha区域的r值进行组成。烘托出底图。

image.png

fragment shager 元素色值srcRgba 和图形蒙层maskRgba进行合并

image.png

运用opengles运用混合处理进行元素通明度叠加制作。

结语

代码仅仅展现了烘托的一小部分,咱们还加入了vbo vao等opengles老练的极点缓存技能,解析数据JSON收据的优化,支撑了列表播映。

咱们在2.0的beta版别中现已完成了视频解析器和烘托器、整个音频播映器都迁移到native层中,数据不需求屡次解析,调用多进程能够跨进程削减压力。

当然咱们遇到了许多问题不同的问题,也是这些问题,让咱们有了行进的方向,谢谢运用咱们开源sdk的同好们。

期望能够为咱们的项目 YYEVA 点上一个⭐⭐⭐,您的支撑便是咱们一直更新文章下去的动力哈。期望咱们多多鼓励