I have a fully functional app using this videoRenderer 
internal class VideoRenderer {
    private var pos_coord_box :Int32 = 0
    private var pos_tex_box:Int32 = 0
    private var pos_trans_box:Int32 = 0
    private var pos_proj_box:Int32 = 0
    private var vbo_coord_box: GLuint = 0
    private var vbo_tex_box: GLuint = 0
    private var vbo_face_box: GLuint = 0
    
    private var program_box: GLuint = 0
    private var texture_id: GLuint = 0
    private var vertShader: GLuint = 0
    private var fragShader: GLuint = 0
    
    init(){
        let box_video_vert=""
            + "uniform mat4 trans; \n"
            + "uniform mat4 proj; \n"
            + "attribute vec4 coord; \n"
            + "attribute vec2 texcoord; \n"
            + "varying vec2 vtexcoord; \n\n"
            + "void main(void)\n"
            + "{\n"
            + "    vtexcoord = texcoord;\n"
            + "    gl_Position = proj*trans*coord;\n"
            + "}\n"
            + "\n"
        let box_video_frag=""
            + "#ifdef GL_ES \n"
            + "precision highp float; \n"
            + "#endif \n"
            + "varying vec2 vtexcoord; \n"
            + "uniform sampler2D texture; \n\n"
            
            + "void main(void) \n"
            + "{"
            + "\n   gl_FragColor = texture2D(texture, vtexcoord);\n"
            + "}"
            + "\n\n"
        program_box = glCreateProgram()
        
        /**Initialize verticle shader **/
        vertShader = glCreateShader(GLenum(GL_VERTEX_SHADER))
        box_video_vert.utf8CString.withUnsafeBufferPointer { p in
            var s = p.baseAddress
            glShaderSource(vertShader, 1, &s, nil)
        }
        glCompileShader(vertShader);
        /**Initialize fragment shader **/
        fragShader = glCreateShader(GLenum(GL_FRAGMENT_SHADER))
        box_video_frag.utf8CString.withUnsafeBufferPointer { p in
            var s = p.baseAddress
            glShaderSource(fragShader, 1, &s, nil)
        }
        glCompileShader(fragShader)
        /**Attach both shaders to program **/
        glAttachShader(program_box, vertShader);
        glAttachShader(program_box, fragShader);
    
        glLinkProgram(program_box);
        glUseProgram(program_box);
        glDetachShader(program_box, vertShader)
        glDeleteShader(vertShader)
        glDetachShader(program_box, fragShader)
        glDeleteShader(fragShader)
        
        pos_coord_box = glGetAttribLocation(program_box, "coord");
        pos_tex_box = glGetAttribLocation(program_box, "texcoord");
        pos_trans_box = glGetUniformLocation(program_box, "trans");
        pos_proj_box = glGetUniformLocation(program_box, "proj");
        //Set the plane four corners
        vbo_coord_box = 0
        glGenBuffers(1, &vbo_coord_box);
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_coord_box)
//        let cube_vertices:[[GLfloat]] = [[(1.0 / 2), (1.0 / 2), 0.0], [(1.0 / 2), (-1.0 / 2), 0.0],[ (-1.0 / 2), (-1.0 / 2), 0.0],[ (-1.0 / 2), (1.0 / 2), 0.0]] //4x3
        let cube_vertices:[GLfloat] = [1.0 / 2, 1.0 / 2, 0.0, 1.0 / 2, -1.0 / 2, 0.0, -1.0 / 2, -1.0 / 2, 0.0, -1.0 / 2, 1.0 / 2, 0.0] //4x3
        cube_vertices.withUnsafeBytes { p in
            glBufferData(GLenum(GL_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_DYNAMIC_DRAW))
        }
        //Set the plane four Side
        vbo_tex_box = 0
        glGenBuffers(1, &vbo_tex_box);
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_tex_box)
        let cube_vertex_texs : [GLubyte] = [0, 0, 0, 1, 1, 1, 1, 0]
        cube_vertex_texs.withUnsafeBytes { p in
            glBufferData(GLenum(GL_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_STATIC_DRAW))
        }
        //Set the face
        vbo_face_box = 0
        glGenBuffers(1, &vbo_face_box);
        glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), vbo_face_box);
        let cube_faces : [GLushort] = [3, 2, 1, 0]
        cube_faces.withUnsafeBytes { p in
            glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_STATIC_DRAW))
        }
        //Create the texture
        glUniform1i(glGetUniformLocation(program_box, "texture"), 0);
        texture_id = 0
        glGenTextures(1, &texture_id);
        glBindTexture(GLenum(GL_TEXTURE_2D), texture_id);
        glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR);
        glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR);
        glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE);
        glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE);
    }
    public func render(_ projectionMatrix:Matrix44F, _ cameraview:Matrix44F, _ size:Vec2F)
    {
        
        let (size0, size1) = size.data
        //Adjust the four corners
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_coord_box)
        let cube_vertices:[GLfloat] = [size0 / 2, size1 / 2,  0.0,  size0 / 2, -size1 / 2,  0.0, -size0 / 2, -size1 / 2,  0.0,  -size0 / 2,  size1 / 2,  0.0]
        cube_vertices.withUnsafeBytes { p in
            glBufferData(GLenum(GL_ARRAY_BUFFER), p.count, p.baseAddress, GLenum(GL_DYNAMIC_DRAW))
        }
        glEnable(GLenum(GL_BLEND));
        glBlendFunc(GLenum(GL_SRC_ALPHA), GLenum(GL_ONE_MINUS_SRC_ALPHA));
        glEnable(GLenum(GL_DEPTH_TEST));
        glUseProgram(program_box);
        
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_coord_box);
        glEnableVertexAttribArray(GLuint(pos_coord_box));
        glVertexAttribPointer(GLuint(pos_coord_box), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 0, nil);
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), vbo_tex_box);
        glEnableVertexAttribArray(GLuint(pos_tex_box));
        glVertexAttribPointer(GLuint(pos_tex_box), 2, GLenum(GL_UNSIGNED_BYTE), GLboolean(GL_FALSE), 0, nil);
        var cameraview_data = cameraview.data
        var projectionMatrix_data = projectionMatrix.data
        
        withUnsafePointer(to: &cameraview_data) { p in
            glUniformMatrix4fv(pos_trans_box, 1, GLboolean(GL_FALSE), UnsafePointer<GLfloat>(OpaquePointer(p)))
        }
        withUnsafePointer(to: &projectionMatrix_data) { p in
            glUniformMatrix4fv(pos_proj_box, 1, GLboolean(GL_FALSE), UnsafePointer<GLfloat>(OpaquePointer(p)))
        }
        glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), vbo_face_box);
        glActiveTexture(GLenum(GL_TEXTURE0));
        glBindTexture(GLenum(GL_TEXTURE_2D), texture_id);
        glDrawElements(GLenum(GL_TRIANGLE_FAN), 4, GLenum(GL_UNSIGNED_SHORT), nil)
        
        glBindTexture(GLenum(GL_TEXTURE_2D), 0);
        
        glFlush()
    }
    public func texid()->GLuint{
        return texture_id
    }
    public func dispose(){
        glDeleteProgram(program_box)
    }
}