阅读 2516

Android播放透明视频

话不多说,开局一张图,内容全靠“编”:

随着业务场景的增多,更多的特效用原生绘制、GIF的方式都不能很好的满足需求了,这就带来了一个新的方式:用视频特效来代替。特别是在视频(直播)行业中,各种特效炫酷又精美,能很好的表达用户的想法。但是这也带来了一个问题:虽然播放视频非常简单,但是同时要把视频下面的UI也展示出来就没那么简单了,这就需要视频有透明效果,这样才能不遮挡底层UI。既然写了这篇博客,自然有很简单的方式来实现这种透明视频的播放了,那就是用第三方库**《wlmedia》**,几句代码就能实现透明视频的播放。

一、先来大致说一下透明视频播放原理(只是单纯的调用库也不好):

视频播放一般都会把视频数据(大部分是yuv)转换为rgba来渲染(播放),实际情况我们也是这么做的,拿到rgba颜色数据之后通过OpenGL绘制到surface上面,此时渲染出来的视频就是正常的(不透明的),因为我们默认alpha通道为1(1完全不透明,0完全透明)。当我们需要达到透明效果时就需要控制alpha通道的值,在渲染像素点的颜色时并考虑当前像素点的透明度,这样渲染出来的颜色值就是带透明度的,这样透明视频的播放就可以实现了。

二、播放透明视频的方式:

1、过滤某一范围的颜色值(最简单,适用于任一视频,但效果不佳,类似于电影绿布效果):

比如我们把特效视频背景设置成黑色 [r(0) g(0) b(0)],然后特效用其他颜色来实现(尽量不要包含黑色),这样我们渲染时就可以判断当前像素的rgb分量值是否接近0,如果接近0,那么就把此像素的alpha值设置成0(完全透明),这样这个像素点就不会显示出来,达到了透明的效果;反之若此像素的rgb分量值与0相差比较大,此时设置alpha的值为1(完全不透明),这样这个像素点就显示出来了,我们的特效也就显示出来了。

2、制作包含alpha分量值的视频(复杂,视频需定制):

这种视频常见的制作效果是alpha值和特效左右平分,alpha值用黑白特效视频制作(纯黑色为0-完全透明,纯白色为1-完全不透明,其余颜色介于(0~1-部分透明)之间),当渲染视频时,首先去拿特效的rgb值,然后再通过rgb的坐标位置去拿alpha值,这样结合起来就可以实现透明效果,当然播放时我们只需要裁剪播放特效视频那一部分区域。比如:特效rgb值是 rgb(100)红色,此时这个值对应的alpha的值的rgb值为(0.5,0.5,0.5),这样我们就取到了透明度alpha=0.5,最终渲染像素点时的rgba值就是rgba(1,0,0,0.5)成了半透明的红色。

三、SDK调用方式:

虽然原理和实现讲了,但是要完全实现效果出来还是有一定的难度,下面我们就开的调用wlmedia的库了,简直so easy!

1、gradle中导入库:目前最新版本 1.1.3

implementation 'ywl.ywl5320:wlmedia:1.1.3'
复制代码

2、设置布局:

//位于所有布局上层
<com.ywl5320.wlmedia.surface.WlSurfaceView        
    android:id="@+id/wlsurfaceview"        
    android:layout_width="match_parent"        
    android:layout_height="match_parent"        
    android:visibility="invisible"/> 

//和普通view一样可随意设置位置
<com.ywl5320.wlmedia.surface.WlTextureView        
    android:id="@+id/wltextureView"        
    android:layout_width="match_parent"        
    android:layout_height="match_parent"        
    android:visibility="invisible"/>
复制代码

3、开始播放(关键代码)

WlSurfaceView wlSurfaceView = findViewById(R.id.wlsurfaceview);
wlSurfaceView.enableTransBg(true); //设置surface背景透明
WlMedia wlMedia = new WlMedia();
wlSurfaceView.setWlMedia(wlMedia);
wlMedia.setSourceType(WlSourceType.NORMAL);
wlMedia.setCodecType(WlCodecType.CODEC_MEDIACODEC);
wlMedia.setLoopPlay(false);
wlMedia.setVideoClearColor(0, 0, 0, 0); //设置surface颜色透明
wlMedia.enableTransVideo(WlVideoTransType.VIDEO_TRANS_LEFT_ALPHA); //设置alpha通道类型(左边)
wlMedia.prepared();
复制代码

以上就是播放透明视频的原理和方法,不止在android中,其他平台也是一样的,原理才是核心。

Demo下载地址:GitHub:alphavideo

注:部分视频素材来自AlphaPlayer