平时看直播APP时,经常会看到粉丝送可以刷屏礼物动炫酷动画。网上也有一些开源的实现方式,这里提供另外一种实现方式。如果将动画UI设计做出视频形式。我们在Camera预览界面上绘制除动画有效内容之外,其它部分为透明的即可。这样就可以同时看到Camera预览和刷屏礼物。编写APP是也不需要在APP中保存大量固定资源,只需要在使用时给个视频链接在线请求播放即可,后续更新动画设计,服务器端直接变更就行了。

当然实际对于直播观看者来说,不需要这样麻烦。直接将主播Camera预览和刷屏动画一起绘制之后,一起编码压缩传递给观看者即可,相当于观看者看到的是预览和动画合并之后的画面。 

     播放透明视频还有一个用途是AR的用途。实际我研究播放透明视频也是由于有需求,要在Camera预览过程中,对拍摄的物体进行识别,并在识别之后,在物体上面显示视频介绍,同时需要保存camera的预览不中断。

     本项目能够实现的最终效果如下图

     

android 直播礼物队列如何设计 直播礼物特效怎么做_顶点着色器

     本项目采用openGL的方式对Camera预览进行绘制。 要绘制的视频有UI处理成左右分屏的形式。如下图:

      

android 直播礼物队列如何设计 直播礼物特效怎么做_ios_02

对于这样的视频,左边即为实现要显示的效果;右边为要显示动画视频的黑白形式。需要显示的内容区域为白色(rgb = ffffff),其它需要显示为透明的区域为黑色(rgb = 000000),有了右边对内容区域RGB值的差异,就可以利用opengl的片元着色器进行相关计算了。

顶点着色器为普通顶点着色器如下:

private final static String VERTEX_SHADER_SIMPLE =
    "attribute vec4 aPosition;                              \n" +
    "attribute vec2 aTextureCoord;                          \n" +
    "varying vec2 vTextureCoord;                            \n" +
    "void main() {                                          \n" +
    "  gl_Position = aPosition;                             \n" +
    "  vTextureCoord = aTextureCoord;                       \n" +
    "}                                                      \n";

片元着色器对上述左右分屏格式的视频采样是进行简单处理。

private final static String FRAGMENT_SHADER_OES_TRANS =
"#extension GL_OES_EGL_image_external : require               \n" +
"precision mediump float;                                     \n" +
"varying vec2 vTextureCoord;                                  \n" +
"uniform samplerExternalOES sTexture;                         \n" +
"void main() {                                                \n" +
"vec4 tc1 = texture2D(sTexture, vec2(vTextureCoord.s/2.0, vTextureCoord.t));\n" +
"vec4 tc2 = texture2D(sTexture, vec2(vTextureCoord.s/2.0+0.5,vTextureCoord.t));\n"+
"gl_FragColor = vec4(tc1.rgb, tc2.r);                         \n" +
"}                                                            \n";

实际上我们需要的采样的纹理与视频左半部分,所以采样是我们将传递进来的s坐标/2 保证只使用左边纹理。我们要用的右边部分纹理主要是获取当然是否需要显示还是透明。

(1)如果是需要显示时,右边的rgb=ffffff,我们随便取r、g、b中任何一个值为当做左边纹理的alpha通道值,这样需要显示的左边纹理的rgba值为tc1.rgb 和 1。

(2)如果是需要显示为透明时,右边的rgb=000000,我们随便取r、g、b中任何一个值为当做左边纹理的alpha通道值,这样需要显示的左边纹理的rgba值为tc1.rgb 和 0。

有了alpha通道的差异,我们在绘制时即可进行颜色混合。