android mediaPlayer的基本使用

1、MediaPlayer的生命周期

MediaPlayer的狀態(tài)圖

有兩種類型的弧,單箭頭表示的是同步方法調(diào)用,有兩個箭頭代表異步方法調(diào)用

1、Idle 狀態(tài)及End 狀態(tài)
當使用new()方法創(chuàng)建一個MediaPlayer對象或者調(diào)用了其reset()方法時,該MediaPlayer對象處于idle狀態(tài)。release()方法調(diào)用后進入End狀態(tài)。

2、Initialized 狀態(tài)
setDataSource()調(diào)用之后,MediaPlayer就進入Initialized狀態(tài),表示要播放的文件已經(jīng)設置好了。如果setDataSource()在MediaPlayer的非Idle 狀態(tài)調(diào)用,會拋出IllegalStateException異常

3、Prepared狀態(tài)
MediaPlayer準備好了

  • prepare():同步方法,調(diào)用這個方法,MediaPlayer就進入Prepared狀態(tài)
  • prepareAsync():異步方法,經(jīng)過Preparing 狀態(tài),在準備工作結束之后,進入Prepared狀態(tài),會回調(diào)OnPreparedListener.onPrepared()。

在Prepared狀態(tài)之后,就可以調(diào)用MediaPlayer的一些set方法了,如,setScreenOnWhilePlaying()、setVolume()、setLooping()。

4、Started 狀態(tài),Paused 狀態(tài)
MediaPlayer準備好之后,調(diào)用start()方法,此時MediaPlayer就處于Started狀態(tài);調(diào)用pause()方法,MediaPlayer進入Paused狀態(tài)。

如果注冊過OnBufferingUpdateListener,在Started 狀態(tài)時,MediaPlayer就會回調(diào)onBufferingUpdate()方法,可以使應用程序保持跟蹤視頻流的緩沖

5、Stopped 狀態(tài)
MediaPlayer處于Started 、Paused 、Prepared、PlaybackCompleted狀態(tài)下,均可調(diào)用stop()停止MediaPlayer,而處于Stopped狀態(tài)的MediaPlayer要想重新播放,需要通過prepareAsync()(prepare())方法回到Prepared狀態(tài)才可以。

6、PlaybackCompleted狀態(tài)
文件正常播放完畢,而又沒有設置循環(huán)播放的話就進入該狀態(tài),并會觸發(fā)OnCompletionListener的onCompletion()方法。

7、Error 狀態(tài)
如果由于某種原因MediaPlayer出現(xiàn)了錯誤,會觸發(fā)OnErrorListener.onError()事件,此時MediaPlayer即進入Error狀態(tài)

注意:
1、MediaPlayer會消耗系統(tǒng)的資源,需要在適當?shù)臅r候把不需要的資源釋放掉。例如,如果在Activity中調(diào)用onStop()方法時,需要釋放MediaPlayer。當Activity恢復或者重新啟動時,需要創(chuàng)建一個新的MediaPlayer并且重新準備。

釋放MediaPlayer

   mediaPlayer.release(); 
   mediaPlayer = null;

2、SurfaceView

SurfaceView是配合MediaPlayer,將一幀一幀的圖像,顯示在界面上。

指定MediaPlayer顯示圖像

void setDisplay(SurfaceHolder holder)
  • SurfaceHolder可以理解為SurfaceView裝載需要顯示的一幀幀圖像的容器,它可以通過SurfaceHolder.getHolder()方法獲得。
  • SurfaceView,通過雙緩沖的機制來顯示幀圖像。雙緩沖可以理解為有兩個線程輪番去 解析視頻流的幀圖像,當一個線程解析完幀圖像后,把圖像渲染到界面中,同時另一線程開始解析下一幀圖像,使得兩個線程輪番配合去解析視頻流,以達到流暢播放的效果。
  • SurfaceView內(nèi)部實現(xiàn)了雙緩沖的機制,但是實現(xiàn)這個功能是非常消耗系統(tǒng)內(nèi)存的。因為移動設備的局限性,Android在設計的時候規(guī) 定,SurfaceView如果為用戶可見的時候,創(chuàng)建SurfaceView的SurfaceHolder用于顯示視頻流解析的幀圖片,如果發(fā)現(xiàn) SurfaceView變?yōu)橛脩舨豢梢姷臅r候,則立即銷毀SurfaceView的SurfaceHolder,以達到節(jié)約系統(tǒng)資源的目的。所以,需要去維護一個SurfaceHolder,需要用到它的一個回調(diào),SurfaceHolder.Callback()
   public interface Callback {
       public void surfaceCreated(SurfaceHolder holder);
       public void surfaceChanged(SurfaceHolder holder, int format, int width, int height);
       public void surfaceDestroyed(SurfaceHolder holder);
   }

3、使用

   /**
    * todo public
    * 加載視頻
    */
   public void loadAndPlay(String videoUrl){
       this.videoUrl=videoUrl;
       surfaceView.getHolder().setKeepScreenOn(true);
       surfaceView.getHolder().addCallback(new SurfaceViewCallback());
   }


   /**
    * 當用戶不可見的時候 ,SurfaceHolder 就會銷毀,當再次可見的時候,會創(chuàng)建新的SurfaceHolder;
    * 使用SurfaceHolder.Callback()維護一個SurfaceHolder
    */
   class SurfaceViewCallback implements SurfaceHolder.Callback {
       @Override
       public void surfaceCreated(SurfaceHolder holder) {
           if(mediaPlayer==null){
               mediaPlayer=new MediaPlayer();
               mediaPlayer.setDataSource(videoUrl);
               mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
               mediaPlayer.setOnPreparedListener(this);
               mediaPlayer.setOnBufferingUpdateListener(this);
               mediaPlayer.setOnErrorListener(this);
               mediaPlayer.setOnCompletionListener(new MediaPlayerCompletion());
               mediaPlayer.prepareAsync();
               mediaPlayer.setDisplay(surfaceView.getHolder());
           }
       }

       @Override
       public void surfaceDestroyed(SurfaceHolder holder) {
           isVideoPrepared=false;
           if(mediaPlayer!=null){
               mediaPlayer.release();
               mediaPlayer=null;
           }
         
       }

   }

   /**
    * 視頻準備好回調(diào)
    */
   @Override
   public void onPrepared(MediaPlayer mp) {
       isVideoPrepared=true;
       mediaPlayer.start();
       mediaPlayer.setScreenOnWhilePlaying(true);
   }

   private boolean isVideoPrepared;

S70326-182808.jpg

Android Multimedia框架總結(一)MediaPlayer介紹之狀態(tài)圖及生命周期Android Multimedia框架總結(三)MediaPlayer中創(chuàng)建到setDataSource過程

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容