天天看點

Android開發之Mediaplayer

 android提供了常見的音頻、視訊的編碼、解碼機制。借助于多媒體類mediaplayer的支援,開發人員可以很友善在在應用中播放音頻、視訊。本篇部落客要講解在android平台下如何播放一個音頻檔案。

  本篇部落客要内容如下:

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#mediaplayer">mediaplayer</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#audiosource">mediaplayer的音頻源</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#usermediaplayer">使用mediaplayer播放音樂</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#userskill">mediaplayer使用技巧</a>

<a target="_blank" href="http://www.cnblogs.com/plokmju/p/android_mediaplayer.html#mp3demo">demo--一個簡單的mp3播放器</a>

mediaplayer

  上面提到過,android下對于音頻、視訊的支援均需要使用到mediaplayer,它主要用來控制android下播放檔案或流的類。mediaplayer處于android多媒體包下"android.media.mediaplayer",僅有一個無參的構造函數,雖然僅為我們提供了一個無參的構造函數,為了友善我們初始化,還為我們提供了幾個靜态的create()方法用于完成mediaplayer初始化的工作。

static mediaplayer create(context context,int resid):通過音頻資源的id來建立一個mediaplayer執行個體。

static mediaplayer create(context context,uri uri):通過一個音頻資源的uri位址來建立一個mediaplayer執行個體。

  mediaplayer除了通過上面兩個create()方法在初始化的時候指定媒體資源,還可以通過mediaplayer.setdatasource()方法為初始化後的mediaplayer設定媒體資源,setdatasource()具有多個重載函數,适用于不同的媒體資源來源,以下講解幾個常用的,其他的可以查閱官方文檔。

void setdatasource(string path):通過一個媒體資源的位址指定mediaplayer的資料源,這裡的path可以是一個本地路徑,也可以是網絡路徑。

void setdatasource(context context,uri uri):通過一個uri指定mediaplayer的資料源,這裡的uri可以是網絡路徑或這一個内容提供者的uri。

void setdatasource(filedescriptor fd):通過一個filedescriptor指定一個mediaplayer的資料源。

  通過上面介紹的初始化mediaplayer的播放時媒體資料源的方法可以看出,mediaplayer支援的資料源有:本地檔案、内部的uri(内容提供者)、外部uri。

  如,設定一個本地sd卡的資源:

  注意讀記憶體卡,還需要設定通路記憶體卡的權限:

  如,設定一個外部uri的網絡流媒體資源:

  如果通路網絡流媒體資源,還需要設定通路網絡的權限:

  mediaplayer其實是一個封裝的很好的音頻、視訊流媒體操作類,如果檢視其源碼,會發現其内部是調用的native方法,是以它其實是有c++實作的。

  既然是一個流媒體操作類,那麼必然涉及到,播放、暫停、停止等操作,實際上mediaplayer也為我們提供了相應的方法來直接操作流媒體。

void start():開始或恢複播放。

void stop():停止播放。

void pause():暫停播放。  

  通過上面三個方法,隻要設定好流媒體資料源,即可在應用中播放流媒體資源,為了更好的操作流媒體,mediaplayer還為我們提供了一些其他的方法,這裡列出一些常用的,詳細内容參閱官方文檔。

int getduration():擷取流媒體的總播放時長,機關是毫秒。

int getcurrentposition():擷取目前流媒體的播放的位置,機關是毫秒。

void seekto(int msec):設定目前mediaplayer的播放位置,機關是毫秒。

void setlooping(boolean looping):設定是否循環播放。

boolean islooping():判斷是否循環播放。

boolean  isplaying():判斷是否正在播放。

void prepare():同步的方式裝載流媒體檔案。

void prepareasync():異步的方式裝載流媒體檔案。

void release ():回收流媒體資源。 

void setaudiostreamtype(int streamtype):設定播放流媒體類型。

void setwakemode(context context, int mode):設定cpu喚醒的狀态。

setnextmediaplayer(mediaplayer next):設定目前流媒體播放完畢,下一個播放的mediaplayer。

  大部分方法的看方法名就可以了解,但是有幾個方法需要單獨說明一下。

  在使用mediaplayer播放一段流媒體的時候,需要使用prepare()或prepareasync()方法把流媒體裝載進mediaplayer,才可以調用start()方法播放流媒體。                 

  setaudiostreamtype()方法用于指定播放流媒體的類型,它傳遞的是一個int類型的資料,均以常量定義在audiomanager類中, 一般我們播放音頻檔案,設定為audiomanager.stream_music即可。

  

  除了上面介紹的一些方法外,mediaplayer還提供了一些事件的回調函數,這裡介紹幾個常用的:

setoncompletionlistener(mediaplayer.oncompletionlistener listener):當流媒體播放完畢的時候回調。

setonerrorlistener(mediaplayer.onerrorlistener listener):當播放中發生錯誤的時候回調。

setonpreparedlistener(mediaplayer.onpreparedlistener listener):當裝載流媒體完畢的時候回調。

setonseekcompletelistener(mediaplayer.onseekcompletelistener listener):當使用seekto()設定播放位置的時候回調。

  在使用mediaplayer的使用過程中,有個小技巧需要說明一下:

  1、在使用start()播放流媒體之前,需要裝載流媒體資源。這裡最好使用prepareasync()用異步的方式裝載流媒體資源。因為流媒體資源的裝載是會消耗系統資源的,在一些硬體不理想的裝置上,如果使用prepare()同步的方式裝載資源,可能會造成ui界面的卡頓,這是非常影響用于體驗的。因為推薦使用異步裝載的方式,為了避免還沒有裝載完成就調用start()而報錯的問題,需要綁定mediaplayer.setonpreparedlistener()事件,它将在異步裝載完成之後回調。異步裝載還有一個好處就是避免裝載逾時引發anr((application

not responding)錯誤。

Android開發之Mediaplayer
Android開發之Mediaplayer

  2、使用完mediaplayer需要回收資源。mediaplayer是很消耗系統資源的,是以在使用完mediaplayer,不要等待系統自動回收,最好是主動回收資源。

  3、使用mediaplayer最好使用一個service來使用,并且在service的ondestory()方法中回收mediaplayer資源,實際上,就算是直接使用activity承載mediaplayer,也最好在銷毀的時候判斷一下mediaplayer是否被回收,如果未被回收,回收其資源,因為底層調用的native方法,如果不銷毀還是會在底層繼續播放,而承載的元件已經被銷毀了,這個時候就無法擷取到這個mediaplayer進而控制它。

Android開發之Mediaplayer
Android開發之Mediaplayer

  4、對于單曲循環之類的操作,除了可以使用setlooping()方法進行設定之外,還可以為mediaplayer注冊回調函數,mediaplayer.setoncompletionlistener(),它會在mediaplayer播放完畢被回調。

Android開發之Mediaplayer
Android開發之Mediaplayer

   5、因為mediaplayer一直操作的是一個流媒體,是以無可避免的可能一段流媒體資源,前半段可以正常播放,而中間一段因為解析或者源檔案錯誤等問題,造成中間一段無法播放問題,需要我們處理這個錯誤,否則會影響ux(使用者體驗)。可以為mediaplayer注冊回調函數setonerrorlistener()來設定出錯之後的解決辦法,一般重新播放或者播放下一個流媒體即可。  

Android開發之Mediaplayer
Android開發之Mediaplayer

  上面已經介紹了mediaplayer播放一段音頻檔案的所有需要用到的内容。下面通過一個簡單的demo來示範如何使用mediaplayer播放一個sd卡上的mp3檔案。操作mediaplayer應該放在service中完成,這裡為了簡單,使用activity直接操作mediaplayer。代碼注釋裡寫的很清楚裡,這裡不再累述。

  執行這個示例需要在/sdcard/目錄下存在xm.mp3的檔案。  

Android開發之Mediaplayer
Android開發之Mediaplayer

 效果展示:

Android開發之Mediaplayer
Android開發之Mediaplayer
Android開發之Mediaplayer

繼續閱讀