media player 狀態與方法

來源:互聯網
上載者:User

7.2.2  MediaPlayer的狀態

音頻和視頻的播放過程也就是MediaPlayer對象的狀態轉換過程。深入理解MediaPlayer的狀態機器是靈活駕馭OPhone多媒體編程的基礎。圖7-3是MediaPlayer的狀態圖,其中MediaPlayer的狀態用橢圓形標記,狀態的切換由箭頭表示,單箭頭代表狀態的切換是同步操作,雙箭頭代表狀態的切換是非同步作業。

1. 建立與銷毀

MediaPlayer可以通過靜態方法MediaPlayer.create()或者new操作符來建立。這兩種方法建立的MediaPlayer對象處於的狀態是不同的,使用create()方法建立的MediaPlayer對象處於prepared狀態,因為系統已經根據參數的資源ID調用了setDataSource()和prepare()方法;使用new操作符建立的MediaPlayer對象則處於idle狀態。除了剛剛構建的MediaPlayer對象處於idle狀態外,調用reset()方法後的MediaPlayer狀態也同樣處於idle狀態。由於處於idle狀態的MediaPlayer還沒有設定資料來源,無法獲得多媒體的時間長度、視頻的高度等資訊,因此現在調用下列方法是典型的編程錯誤。對於剛剛建立的MediaPlayer對象調用如下方法,底層系統不會調用MediaPlayer註冊的OnErrorListener,MediaPlayer的狀態也不會改變。對於通過調用reset()方法進入idle狀態的MediaPlayer對象調用如下方法,則會導致底層系統調用OnErrorListener.onError()方法,MediaPlayer對象將進入error狀態。

 
(點擊查看大圖)圖7-3  MediaPlayer的狀態圖

getCurrentPosition()

getDruation()

getVideoWidth()

getVideoHeight()

setAudioStreamType()

setLooping()

setVolume()

pause()

start()

stop()

seekTo()

prepare()

prepareAsync()

對於不再需要的MediaPlayer對象,一定要通過調用release()方法使其進入到end狀態,因為這關係到資源的釋放問題。如果MediaPlayer對象不釋放硬體加速器等資源,隨後建立的MediaPlayer對象就無法使用這唯一的資源,甚至導致建立失敗。處於end狀態的MediaPlayer意味著它的生命週期終結,無法再回到其他狀態了。

2. 初始化

在播放音頻和視頻之前必須對MediaPlayer進行初始化操作,這主要由兩步工作完成。調用重載的setDataSource()方法將使MediaPlayer對象進入到initialized狀態,隨後調用prepare()或者prepareAsync()方法將使MediaPlayer對象進入到prepared狀態。由於prepareAsync()方式是非同步呼叫,因此通常為MediaPlayer註冊OnPreparedListener(),並在onPrepare()方法中啟動播放器。當MediaPlayer對象處於prepared狀態時,意味著調用者已經可以獲得多媒體的時間長度等資訊,此時可以調用MediaPlayer的相關方法設定播放器的屬性。例如,調用setVolume(float leftVolume, float rightVolume)設定播放器的音量。

3. 播放、暫停和停止

調用start()方法,MediaPlayer將進入到started狀態。isPlaying()方法可以用來判斷MediaPlayer是否處在started狀態。當MediaPlayer從網路上播放多媒體檔案時,可以通過onBufferingUpdateListener.onBufferingUpdate(MediaPlayer mp,int percent)來監聽緩衝的進度,其中percent是0~100的整數,代表已經緩衝好的多媒體資料的百分比。

調用pause()方法,MediaPlayer將進入到paused狀態。需要注意的是,從started到paused、從paused到started狀態的轉換是非同步過程,也就是說,可能經過一段時間才能更新MediaPlayer的狀態。在調用isPlaying()來查詢播放器的狀態時需要考慮這一點。

調用stop()方法,MediaPlayer將進入到stopped狀態。一旦MediaPlayer進入stopped狀態,必須再次調用prepare()或者prepareAsyn()才能使其進入到prepared狀態,以便複用此MediaPlayer對象,再次播放多媒體檔案。

4. 快進和快退

調用seekTo()方法可以調整MediaPlayer的媒體時間,以實現快退和快進的功能。seekTo()方法也是非同步,方法會立即返回,但是媒體時間調整的工作可能需要一段時間才能完成。如果為MediaPlayer設定了onSeekCompleteListener,那麼onSeekComplete()方法將被調用。需要說明的一點是,seekTo()不僅可以在started狀態下調用,還可以在paused、prepared和playbackCompleted狀態下調用。

5. 播放結束狀態

如果播放狀態自然結束,MediaPlayer可能進入兩種可能的狀態。當迴圈播放模式設定為true時,MediaPlayer對象保持started狀態不變;當迴圈播放模式設定為false時,MediaPlayer對象的onCompletionListener.onCompletion()方法會被調用,MediaPlayer對象進入到playbackCompleted狀態。對於處於playbackCompleted狀態的播放器,再次調用start()方法,將重新播放音/視頻檔案。需要注意的是,當播放器結束時,音/視頻的時間長度、視頻的尺寸資訊依然可以通過調用getDuration()、getVideoWidth()和getVideoHeight()等方法獲得。

6. 錯誤處理

在播放器播放音/視頻檔案時,可能發生各種各樣的錯誤,比如IO錯誤、多媒體檔案格式錯誤等。正確處理播放過程中的各種錯誤顯得尤為重要。為了監聽錯誤資訊,可以為MediaPlayer對象註冊onErrorListener監聽器,當錯誤發生時,onErrorListener.onError()方法會被調用,MediaPlayer對象進入到error狀態。如果希望複用MediaPlayer對象並從錯誤中恢複過來,那麼可以調用reset()方法使MediaPlayer再次進入到idle狀態。總之,監視MediaPlayer的狀態是非常重要的,在錯誤發生之際提示使用者,並恢複播放器的狀態才是正確的處理方法。

除了上述的錯誤之外,如果在不恰當的時間調用了某方法,則會拋出IllegalStateException異常,在程式中應該使用try/catch塊捕獲到此類的編程錯誤。

至此,我們已經詳細地介紹了MediaPlayer的狀態圖,下面通過一個具體的媒體播放器執行個體向讀者介紹如何使用MediaPlayer的相關API。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.