使用Android的OpenGL編寫視頻播放器


  Android自身有MediaPlayer播放器,為什么還要使用OpenGL?因為使用OpenGL可以實現更多的效果,比如對視頻翻轉一定角度,加任意特效,多視頻合並播放等,類似“激萌”的APP應該就是這樣做的;相比之下,直接調用MediaPlayer的功能就少太多了。

  OpenGL ES剔除了OpenGL中四邊形和多邊形的部分,即ES版本只支持三角形的繪制。使用分為三個步驟:

  • 創建GLSurfaceView組件,使用Activity來顯示GLSurfaceView;
  • 為GLSurfaceView組件創建GLSurfaceView.Renderer實例,實現GLSurfaceViewRenderer類的三個接口:
// 真正繪制的函數
abstract void onDrawFrame(GL10 gl); // 當GLSurfaceView的大小改變時回調,如橫屏豎屏切換
abstract void onSurfaceChanged(GL10 gl, int width, int height); // 當GLSurfaceView被創建時回調
abstract void onSurfaceCreated(GL10 gl, EGLConfig config);
  • 調用GLSurfaceView組件的setRenderer()方法指定Renderer對象。

  由以上三個步驟,可以編寫OpenGL的渲染框架如下:

public class SampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 創建一個GLSurfaceView,用於顯示OpenGL繪制的圖形
        GLSurfaceView glView = new GLSurfaceView(this); // 創建GLSurfaceView的內容繪制器
        SampleRender myRender = new SampleRender(); // 為GLSurfaceView設置繪制器
 glView.setRenderer(myRender); setContentView(glView); } }
public class SampleRender implements Renderer { @Override public void onDrawFrame(GL10 gl) { // 清除屏幕緩存和深度緩存
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 啟用頂點座標數據
 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 啟用頂點顏色數據
 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); // 設置當前矩陣堆棧為模型堆棧,
 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置當前的模型視圖矩陣
 gl.glLoadIdentity(); gl.glTranslatef(0.6f, 0.8f, -1.5f); gl.glRotatef(rotate, 0f, 0.1f, 0f); // 設置頂點的位置數據
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, rectDataBuffer); // 設置頂點的顏色數據
        gl.glColorPointer(4, GL10.GL_FIXED, 0, rectColorBuffer); // 根據頂點數據繪制平面圖形
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); // 繪制結束
 gl.glFinish(); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); } }

   在此渲染框架的基礎上,使用MediaPlayer播放視頻,調用MediaPlayer的setSurface()函數set到一個surface上。

    SurfaceTexture mSurfaceTexture = new SurfaceTexture(textureName);
    Surface mSurface = new Surface(mSurfaceTexture);
    mMediaPlayer.setSurface(mSurface);
    mMediaPlayer.setDataSource(fileName);
    mMediaPlayer.prepareAsync();

  這樣,播放器播放的視頻都顯示到了我們設置的texture上,然后調用GLES20.glBindTexture(render.GL_TEXTURE_EXTERNAL_OES,textureName);綁定紋理,將紋理顯示出來即可。剩下的就是對SurfaceTexture做伸縮,分屏,加特效圖片等具體的業務了。     

  GLSurfaceView自帶渲染線程,如果不使用默認的渲染線程,需要進行如下設置,之后調用requestRender()手動渲染:

setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

  自行設計定時器渲染的話,注意保證定時精度,如果精度太小而機器性能有限,可以使用多個定時器大粒度交叉渲染的方式保證30幀每秒的渲染頻率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM