Android 基于MediaCodec开发抖音短视频录制(贰)

前言

上一篇文章中,我大概介绍了一下短视频的拍摄,主要就是音视频的加减速。这篇文章我将介绍下抖音视频特效的实现,废话不多说,进入正题。

1.特效概览

抖音上目前有这九种视频特效,本文将介绍前面六种的实现。有人可能会问了,为什么最后三种特效被忽略了。

当然是因为我懒啦。

2.『灵魂出窍』

抖音的实现效果如下:

我的实现效果如下:

代码实现

通过观察抖音的效果,可以看到,共有两个图层,一个是视频原图,还有一个是从中心放大并且透明度逐渐减小的图层,关键代码如下。

2.1 顶点着色器

uniform mat4 uTexMatrix;
attribute vec2 aPosition;
attribute vec4 aTextureCoord;
varying vec2 vTextureCoord;
uniform mat4 uMvpMatrix;
void main(){
    gl_Position = uMvpMatrix * vec4(aPosition,0.1,1.0);
    vTextureCoord = (uTexMatrix * aTextureCoord).xy;
}

2.2 片元着色器

#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTextureCoord;
uniform samplerExternalOES uTexture;
uniform float uAlpha;
void main(){
    gl_FragColor = vec4(texture2D(uTexture,vTextureCoord).rgb,uAlpha);
}

这两部分代码比较简单,没有什么特殊的操作,就是单纯地把纹理渲染到内存中

2.3动画代码

//当前动画进度
private float mProgress = 0.0f;
//当前地帧数
private int mFrames = 0;
//动画最大帧数
private static final int mMaxFrames = 15;
//动画完成后跳过的帧数
private static final int mSkipFrames = 8;
//放大矩阵
private float[] mMvpMatrix = new float[16];
//opengl 参数位置
private int mMvpMatrixLocation;
private int mAlphaLocation;
public void onDraw(int textureId,float[] texMatrix){
        //因为这里是两个图层,所以开启混合模式
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
        mProgress = (float) mFrames / mMaxFrames;
        if (mProgress > 1f) {
            mProgress = 0f;
        }
        mFrames++;
        if (mFrames > mMaxFrames + mSkipFrames) {
            mFrames = 0;
        }
        Matrix.setIdentityM(mMvpMatrix, 0);//初始化矩阵
        //第一帧是没有放大的,所以这里直接赋值一个单位矩阵
        glUniformMatrix4fv(mMvpMatrixLocation, 1, false, mMvpMatrix, 0);
        //底层图层的透明度
        float backAlpha = 1f;
        //放大图层的透明度
        float alpha = 0f;
        if (mProgress > 0f) {
            alpha = 0.2f - mProgress * 0.2f;
            backAlpha = 1 - alpha;
        }
        glUniform1f(mAlphaLocation, backAlpha);
        glUniformMatrix4fv(mUniformTexMatrixLocation, 1, false, texMatrix, 0);
        //初始化顶点着色器数据,包括纹理坐标以及顶点坐标
        mRendererInfo.getVertexBuffer().position(0);
        glVertexAttribPointer(mAttrPositionLocation, 2,
                GL_FLOAT, false, 0, mRendererInfo.getVertexBuffer());
        mRendererInfo.getTextureBuffer().position(0);
        glVertexAttribPointer(mAttrTexCoordLocation, 2,
                GL_FLOAT, false, 0, mRendererInfo.getTextureBuffer());
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
        //绘制底部原图
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
        if (mProgress > 0f) {
            //这里绘制放大图层
            glUniform1f(mAlphaLocation, alpha);
            float scale = 1.0f + 1f * mProgress;
            Matrix.scaleM(mMvpMatrix, 0, scale, scale, scale);
            glUniformMatrix4fv(mMvpMatrixLocation, 1, false, mMvpMatrix, 0);
            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
        }

        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
        GLES20.glUseProgram(0);
        glDisable(GL_BLEND);
}

以上代码最终绘制出来的就是 『灵魂出窍』的效果

3.『抖动』

抖音的实现效果如下:

我的实现效果如下:

代码实现

要做这个效果前,我们先分析下抖音的效果。这个特效总共包含两个部分的内容:

  • 中心放大
  • 颜色偏移

我们把视频暂停截图之后,可以看到如下的图:

从图上我们可以看到,键盘里的原文字变成了蓝色,而左上角和右下角分别多了绿色和红色的字,那么这个颜色分离就是将一个像素的RGB值分别分离出去。

2.1 顶点着色器

uniform mat4 uTexMatrix;
attribute vec2 aPosition;
attribute vec4 aTextureCoord;
varying vec2 vTextureCoord;
uniform mat4 uMvpMatrix;
void main(){
    gl_Position = uMvpMatrix * vec4(aPosition,0.1,1.0);
    vTextureCoord = (uTexMatrix * aTextureCoord).xy;
}

 2.2 片元着色器

#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTextureCoord;
uniform samplerExternalOES uTexture;
//颜色的偏移距离
uniform float uTextureCoordOffset;
void main(){
    vec4 blue = texture2D(uTexture,vTextureCoord);
    vec4 gree
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值