mediaplayer总时长不正确_OpenGL ES + MediaPlayer 渲染播放视频+滤镜效果

本文介绍了如何使用OpenGL ES和MediaPlayer在Android上播放视频,并通过着色器实现滤镜效果,如灰度图。首先展示了一个使用OpenGL着色器的黑白效果,接着详细讲解了顶点着色器、片段着色器的编写,以及如何通过SurfaceTexture和samplerExternalOES处理MediaPlayer的YUV输出。最后,提供了完整的GLVideoRenderer代码示例,实现滤镜视频效果。
摘要由CSDN通过智能技术生成

之前曾经写过用SurfaceView,TextureView+MediaPlayer 播放视频,和  ffmpeg avi 解码后SurfaceView播放视频 ,今天再给大家来一篇 OpenGL ES+MediaPlayer 来播放视频。

当年也曾呆过camera开发组近一年时间,可惜那时候没写博客的意识,没能给自己给大家留下多少干货分享。

上个效果图吧:

57ad606d52c3466e7531eb2443f9252a.png

用 OpenGL 着色器实现黑白(灰度图)效果。


即 0.299,0.587,0.114  CRT中转灰度的模型

76ce4b9c307e3d68d8af31db94a5e09e.png

下面看具体实现的逻辑:

如果你曾用 OpenGL 实现过贴图,那么就容易理解多了。

和图片不同的是,视频需要不断地刷新,每当有新的一帧来时,我们都应该更新纹理,然后重新绘制。用 OpenGL 播放视频就是把视频贴到屏幕上。


对openGL不熟的同学先看这里:学 OpenGL 必知道的图形学知识

1.先写顶点着色器和片段着色器

顶点着色器:

attribute vec4 aPosition;//顶点位置
attribute vec4 aTexCoord;//S T 纹理坐标
varying vec2 vTexCoord;
uniform mat4 uMatrix;
uniform mat4 uSTMatrix;
void main() {
    vTexCoord = (uSTMatrix * aTexCoord).xy;
    gl_Position = uMatrix*aPosition;
}

片段着色器:

#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTexCoord;
uniform samplerExternalOES sTexture;
void main() {
    gl_FragColor=texture2D(sTexture, vTexCoord);
}

对着色器语言不懂的同学看这里:http://blog.csdn.net/king1425/article/details/71425556

samplerExternalOES 代替贴图片时的 sampler2D ,作用就是和s urfaceTexture 配合进行纹理更新和格式转换。

2.MediaPlayer的输出

在 GLVideoRenderer 的构造函数中初始化 MediaPlayer :

mediaPlayer=new MediaPlayer();
        try{
            mediaPlayer.setDataSource(context, Uri.parse(videoPath));
        }catch (IOException e){
            e.printStackTrace();
        }
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setLooping(true);

        mediaPlayer.setOnVideoSizeChangedListener(this);

onSurfaceCreated函数中使用SurfaceTexture来设置MediaPlayer的输出。


我们要用SurfaceTexture 创建一个Surface,然后将这个Surface作为MediaPlayer的输出表面。

SurfaceTexture的主要作用就是,从视频流和相机数据流获取新一帧的数据,获取新数据调用的方法是updateTexImage。

需要注意的是MediaPlayer的输出往往不是RGB格式(一般是YUV),而GLSurfaceView需要RGB格式才能正常显示。


所以我们先在onSurfaceCreated中将生成纹理的代码改成这样:

textureId = textures[0];
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
ShaderUtils.checkGlError("ws-------glBindTexture mTextureID");

GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
        GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
        GLES20.GL_LINEAR);

GLES11Ext.GL_TEXTURE_EXTERNAL_OES的用处是什么?


之前提到视频解码的输出格式是YUV的(YUV4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值