Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓如何在曲面上播放视频(OpenGL)_Android_Video_Opengl Es - Fatal编程技术网

Android 安卓如何在曲面上播放视频(OpenGL)

Android 安卓如何在曲面上播放视频(OpenGL),android,video,opengl-es,Android,Video,Opengl Es,需要帮助 如何在Android中的Surface(OpenGL)上播放视频? 我尝试在MediaPlayer中使用帮助方法setSurface()在mySurfaceView-extensed-SurfaceView中播放视频 SurfaceTexture mTexture = new SurfaceTexture(texture_id); Surface mSurface = new Surface(mTexture); MediaPlayer mp = new MediaPlayer();

需要帮助

  • 如何在Android中的
    Surface(OpenGL)
    上播放视频? 我尝试在
    MediaPlayer
    中使用帮助方法
    setSurface()
    mySurfaceView-extensed-SurfaceView
    中播放视频

    SurfaceTexture mTexture = new SurfaceTexture(texture_id);
    Surface mSurface = new Surface(mTexture);
    MediaPlayer mp = new MediaPlayer();
    mp.setSurface(mSurface);
    
  • 我只能播放音频-视频,不能播放

  • 如何获取用于在OpenGL中发送的视频缓冲区
  • 如何在
    GLTexture
    上播放视频

  • 我想你不能。至少我发现了。 我的计划是在播放视频时使用某种OpenGL场景(文本代码)。 由于android使用硬件解码来显示视频,因此OpenGL将无法实现这一点。我还尝试使用ffmpeg在OpenGL中播放视频,但我发现,我使用的任何设备的性能都不足以通过ffmpeg进行SW解码

    所以我不得不用一个视频视图来显示我的视频,并在上面放一个GLSURFACHEVIEW来查看我的股票代码文本。 但您必须使GLSurfaceView半透明,就像Apidmos中使用“半透明GLSurfaceView活动”所做的那样

    我意识到的另一件事是:如果你把一个GLSurfaceView放在一个VideoView之上,你的fps会从60fps(opengl)急剧下降到大约30-40fps。 这适用于我测试的所有2.x版本的android。 上周我有机会在Android 4上测试它,这次我在fps上没有出现故障。也许他们真的改进了IC的图形管道


    您好,-chris-

    来自android源代码

    import java.io.IOException;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
    
    import android.content.Context;
    import android.graphics.SurfaceTexture;
    import android.media.MediaPlayer;
    import android.opengl.GLES20;
    import android.opengl.GLSurfaceView;
    import android.opengl.Matrix;
    import android.util.Log;
    import android.view.Surface;
    
    class VideoSurfaceView extends GLSurfaceView {
    
        VideoRender mRenderer;
        private MediaPlayer mMediaPlayer = null;
    
        public VideoSurfaceView(Context context, MediaPlayer mp) {
            super(context);
    
            setEGLContextClientVersion(2);
            mMediaPlayer = mp;
            mRenderer = new VideoRender(context);
            setRenderer(mRenderer);
        }
    
        @Override
        public void onResume() {
            queueEvent(new Runnable(){
                    public void run() {
                        mRenderer.setMediaPlayer(mMediaPlayer);
                    }});
    
            super.onResume();
        }
    
        private static class VideoRender
            implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
            private static String TAG = "VideoRender";
    
            private static final int FLOAT_SIZE_BYTES = 4;
            private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
            private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
            private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
            private final float[] mTriangleVerticesData = {
                // X, Y, Z, U, V
                -1.0f, -1.0f, 0, 0.f, 0.f,
                1.0f, -1.0f, 0, 1.f, 0.f,
                -1.0f,  1.0f, 0, 0.f, 1.f,
                1.0f,  1.0f, 0, 1.f, 1.f,
            };
    
            private FloatBuffer mTriangleVertices;
    
            private final String mVertexShader =
                    "uniform mat4 uMVPMatrix;\n" +
                    "uniform mat4 uSTMatrix;\n" +
                    "attribute vec4 aPosition;\n" +
                    "attribute vec4 aTextureCoord;\n" +
                    "varying vec2 vTextureCoord;\n" +
                    "void main() {\n" +
                    "  gl_Position = uMVPMatrix * aPosition;\n" +
                    "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
                    "}\n";
    
            private final String mFragmentShader =
                    "#extension GL_OES_EGL_image_external : require\n" +
                    "precision mediump float;\n" +
                    "varying vec2 vTextureCoord;\n" +
                    "uniform samplerExternalOES sTexture;\n" +
                    "void main() {\n" +
                    "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
                    "}\n";
    
            private float[] mMVPMatrix = new float[16];
            private float[] mSTMatrix = new float[16];
    
            private int mProgram;
            private int mTextureID;
            private int muMVPMatrixHandle;
            private int muSTMatrixHandle;
            private int maPositionHandle;
            private int maTextureHandle;
    
            private SurfaceTexture mSurface;
            private boolean updateSurface = false;
    
            private static int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
    
            private MediaPlayer mMediaPlayer;
    
            public VideoRender(Context context) {
                mTriangleVertices = ByteBuffer.allocateDirect(
                    mTriangleVerticesData.length * FLOAT_SIZE_BYTES)
                        .order(ByteOrder.nativeOrder()).asFloatBuffer();
                mTriangleVertices.put(mTriangleVerticesData).position(0);
    
                Matrix.setIdentityM(mSTMatrix, 0);
            }
    
            public void setMediaPlayer(MediaPlayer player) {
                mMediaPlayer = player;
            }
    
            public void onDrawFrame(GL10 glUnused) {
                synchronized(this) {
                    if (updateSurface) {
                        mSurface.updateTexImage();
                        mSurface.getTransformMatrix(mSTMatrix);
                        updateSurface = false;
                    }
                }
    
                GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
                GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
    
                GLES20.glUseProgram(mProgram);
                checkGlError("glUseProgram");
    
                GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
                GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
    
                mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
                GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
                    TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
                checkGlError("glVertexAttribPointer maPosition");
                GLES20.glEnableVertexAttribArray(maPositionHandle);
                checkGlError("glEnableVertexAttribArray maPositionHandle");
    
                mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
                GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false,
                    TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
                checkGlError("glVertexAttribPointer maTextureHandle");
                GLES20.glEnableVertexAttribArray(maTextureHandle);
                checkGlError("glEnableVertexAttribArray maTextureHandle");
    
                Matrix.setIdentityM(mMVPMatrix, 0);
                GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
                GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
    
                GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
                checkGlError("glDrawArrays");
                GLES20.glFinish();
    
            }
    
            public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    
            }
    
            public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
                mProgram = createProgram(mVertexShader, mFragmentShader);
                if (mProgram == 0) {
                    return;
                }
                maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
                checkGlError("glGetAttribLocation aPosition");
                if (maPositionHandle == -1) {
                    throw new RuntimeException("Could not get attrib location for aPosition");
                }
                maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
                checkGlError("glGetAttribLocation aTextureCoord");
                if (maTextureHandle == -1) {
                    throw new RuntimeException("Could not get attrib location for aTextureCoord");
                }
    
                muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
                checkGlError("glGetUniformLocation uMVPMatrix");
                if (muMVPMatrixHandle == -1) {
                    throw new RuntimeException("Could not get attrib location for uMVPMatrix");
                }
    
                muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
                checkGlError("glGetUniformLocation uSTMatrix");
                if (muSTMatrixHandle == -1) {
                    throw new RuntimeException("Could not get attrib location for uSTMatrix");
                }
    
    
                int[] textures = new int[1];
                GLES20.glGenTextures(1, textures, 0);
    
                mTextureID = textures[0];
                GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
                checkGlError("glBindTexture mTextureID");
    
                GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
                                       GLES20.GL_NEAREST);
                GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
                                       GLES20.GL_LINEAR);
    
                /*
                 * Create the SurfaceTexture that will feed this textureID,
                 * and pass it to the MediaPlayer
                 */
                mSurface = new SurfaceTexture(mTextureID);
                mSurface.setOnFrameAvailableListener(this);
    
                Surface surface = new Surface(mSurface);
                mMediaPlayer.setSurface(surface);
                surface.release();
    
                try {
                    mMediaPlayer.prepare();
                } catch (IOException t) {
                    Log.e(TAG, "media player prepare failed");
                }
    
                synchronized(this) {
                    updateSurface = false;
                }
    
                mMediaPlayer.start();
            }
    
            synchronized public void onFrameAvailable(SurfaceTexture surface) {
                updateSurface = true;
            }
    
            private int loadShader(int shaderType, String source) {
                int shader = GLES20.glCreateShader(shaderType);
                if (shader != 0) {
                    GLES20.glShaderSource(shader, source);
                    GLES20.glCompileShader(shader);
                    int[] compiled = new int[1];
                    GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
                    if (compiled[0] == 0) {
                        Log.e(TAG, "Could not compile shader " + shaderType + ":");
                        Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
                        GLES20.glDeleteShader(shader);
                        shader = 0;
                    }
                }
                return shader;
            }
    
            private int createProgram(String vertexSource, String fragmentSource) {
                int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
                if (vertexShader == 0) {
                    return 0;
                }
                int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
                if (pixelShader == 0) {
                    return 0;
                }
    
                int program = GLES20.glCreateProgram();
                if (program != 0) {
                    GLES20.glAttachShader(program, vertexShader);
                    checkGlError("glAttachShader");
                    GLES20.glAttachShader(program, pixelShader);
                    checkGlError("glAttachShader");
                    GLES20.glLinkProgram(program);
                    int[] linkStatus = new int[1];
                    GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
                    if (linkStatus[0] != GLES20.GL_TRUE) {
                        Log.e(TAG, "Could not link program: ");
                        Log.e(TAG, GLES20.glGetProgramInfoLog(program));
                        GLES20.glDeleteProgram(program);
                        program = 0;
                    }
                }
                return program;
            }
    
            private void checkGlError(String op) {
                int error;
                while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
                    Log.e(TAG, op + ": glError " + error);
                    throw new RuntimeException(op + ": glError " + error);
                }
            }
    
        }  // End of class VideoRender.
    
    }  // End of class VideoSurfaceView.
    
    您可以在所需的surfaceTexture上的mediaPlayerObject上使用上述代码行,该surfaceTexture是在surfaceview上应用的纹理


    希望有帮助

    我刚刚将Java转换为Kotlin版本

    internal inline fun <T> glRun(message: String = "", block: (() -> T)): T {
        return block().also {
            var error: Int = GLES20.glGetError()
            while (error != GLES20.GL_NO_ERROR) {
                error = GLES20.glGetError()
                Log.d("MOVIE_GL_ERROR", "$message: $error")
                throw RuntimeException("GL Error: $message")
            }
        }
    }
    
    class MovieRenderer: GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
    
        private var program = 0
        private var textureId = 0
    
        // Handles
        private var mvpMatrixHandle = 0
        private var stMatrixHandle = 0
        private var positionHandle = 0
        private var textureHandle = 0
    
        // Surface Texture
        private var updateSurface = false
        private lateinit var surfaceTexture: SurfaceTexture
    
        // Matrices
        private var mvpMatrix = FloatArray(16)
        private var stMatrix = FloatArray(16)
    
        // float buffer
        private val vertices: FloatBuffer = ByteBuffer.allocateDirect(VERTICES_DATA.size * FLOAT_SIZE_BYTES)
            .order(ByteOrder.nativeOrder())
            .asFloatBuffer().also {
                it.put(VERTICES_DATA).position(0)
            }
    
        var mediaPlayer: MediaPlayer? = null
    
        @Synchronized
        override fun onFrameAvailable(surfaceTexture: SurfaceTexture?) {
            updateSurface = true
        }
    
        override fun onDrawFrame(gl: GL10?) {
            synchronized(this) {
                if (updateSurface) {
                    surfaceTexture.updateTexImage()
                    surfaceTexture.getTransformMatrix(stMatrix)
                    updateSurface = false
                }
            }
    
            GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
            GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT or GLES20.GL_COLOR_BUFFER_BIT)
    
            glRun("glUseProgram: $program") {
                GLES20.glUseProgram(program)
            }
    
            vertices.position(VERTICES_POS_OFFSET);
    
            glRun("glVertexAttribPointer: Stride bytes") {
                GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false,
                    VERTICES_STRIDE_BYTES, vertices)
            }
    
            glRun("glEnableVertexAttribArray") {
                GLES20.glEnableVertexAttribArray(positionHandle)
            }
    
            vertices.position(VERTICES_UV_OFFSET)
    
            glRun("glVertexAttribPointer: texture handle") {
                GLES20.glVertexAttribPointer(textureHandle, 3, GLES20.GL_FLOAT, false,
                    VERTICES_STRIDE_BYTES, vertices)
            }
    
            glRun("glEnableVertexAttribArray") {
                GLES20.glEnableVertexAttribArray(textureHandle)
            }
    
            Matrix.setIdentityM(mvpMatrix, 0)
    
            glRun("glUniformMatrix4fv: mvpMatrix") {
                GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
            }
    
            glRun("glUniformMatrix4fv: stMatrix") {
                GLES20.glUniformMatrix4fv(stMatrixHandle, 1, false, stMatrix, 0)
            }
    
            glRun("glDrawArrays: GL_TRIANGLE_STRIP") {
                GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4)
            }
    
            GLES20.glFinish()
        }
    
        override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
            GLES20.glViewport(0, 0, width, height)
        }
    
        override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
            program = createProgram()
            positionHandle = "aPosition".attr()
            textureHandle = "aTextureCoord".attr()
            mvpMatrixHandle = "uMVPMatrix".uniform()
            stMatrixHandle = "uSTMatrix".uniform()
            createTexture()
        }
    
        private fun createTexture() {
            val textures = IntArray(1)
            GLES20.glGenTextures(1, textures, 0)
            textureId = textures.first()
            glRun("glBindTexture textureId") { GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId) }
    
            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST)
            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR)
    
            surfaceTexture = SurfaceTexture(textureId)
            surfaceTexture.setOnFrameAvailableListener(this)
    
            val surface = Surface(surfaceTexture)
            mediaPlayer?.setSurface(surface)
            surface.release()
    
            try {
                mediaPlayer?.prepare()
            } catch (error: IOException) {
                Log.e("MovieRenderer", "media player prepare failed");
                throw error
            }
    
            synchronized(this) {
                updateSurface = false
            }
    
            mediaPlayer?.start()
        }
    
    
    
        private fun String.attr(): Int {
            return glRun("Get attribute location: $this") {
                GLES20.glGetAttribLocation(program, this).also {
                    if (it == -1) fail("Error Attribute: $this not found!")
                }
            }
        }
    
        private fun String.uniform(): Int {
            return glRun("Get uniform location: $this") {
                GLES20.glGetUniformLocation(program, this).also {
                    if (it == -1) fail("Error Uniform: $this not found!")
                }
            }
        }
    
        companion object {
            private const val GL_TEXTURE_EXTERNAL_OES = 0x8D65
    
            private const val FLOAT_SIZE_BYTES = 4
            private const val VERTICES_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES
            private const val VERTICES_POS_OFFSET = 0
            private const val VERTICES_UV_OFFSET = 3
    
            private val VERTICES_DATA = floatArrayOf(
                -1.0f, -1.0f, 0f, 0.0f, 0.0f,
                1.0f, -1.0f, 0f, 1.0f, 0.0f,
                -1.0f,  1.0f, 0f, 0.0f, 1.0f,
                1.0f,  1.0f, 0f, 1.0f, 1.0f
            )
    
            private const val VERTEX_SHADER = """
                uniform mat4 uMVPMatrix;
                uniform mat4 uSTMatrix;
                attribute vec4 aPosition;
                attribute vec4 aTextureCoord;
                varying vec2 vTextureCoord;
                void main() {
                    gl_Position = uMVPMatrix * aPosition;
                    vTextureCoord = (uSTMatrix * aTextureCoord).xy;
                }
            """
    
            private const val FRAGMENT_SHADER = """
                #extension GL_OES_EGL_image_external : require
                precision mediump float;
                varying vec2 vTextureCoord;
                uniform samplerExternalOES sTexture;
                void main() {
                  gl_FragColor = texture2D(sTexture, vTextureCoord);
                }
            """
    
            private fun createShader(type: Int, source: String): Int {
                val shader = GLES20.glCreateShader(type)
                if (shader == 0) throw RuntimeException("Cannot create shader $type\n$source")
                GLES20.glShaderSource(shader, source)
                GLES20.glCompileShader(shader)
    
                val args = IntArray(1)
                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, args, 0)
                if (args.first() == 0) {
                    Log.e("MOVIE_SHADER", "Failed to compile shader source")
                    Log.e("MOVIE_SHADER", GLES20.glGetShaderInfoLog(shader))
                    GLES20.glDeleteShader(shader)
                    throw RuntimeException("Could not compile shader $source\n$type")
                }
    
                return shader
            }
    
            private fun createProgram(vertexShaderSource: String = VERTEX_SHADER,
                                      fragmentShaderSource: String = FRAGMENT_SHADER): Int {
    
                val vertexShader = createShader(GLES20.GL_VERTEX_SHADER, vertexShaderSource)
                val fragmentShader = createShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderSource)
    
                val program = GLES20.glCreateProgram()
                if (program == 0) throw RuntimeException("Cannot create program")
    
                glRun("Attach vertex shader to program") {
                    GLES20.glAttachShader(program, vertexShader)
                }
    
                glRun("Attach fragment shader to program") {
                    GLES20.glAttachShader(program, fragmentShader)
                }
    
                GLES20.glLinkProgram(program)
                val args = IntArray(1)
                GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, args, 0)
    
                if (args.first() != GLES20.GL_TRUE) {
                    val info = GLES20.glGetProgramInfoLog(program)
                    GLES20.glDeleteProgram(program)
                    throw RuntimeException("Cannot link program $program, Info: $info")
                }
    
                return program
            }
    
    
            private fun fail(message: String): Nothing {
                throw RuntimeException(message)
            }
    
        }
    }
    
    internal-inline-fun-glRun(message:String=”“,block:(()->T)):T{
    返回块(){
    变量错误:Int=GLES20.glGetError()
    while(error!=GLES20.GL\u无错误){
    error=GLES20.glGetError()
    Log.d(“MOVIE\u GL\u ERROR”,“$message:$ERROR”)
    抛出运行时异常(“GL错误:$message”)
    }
    }
    }
    类MovieRenderer:GLSurfaceView.Renderer,SurfaceTexture.OnFrameAvailableListener{
    专用var程序=0
    私有变量textureId=0
    //处理
    私有变量mvpMatrixHandle=0
    私有变量stMatrix Handle=0
    私有变量positionHandle=0
    私有变量textureHandle=0
    //表面结构
    private var updateSurface=false
    私有lateinit var surfaceTexture:surfaceTexture
    //矩阵
    私有变量MVP矩阵=浮点数组(16)
    私有变量stMatrix=FloatArray(16)
    //浮动缓冲器
    私有val顶点:FloatBuffer=ByteBuffer.allocateDirect(顶点\u DATA.size*浮点\u大小\u字节)
    .order(ByteOrder.nativeOrder())
    .asFloatBuffer()。同时{
    it.put(顶点数据).position(0)
    }
    变量mediaPlayer:mediaPlayer?=null
    @同步的
    覆盖框架可用(surfaceTexture:surfaceTexture?){
    updateSurface=true
    }
    覆盖图框(gl:GL10?){
    已同步(此){
    if(updateSurface){
    SurfacetTexture.UpdateMaximage()
    SurfacetTexture.getTransformMatrix(stMatrix)
    updateSurface=false
    }
    }
    GLES20.glClearColor(0.0f、0.0f、0.0f、1.0f)
    GLES20.glClear(GLES20.GL_深度_缓冲位或GLES20.GL_颜色_缓冲位)
    glRun(“glUseProgram:$program”){
    GLES20.glUseProgram(程序)
    }
    顶点位置(顶点位置偏移);
    glRun(“glvertexattributepointer:Stride字节”){
    GLES20.GlvertexAttribute指针(位置手柄,3,GLES20.GL_浮点,假,
    顶点\u步长\u字节,顶点)
    }
    glRun(“GlenableVertexAttributeArray”){
    GLES20.GlenableVertexAttribute数组(位置句柄)
    }
    顶点.位置(顶点\u UV\u偏移)
    glRun(“glvertexattributepointer:纹理句柄”){
    GLES20.glVertexAttribute指针(textureHandle,3,GLES20.GL_FLOAT,false,
    顶点\u步长\u字节,顶点)
    }
    glRun(“GlenableVertexAttributeArray”){
    GLES20.GlenableVertexAttribute数组(纹理句柄)
    }
    矩阵setIdentityM(MVP矩阵,0)
    glRun(“glUniformMatrix4fv:mvpMatrix”){
    GLES20.glUniformMatrix4fv(mvpMatrixHandle,1,false,mvpMatrix,0)
    }
    glRun(“glUniformMatrix4fv:stMatrix”){
    GLES20.glUniformMatrix4fv(stMatrix Handle,1,false,stMatrix,0)
    }
    glRun(“glDrawArrays:GL\U三角形\U带”){
    GLES20.GlDrawArray(GLES20.GL_三角形_带,0,4)
    }
    GLES20.glFinish()
    }
    更改了曲面上的覆盖(gl:GL10?,宽度:Int,高度:Int){
    GLES20.glViewport(0,0,宽度,高度)
    }
    覆盖已创建的曲面(gl:GL10?,配置:EGLConfig?){
    program=createProgram()
    positionHandle=“aPosition”.attr()
    textureHandle=“atexturecord”.attr()
    mvpMatrixHandle=“uMVPMatrix”.uniform()
    stmatrix handle=“uSTMatrix”.uniform()
    createTexture()
    }
    private fun createTexture(){
    val纹理=阵列(1)
    GLES20.glGenTextures(1,纹理,0)
    textureId=纹理。第一个()
    glRun(“glBindTexture textureId”){GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES,textureId)}
    GLES20.glTexParameteri(GL_纹理_外部_OES,GLES20.GL_纹理_最小_过滤器,GLES20.GL_最近)
    GLES20.glTexParameteri(GL_纹理_外部_OES,GLES20.GL_纹理_MAG_过滤器,GLES20.GL_线性)
    surfaceTexture=surfaceTexture(textureId)
    surfaceTexture.setOnFrameAvailableListener(此)
    val表面=表面(表面纹理)
    mediaPlayer?.setSurface(表面)
    表面。释放()
    试一试{
    mediaPlayer?.prepare()
    }捕获(错误:IOException){
    Log.e(“电影制作人”、“媒体播放器准备失败”);
    
    internal inline fun <T> glRun(message: String = "", block: (() -> T)): T {
        return block().also {
            var error: Int = GLES20.glGetError()
            while (error != GLES20.GL_NO_ERROR) {
                error = GLES20.glGetError()
                Log.d("MOVIE_GL_ERROR", "$message: $error")
                throw RuntimeException("GL Error: $message")
            }
        }
    }
    
    class MovieRenderer: GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
    
        private var program = 0
        private var textureId = 0
    
        // Handles
        private var mvpMatrixHandle = 0
        private var stMatrixHandle = 0
        private var positionHandle = 0
        private var textureHandle = 0
    
        // Surface Texture
        private var updateSurface = false
        private lateinit var surfaceTexture: SurfaceTexture
    
        // Matrices
        private var mvpMatrix = FloatArray(16)
        private var stMatrix = FloatArray(16)
    
        // float buffer
        private val vertices: FloatBuffer = ByteBuffer.allocateDirect(VERTICES_DATA.size * FLOAT_SIZE_BYTES)
            .order(ByteOrder.nativeOrder())
            .asFloatBuffer().also {
                it.put(VERTICES_DATA).position(0)
            }
    
        var mediaPlayer: MediaPlayer? = null
    
        @Synchronized
        override fun onFrameAvailable(surfaceTexture: SurfaceTexture?) {
            updateSurface = true
        }
    
        override fun onDrawFrame(gl: GL10?) {
            synchronized(this) {
                if (updateSurface) {
                    surfaceTexture.updateTexImage()
                    surfaceTexture.getTransformMatrix(stMatrix)
                    updateSurface = false
                }
            }
    
            GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
            GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT or GLES20.GL_COLOR_BUFFER_BIT)
    
            glRun("glUseProgram: $program") {
                GLES20.glUseProgram(program)
            }
    
            vertices.position(VERTICES_POS_OFFSET);
    
            glRun("glVertexAttribPointer: Stride bytes") {
                GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false,
                    VERTICES_STRIDE_BYTES, vertices)
            }
    
            glRun("glEnableVertexAttribArray") {
                GLES20.glEnableVertexAttribArray(positionHandle)
            }
    
            vertices.position(VERTICES_UV_OFFSET)
    
            glRun("glVertexAttribPointer: texture handle") {
                GLES20.glVertexAttribPointer(textureHandle, 3, GLES20.GL_FLOAT, false,
                    VERTICES_STRIDE_BYTES, vertices)
            }
    
            glRun("glEnableVertexAttribArray") {
                GLES20.glEnableVertexAttribArray(textureHandle)
            }
    
            Matrix.setIdentityM(mvpMatrix, 0)
    
            glRun("glUniformMatrix4fv: mvpMatrix") {
                GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0)
            }
    
            glRun("glUniformMatrix4fv: stMatrix") {
                GLES20.glUniformMatrix4fv(stMatrixHandle, 1, false, stMatrix, 0)
            }
    
            glRun("glDrawArrays: GL_TRIANGLE_STRIP") {
                GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4)
            }
    
            GLES20.glFinish()
        }
    
        override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
            GLES20.glViewport(0, 0, width, height)
        }
    
        override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
            program = createProgram()
            positionHandle = "aPosition".attr()
            textureHandle = "aTextureCoord".attr()
            mvpMatrixHandle = "uMVPMatrix".uniform()
            stMatrixHandle = "uSTMatrix".uniform()
            createTexture()
        }
    
        private fun createTexture() {
            val textures = IntArray(1)
            GLES20.glGenTextures(1, textures, 0)
            textureId = textures.first()
            glRun("glBindTexture textureId") { GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId) }
    
            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST)
            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR)
    
            surfaceTexture = SurfaceTexture(textureId)
            surfaceTexture.setOnFrameAvailableListener(this)
    
            val surface = Surface(surfaceTexture)
            mediaPlayer?.setSurface(surface)
            surface.release()
    
            try {
                mediaPlayer?.prepare()
            } catch (error: IOException) {
                Log.e("MovieRenderer", "media player prepare failed");
                throw error
            }
    
            synchronized(this) {
                updateSurface = false
            }
    
            mediaPlayer?.start()
        }
    
    
    
        private fun String.attr(): Int {
            return glRun("Get attribute location: $this") {
                GLES20.glGetAttribLocation(program, this).also {
                    if (it == -1) fail("Error Attribute: $this not found!")
                }
            }
        }
    
        private fun String.uniform(): Int {
            return glRun("Get uniform location: $this") {
                GLES20.glGetUniformLocation(program, this).also {
                    if (it == -1) fail("Error Uniform: $this not found!")
                }
            }
        }
    
        companion object {
            private const val GL_TEXTURE_EXTERNAL_OES = 0x8D65
    
            private const val FLOAT_SIZE_BYTES = 4
            private const val VERTICES_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES
            private const val VERTICES_POS_OFFSET = 0
            private const val VERTICES_UV_OFFSET = 3
    
            private val VERTICES_DATA = floatArrayOf(
                -1.0f, -1.0f, 0f, 0.0f, 0.0f,
                1.0f, -1.0f, 0f, 1.0f, 0.0f,
                -1.0f,  1.0f, 0f, 0.0f, 1.0f,
                1.0f,  1.0f, 0f, 1.0f, 1.0f
            )
    
            private const val VERTEX_SHADER = """
                uniform mat4 uMVPMatrix;
                uniform mat4 uSTMatrix;
                attribute vec4 aPosition;
                attribute vec4 aTextureCoord;
                varying vec2 vTextureCoord;
                void main() {
                    gl_Position = uMVPMatrix * aPosition;
                    vTextureCoord = (uSTMatrix * aTextureCoord).xy;
                }
            """
    
            private const val FRAGMENT_SHADER = """
                #extension GL_OES_EGL_image_external : require
                precision mediump float;
                varying vec2 vTextureCoord;
                uniform samplerExternalOES sTexture;
                void main() {
                  gl_FragColor = texture2D(sTexture, vTextureCoord);
                }
            """
    
            private fun createShader(type: Int, source: String): Int {
                val shader = GLES20.glCreateShader(type)
                if (shader == 0) throw RuntimeException("Cannot create shader $type\n$source")
                GLES20.glShaderSource(shader, source)
                GLES20.glCompileShader(shader)
    
                val args = IntArray(1)
                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, args, 0)
                if (args.first() == 0) {
                    Log.e("MOVIE_SHADER", "Failed to compile shader source")
                    Log.e("MOVIE_SHADER", GLES20.glGetShaderInfoLog(shader))
                    GLES20.glDeleteShader(shader)
                    throw RuntimeException("Could not compile shader $source\n$type")
                }
    
                return shader
            }
    
            private fun createProgram(vertexShaderSource: String = VERTEX_SHADER,
                                      fragmentShaderSource: String = FRAGMENT_SHADER): Int {
    
                val vertexShader = createShader(GLES20.GL_VERTEX_SHADER, vertexShaderSource)
                val fragmentShader = createShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderSource)
    
                val program = GLES20.glCreateProgram()
                if (program == 0) throw RuntimeException("Cannot create program")
    
                glRun("Attach vertex shader to program") {
                    GLES20.glAttachShader(program, vertexShader)
                }
    
                glRun("Attach fragment shader to program") {
                    GLES20.glAttachShader(program, fragmentShader)
                }
    
                GLES20.glLinkProgram(program)
                val args = IntArray(1)
                GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, args, 0)
    
                if (args.first() != GLES20.GL_TRUE) {
                    val info = GLES20.glGetProgramInfoLog(program)
                    GLES20.glDeleteProgram(program)
                    throw RuntimeException("Cannot link program $program, Info: $info")
                }
    
                return program
            }
    
    
            private fun fail(message: String): Nothing {
                throw RuntimeException(message)
            }
    
        }
    }