GlsurfaceView 怎么上传视频到抖音频

&>&GLSurfaceView控件通过MediaPlayer播放视频
GLSurfaceView控件通过MediaPlayer播放视频
上传大小:45.02MB
GLSurfaceView控件实现 GLSurfaceView.Renderer , SurfaceTexture.OnFrameAvailableListener接口,通过MediaPlayer播放本地视频
综合评分:0
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有0条
VIP会员动态
热门资源标签
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
GLSurfaceView控件通过MediaPlayer播放视频
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
fowuchubuzai
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*投诉人姓名:
*投诉人联系方式:
*版权证明:
*详细原因:
GLSurfaceView控件通过MediaPlayer播放视频Android OpenGL使用GLSurfaceView预览视频
一年之前做过一些即时通信视频相关的工作,主要是做视频渲染这一部分的工作,由于2016毕业来到了华为,华为对研究生的安排就是“哪里需要去哪里”,和你专业和擅长的没有太大的关系,所以一直在适应当下的工作,现在基本上可以胜任现在的工作,可以抽出一些时间来总结一下之前了解过的OpenGL相关知识。
第一章 相关知识介绍
在介绍具体的功能之前,先对一些主要的类和方法进行一些介绍,这样可以更好的理解整个程序
1.1 GLSurfaceView
在谷歌的官方文档中是这样解释GLSurfaceView的:
An implementation of SurfaceView that uses the dedicated surface for displaying OpenGL rendering.
大意是GLSurfaceView是一个继承了SurfaceView类,它是专门用来显示OpenGL的渲染。通俗的来说,GLSurfaceView可以用来显示视频、图像和3D模型等视图,在接下来的章节中主要是使用它来显示Camera视频数据,大家可能会有一些问题,SurfaceView也可用来预览Camera,那么这两者有什么区别吗?GLSurfaceView能够真正做到让Camera的数据和显示分离,我们就可以在此基础上对视频数据做一些处理,例如美图,增加特效等。
1.2 GLSurfaceView.Renderer
如果说GLSurfaceView是画布,那么仅仅有一张白纸是没用的,我们还需要一支画笔,Renderer的功能就是这里说的画笔。Renderer是一个接口,主要包含3个抽象的函数:onSurfaceCreated、onDrawFrame、onSurfaceChanged,从名字就可以看出,分别是在SurfaceView创建、视图大小发生改变和绘制图形时调用。
1.3 Camera
从Android 5.0开始(API Level 21),可以完全控制安卓设别相机的新API Camera2(android.hardware.Camera2)被引进来了。虽然新的Camera2不管在功能上还是友好度上都强于旧的Camera,但是我们这里还是使用的旧的Camera,由于新的Camera2暂时还没有找到可以获取视频帧的接口,因为后面肯能会对Canmera视频帧做一些处理,所以这里暂时还是使用旧的Camera。
第二章 开始绘制
2.1 CameraGLSurfaceView
public class CameraGLSurfaceView extends GLSurfaceView implements Renderer, SurfaceTexture.OnFrameAvailableListener {
private Context mC
private SurfaceTexture mS
private int mTextureID = -1;
private DirectDrawer mDirectD
public CameraGLSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext =
setEGLContextClientVersion(2);
setRenderer(this);
setRenderMode(RENDERMODE_WHEN_DIRTY);
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
LOG.logI("onSurfaceCreated...");
mTextureID = GlUtil.createTextureID();
mSurface = new SurfaceTexture(mTextureID);
mSurface.setOnFrameAvailableListener(this);
mDirectDrawer = new DirectDrawer(mTextureID);
CameraCapture.get().openBackCamera();
public void onSurfaceChanged(GL10 gl, int width, int height) {
LOG.logI("onSurfaceChanged...");
GLES20.glViewport(0, 0, width, height);
if (!CameraCapture.get().isPreviewing()) {
CameraCapture.get().doStartPreview(mSurface);
public void onDrawFrame(GL10 gl) {
LOG.logI("onDrawFrame...");
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
mSurface.updateTexImage();
mDirectDrawer.draw();
public void onPause() {
super.onPause();
CameraCapture.get().doStopCamera();
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
LOG.logI("onFrameAvailable...");
this.requestRender();
这个类主要做了以下几件事情:
实现Renderer这个接口,并且实现GLSurfaceView的初始化。在CameraGLSurfaceView的构造函数中设置了GLSurfaceView的版本:setEGLContextClientVersion(2),如果没有这个设置,GLSurfaceView是什么也绘制不出来的,因为Android支持OpenGL ES1.1、2.0以及3.+等版本,而且版本间的差别很大,不声明版本号,GLSurfaceView是不知道使用哪个版本进行渲染;设置Renderer与当前的View绑定,然后再设置渲染的模式为RENDERMODE_WHEN_DIRTY。渲染模式的设置也很关键,渲染模式有两种:RENDERMODE_WHEN_DIRTY和RENDERMODE_CONTINUOUSLY。DIRYT的含义是只有当被通知的时候才会去渲染视图,而CONTINUOUSLY的含义是视频会一直连续的渲染。
在onSurfaceCreated()函数中,创建一个渲染的纹理,这个纹理就是用来显示Camera的图像,所以需要新创建的SurfaceTexture绑定在一起,而SurfaceTexture是作为渲染的载体,另一方面需要和DirectDrawer绑定在一起,DirectDrawer是用来绘制图像的,下面会具体介绍。最后是初始化Camera。
因为在初始化的时候这是了渲染的模式为RENDERMODE_WHEN_DIRTY,所以我们就通知GLSurfaceView什么时候需要渲染图像,而接口SurfaceTexture.OnFrameAvailableListener完成这项工作,函数onFrameAvailable()在有新数据到来时,会被调用,在其中调用requestRender(),就可以完成新数据的渲染。
在onSurfaceChanged()函数中,设置了OpenGL窗口的大小,(0,0)表示窗口内部视口的左下角,(w,h)指定了视口的大小;打开Camera的预览。
最后,在onDrawFrame()函数中绘制更新的纹理。
2.2 DirectDrawer
这个类非常重要,负责将SurfaceTexture(纹理的句柄)内容绘制到屏幕上。
public class DirectDrawer {
private FloatBuffer vertexBuffer, mTextureCoordsB
private ShortBuffer drawListB
private final int mP
private int mPositionH
private int mTextureCoordH
private int mMVPMatrixH
private short drawOrder[] = {0, 2, 1, 0, 3, 2};
private final int COORDS_PER_VERTEX = 2;
private final int vertexStride = COORDS_PER_VERTEX * 4;
private float mVertices[] = new float[8];
private float mTextureCoords[] = new float[8];
private float mTextHeightRatio = 0.1f;
private int
public float[] mMVP = new float[16];
public void resetMatrix() {
mat4f_LoadOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, mMVP);
public DirectDrawer(int texture) {
String vertextShader = TextResourceReader.readTextFileFromResource(MyApplication.getContext()
, R.raw.video_vertex_shader);
String fragmentShader = TextResourceReader.readTextFileFromResource(MyApplication.getContext()
, R.raw.video_normal_fragment_shader);
mProgram = GlUtil.createProgram(vertextShader, fragmentShader);
if (mProgram == 0) {
throw new RuntimeException("Unable to create program");
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
GlUtil.checkLocation(mPositionHandle, "vPosition");
mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "inputTextureCoordinate");
GlUtil.checkLocation(mTextureCoordHandle, "inputTextureCoordinate");
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
GlUtil.checkLocation(mMVPMatrixHandle, "uMVPMatrix");
this.texture =
updateVertices();
setTexCoords();
ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
mat4f_LoadOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, mMVP);
public void draw() {
GLES20.glUseProgram(mProgram);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
GLES20.glVertexAttribPointer(mTextureCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, mTextureCoordsBuffer);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVP, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
public static void mat4f_LoadOrtho(float left, float right, float bottom, float top, float near, float far, float[] mout) {
float r_l = right -
float t_b = top -
float f_n = far -
float tx = -(right + left) / (right - left);
float ty = -(top + bottom) / (top - bottom);
float tz = -(far + near) / (far - near);
mout[0] = 2.0f / r_l;
mout[1] = 0.0f;
mout[2] = 0.0f;
mout[3] = 0.0f;
mout[4] = 0.0f;
mout[5] = 2.0f / t_b;
mout[6] = 0.0f;
mout[7] = 0.0f;
mout[8] = 0.0f;
mout[9] = 0.0f;
mout[10] = -2.0f / f_n;
mout[11] = 0.0f;
mout[12] =
mout[13] =
mout[14] =
mout[15] = 1.0f;
public void updateVertices() {
final float w = 1.0f;
final float h = 1.0f;
mVertices[0] = -w;
mVertices[1] =
mVertices[2] = -w;
mVertices[3] = -h;
mVertices[4] =
mVertices[5] = -h;
mVertices[6] =
mVertices[7] =
vertexBuffer = ByteBuffer.allocateDirect(mVertices.length * 4).order(ByteOrder.nativeOrder())
.asFloatBuffer().put(mVertices);
vertexBuffer.position(0);
public void setTexCoords() {
mTextureCoords[0] = 0;
mTextureCoords[1] = 1 - mTextHeightR
mTextureCoords[2] = 1;
mTextureCoords[3] = 1 - mTextHeightR
mTextureCoords[4] = 1;
mTextureCoords[5] = 0 + mTextHeightR
mTextureCoords[6] = 0;
mTextureCoords[7] = 0 + mTextHeightR
mTextureCoordsBuffer = ByteBuffer.allocateDirect(mTextureCoords.length * 4).order(ByteOrder.nativeOrder())
.asFloatBuffer().put(mTextureCoords);
mTextureCoordsBuffer.position(0);
这个类的主要功能就是绘制图像。
(1) 定义Vertex Shader(顶点着色器,用来绘制图形的形状)、Fragment Shader(片段着色器,用来绘制图形的颜色或者纹理)和Program(OpenGL ES对象,包含了用来绘制一个或者多个形状的shader),然后接下来都是围绕着这三个变量,最后通过调用OpenGL方法进行绘制。具体的过程可以参考前面的博客
(2) 既然我们需要预览Camera的视频数据,那么我们可以知道现实的区域的形状大部分都是四边形,但是在OpenGL中只有提供了绘制三角形的方法,我们就需要将两个三角形拼接成一个正方形,所以需要定义一个大小为8的数组,如下面代码所示:
static float squareCoords[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
此时,我们就有了一个四边形的4个点的数据了。但是,OpenGL并不是对数组的数据直接进行操作的,而是在直接内存中,即操作的数据需要保存到NIO里面的Buffer对象中。而我们上面生命的float[]对象保存在数组中,因此我们需要将float[]对象转换为Java.nio.Buffer对象,代码如下:
public void updateVertices() {
final float w = 1.0f;
final float h = 1.0f;
mVertices[0] = -w;
mVertices[1] =
mVertices[2] = -w;
mVertices[3] = -h;
mVertices[4] =
mVertices[5] = -h;
mVertices[6] =
mVertices[7] =
vertexBuffer = ByteBuffer.allocateDirect(mVertices.length * 4).order(ByteOrder.nativeOrder())
.asFloatBuffer().put(mVertices);
vertexBuffer.position(0);
注意,ByteBuffer和FloatBuffer以及IntBuffer都是继承自抽象类java.nio.Buffer。
另外,OpenGL在底层的实现是C语言,与Java默认的数据存储字节顺序可能不同,即大端小端问题。因此,为了保险起见,在将数据传递给OpenGL之前,我们需要指明使用本机的存储顺序。
此时,我们顺利地将float[]转为了FloatBuffer,后面绘制三角形的时候,直接通过成员变量mTriangleBuffer即可。
(3) 最后就是将准备好的数据绘制到屏幕上,OpenGL 提供了两个绘制的方法glDrawArrays(int mode, int first, int count)和glDrawElements(int mode,int count, int type, Buffer indices)两个方法,在这里我们使用的第二种绘制的方法,关于mode有几种模式供我们选择:
GL_POINTS:绘制独立的点到屏幕
GL_LINE_STRIP:连续的连线,第n个顶点与第n-1个顶点绘制一条直线
GL_LINE_LOOP:与上一个相同,但是需要首尾相联接
GL_LINES:形成对的独立的线段
GL_TRIANGLE_STRIP:绘制一系列的三角形,先是顶点v0,v1,v2,然后是v2,v1,v3(注意规律),然后v2,v3,v4等。该规律确保所有的三角形都以相同的方向绘制
GL_TRIANGLE_FAN和GL_TRANGLE_STRIP类似,但其县绘制v0,v1,v2,再是v0,v2,v3,然后v0,v3,v4等。
(4) 需要注意的是,在这个类中,定义了mMVP这个数组,这个数组的功能是对视频帧数据进行转换的,例如旋转图像等。
第三章 总结
到此为止,使用GLSurfaceView预览Camera的介绍就完了,这篇文章,仅仅介绍了CameraGLSurfaceView和DirectDrawer这两个类,但是如何对Camera进行操作的并没有介绍,这不是本文的重点,所以就省略了。接下来还会介绍一些有关GLSurfaceView的文章。
短视频sdk:选择一个靠谱的短视频SDK 你需要了解这些
Android视频图片缩略图的获取
Android摄像头开发:实时摄像头视频预览帧的编码问题(二)
Android平台Camera实时滤镜实现方法探讨(五)--GLSurfaceView实现Camera预览
使用Camera和GLSurfaceView创建自定义相机预览画面并在预览画面上加入自定义图形
Android+OpenGL短视频录制方案
android中用GLSurfaceview和opengl es2.0显示图片,图片无法正常显示
Android Camera API 2使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜)
Android SurfaceTexture和GLSurfaceView做Camera预览
没有更多推荐了,GLSurfaceView.Renderer,openGL的渲染接口
如果需要用opengl ES对视频输出的帧做渲染处理,比如四棱锥,六面体的反映射,就需要实现GLSurfaceView.Renderer这个接口。
GLSurfaceView.Renderer 一个渲染器接口,完成设置之后要调用 setRenderer(GLSurfaceView.Renderer) 去注册。其接口:onDrawFrame(GL10 glUnused)
需要画图时调用这里。mSurface.setOnFrameAvailableListener()就是将监听绑定到mSurface这个SurfaceTexture上。onSurfaceChanged(GL10 glUnused, int width, int height)
当surface大小发生变化会来到这里。onSurfaceCreated(GL10 glUnused, EGLConfig config)
当GLSurfaceView创建时,会调用这个接口。初始化用,写shader创建program之类的都放在这里完成。其中,setEGLContextClientVersion(2)是设置opengl ES的版本号
这里先记个大概笔记,后面再补充代码对应分析。
更详细请参考
http://web.mit.edu/hychenj/MacData/afs/sipb/project/android/docs/reference/android/opengl/GLSurfaceView.Renderer.html
android.opengl.GLSurfaceView.Renderer概述
Android初始化OpenGL ES,并且分析Renderer子线程原理
使用Opengl ES GlSurfaceView Render Camera preview
GLSurfaceView.Renderer
Android GLSurfaceView.Renderer 类 onDrawFrame 方法的刷新机制
没有更多推荐了,Error 404 (Not Found)!!1
404. That’s an error.
The requested URL /8121259/ was not found on this server.
That’s all we know.——ACMer, Android Developer, Computer Vision Workhorse
[OpenGL]从零开始写一个Android平台下的全景视频播放器——2.2 使用GLSurfaceView和MediaPlayer播放一个平面视频(中)
,欢迎star~!
为了方便没有准备好梯子的同学,我把项目在,不过更新会慢一些
更新着色器代码
因为使用了视频作为输入源,需要更新着色器代码
fragment_shader.glsl
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 vTexC
uniform samplerExternalOES sT
void main() {
gl_FragColor=texture2D(sTexture, vTexCoord);
在这里,我们使用samplerExternalOES代替之前的sampler2D,需要注意的是第一行的注解是必须加上的
这个samplerExternalOES有什么用呢? 其实就是之前说的和surfaceTexture配合进行纹理更新和格式转换,具体的可以直接看OpenGL ES的官方文档,我截了一段供大家参考(估计也没什么人看。。):
vertex_shader.glsl
attribute vec4 aP
attribute vec4 aTexC
varying vec2 vTexC
uniform mat4 uM
uniform mat4 uSTM
void main() {
vTexCoord = (uSTMatrix * aTexCoord).
gl_Position = uMatrix*aP
在顶点着色器中,需要加入对应的uSTMatrix,并且aTexCoord要改成长度为4的向量,以便于做乘法操作。
更新GLRenderer
在GLRenderer中,用类似的方法获取uSTMMatrixHandle
uSTMMatrixHandle = GLES20.glGetUniformLocation(programId, "uSTMatrix");
每次绘制的时候,将mSTMatrix用类似的方法传给OpenGL:
GLES20.glUniformMatrix4fv(uSTMMatrixHandle, 1, false, mSTMatrix, 0);
因为用了扩展纹理,所以我们绑定的纹理类型也要做修改:
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,textureId);
我们刚才只是设定了一个boolean来表示可以更新纹理了,却没有具体操作,所以在onDrawFrame最开始加入如下代码
synchronized (this){
if (updateSurface){
surfaceTexture.updateTexImage();
surfaceTexture.getTransformMatrix(mSTMatrix);
updateSurface = false;
为了后续操作方便,我将绘制三角形的方式换成了绘制三角形带。
因为目前写的代码已经比较长了,我会在最后直接贴出GLRenderer的代码,如果遇到了什么问题,可以对照着看一下。
那我们来试一下吧,直接指定一个视频源,看看能不能正常显示(别忘了声明权限哦):
glSurfaceView.setRenderer(new GLRenderer(this, Environment.getExternalStorageDirectory().getPath()+"/360Video/video.mp4"));
这是一个2:1的全景视频,可以看到全景视频被压扁了,而且画面也是倒过来的,如果按一下HOME键,会发现视频并不会自己停止播放,我们会在下一节来解决屏幕尺寸适应和播放器生命周期的问题。
GLRenderer.java
package com.martin.ads.pa
import android.content.C
import android.graphics.SurfaceT
import android.media.AudioM
import android.media.MediaP
import android.net.U
import android.opengl.GLES11E
import android.opengl.GLES20;
import android.opengl.GLSurfaceV
import android.opengl.M
import android.util.L
import android.view.S
import java.io.IOE
import java.nio.ByteB
import java.nio.ByteO
import java.nio.FloatB
import java.nio.ShortB
import javax.microedition.khronos.egl.EGLC
import javax.microedition.khronos.opengles.GL10;
* Created by Ads on .
public class GLRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
private static final String TAG = "GLRenderer";
private int aPositionH
private int programId;
private FloatBuffer vertexB
private final float[] vertexData = {
-1f,1f,0f,
1f,-1f,0f,
-1f,-1f,0f
private final float[] projectionMatrix=new float[16];
private int uMatrixH
private final float[] textureVertexData = {
private FloatBuffer textureVertexB
private int uTextureSamplerH
private int aTextureCoordH
private int textureId;
private SurfaceTexture surfaceT
private MediaPlayer mediaP
private float[] mSTMatrix = new float[16];
private int uSTMMatrixH
private boolean updateS
private boolean playerP
private int screenWidth,screenH
public GLRenderer(Context context,String videoPath) {
this.context =
playerPrepared=false;
synchronized(this) {
updateSurface = false;
vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertexData);
vertexBuffer.position(0);
textureVertexBuffer = ByteBuffer.allocateDirect(textureVertexData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(textureVertexData);
textureVertexBuffer.position(0);
mediaPlayer=new MediaPlayer();
mediaPlayer.setDataSource(context, Uri.parse(videoPath));
}catch (IOException e){
e.printStackTrace();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(true);
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
String vertexShader = ShaderUtils.readRawTextFile(context, R.raw.vertex_shader);
String fragmentShader= ShaderUtils.readRawTextFile(context, R.raw.fragment_shader);
programId=ShaderUtils.createProgram(vertexShader,fragmentShader);
aPositionHandle= GLES20.glGetAttribLocation(programId,"aPosition");
uMatrixHandle=GLES20.glGetUniformLocation(programId,"uMatrix");
uSTMMatrixHandle = GLES20.glGetUniformLocation(programId, "uSTMatrix");
uTextureSamplerHandle=GLES20.glGetUniformLocation(programId,"sTexture");
aTextureCoordHandle=GLES20.glGetAttribLocation(programId,"aTexCoord");
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
textureId = textures[0];
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);
ShaderUtils.checkGlError("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);
surfaceTexture = new SurfaceTexture(textureId);
surfaceTexture.setOnFrameAvailableListener(this);
Surface surface = new Surface(surfaceTexture);
mediaPlayer.setSurface(surface);
surface.release();
if (!playerPrepared){
mediaPlayer.prepare();
playerPrepared=true;
} catch (IOException t) {
Log.e(TAG, "media player prepare failed");
mediaPlayer.start();
playerPrepared=true;
public void onSurfaceChanged(GL10 gl, int width, int height) {
screenWidth= screenHeight=
float ratio=width&height?
(float)width/height:
(float)height/
if (width&height){
Matrix.orthoM(projectionMatrix,0,-ratio,ratio,-1f,1f,-1f,1f);
}else Matrix.orthoM(projectionMatrix,0,-1f,1f,-ratio,ratio,-1f,1f);
public void onDrawFrame(GL10 gl) {
GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
synchronized (this){
if (updateSurface){
surfaceTexture.updateTexImage();
surfaceTexture.getTransformMatrix(mSTMatrix);
updateSurface = false;
GLES20.glUseProgram(programId);
GLES20.glUniformMatrix4fv(uMatrixHandle,1,false,projectionMatrix,0);
GLES20.glUniformMatrix4fv(uSTMMatrixHandle, 1, false, mSTMatrix, 0);
vertexBuffer.position(0);
GLES20.glEnableVertexAttribArray(aPositionHandle);
GLES20.glVertexAttribPointer(aPositionHandle, 3, GLES20.GL_FLOAT, false,
12, vertexBuffer);
textureVertexBuffer.position(0);
GLES20.glEnableVertexAttribArray(aTextureCoordHandle);
GLES20.glVertexAttribPointer(aTextureCoordHandle,2,GLES20.GL_FLOAT,false,8,textureVertexBuffer);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,textureId);
GLES20.glUniform1i(uTextureSamplerHandle,0);
GLES20.glViewport(0,0,screenWidth,screenHeight);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
synchronized public void onFrameAvailable(SurfaceTexture surface) {
updateSurface = true;
音视频直播技术--SurfaceView、GLSurfaceView与TextureView
Android使用OpengGL Es2.0技术(GLSurfaceView含缩放功能)yuv视频流展示总结
[OpenGL]从零开始写一个Android平台下的全景视频播放器——3.1 全景视频是如何实现的
[OpenGL]从零开始写一个Android平台下的全景视频播放器——目录
TextureView/SurfaceView/GLSurfaceView/VideoView渲染视频(点播播放器)
[OpenGL]从零开始写一个Android平台下的全景视频播放器——2.3 使用GLSurfaceView和MediaPlayer播放一个平面视频(下)
[OpenGL]从零开始写一个Android平台下的全景视频播放器——5.1 使用OpenGL把全景视频贴到球上
[OpenGL]从零开始写一个Android平台下的全景视频播放器——2.1 使用GLSurfaceView和MediaPlayer播放一个平面视频(上)
GLSurfaceView+openGL播放VR视频/全景视频(VR解码器)
没有更多推荐了,}

我要回帖

更多关于 彩妆全步骤视频教程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信