目錄:
(3)Android 官方網站 對 MediaPlayer的介紹
正文:
MediaPlayer
public class MediaPlayer
MediaPlayer類被用來控制音/視頻文件和流的播放。可以在VideoView中找到有關如何使用此類中的方法的示例。
這里涉及的主題是:
1.
狀態圖
2.
有效和無效狀態
3.
權限
4.
注冊信息和錯誤回調
★ 開發者指南
有關如何使用MediaPlayer的更多信息,請閱讀
Media Playback開發人員指南。
狀態圖
音/視頻文件和流的播放控制是作為一個狀態機來進行管理。下圖顯示了受支持的播放控制操作驅動的MediaPlayer對象的生命周期和狀態。 橢圓表示MediaPlayer對象可能駐留的狀態。弧表示驅動對象狀態轉換的播放控制操作。有兩種類型的弧。 單箭頭的弧表示同步方法調用,而雙箭頭的弧表示異步方法調用。

從這個狀態圖中,可以看到MediaPlayer對象具有以下狀態:
- 當使用 new 創建MediaPlayer對象或者在調用 reset() 之后,它處於空閑狀態; 並且在調用 release() 之后,它處於 End 狀態。 在這兩個狀態之間是MediaPlayer對象的生命周期。
1. 一個新構造的 MediaPlayer 對象 和 調用
reset() 方法后的MediaPlayer對象之間存在微妙但重要的區別。針對這兩種情況的空閑狀態下調用諸如
getCurrentPosition(),
getDuration(),
getVideoHeight(),
getVideoWidth(),
setAudioAttributes(AudioAttributes),
setLooping(boolean),
setVolume(float, float),
pause(),
start(),
stop(),
seekTo(long, int),
prepare() or
prepareAsync() 方法是程序設計錯誤。如果在一個 MediaPlayer 對象被構造后任意調用這些方法,則內部播放引擎不會調用用戶提供的回調方法OnErrorListener.onError(),並且該對象狀態保持不變;但是如果這些方法是在
reset()后被調用,則內部播放引擎將調用用戶提供的回調方法OnErrorListener.onError(),並且該對象將被轉換為 Error 狀態。
2. 還建議一旦不再使用MediaPlayer對象,立即調用
release(),以便可以立即釋放與MediaPlayer對象關聯的內部播放器引擎使用的資源。 資源可能包括單一資源(如硬件加速組件)和調用release()失敗可能導致MediaPlayer對象的后續實例回退到軟件實現或完全失敗(?)。 一旦MediaPlayer對象處於End狀態,就無法再使用它,也無法將其恢復到任何其他狀態。
3. 此外,使用new創建的MediaPlayer對象處於空閑狀態,而使用其中一個重載的方便的創建方法創建的對象不處於空閑狀態。 實際上,如果使用create方法創建成功,則對象處於Prepared狀態。
- 通常,一些播放控制操作可能由於各種原因而失敗,例如不支持的音頻/視頻格式,交錯的音頻/視頻,分辨率太高,流超時等。因此,在這些情況下,關注錯誤報告和恢復是非常重要的。有時,由於編程錯誤,也可能在無效狀態下調用播放控制操作。在所有這些錯誤條件下,如果開發者事先通過setOnErrorListener(android.media.MediaPlayer.OnErrorListener)注冊了 OnErrorListener ,則內部播放器引擎會調用開發者提供的 OnErrorListener.onError() 方法。
1. 重要的是要注意,一旦發生錯誤,MediaPlayer對象就會進入錯誤狀態(
Error state)(除非如上所述),即使應用程序尚未注冊錯誤監聽器也是如此。
3. 讓應用程序注冊OnErrorListener以查找內部播放器引擎的錯誤通知是一種很好的編程習慣。
4. 調用譬如
prepare(),
prepareAsync()時,或者一個在無效狀態(
Idle state)重寫的 setDataSource 方法時,拋出IllegalStateException 可以防止編程錯誤。
- 調用 setDataSource(FileDescriptor), 或 setDataSource(String), 或 setDataSource(Context, Uri), 或 setDataSource(FileDescriptor, long, long), 或 setDataSource(MediaDataSource)
將一個 MediaPlayer 對象從空閑狀態(
Idle state) 轉換為 初始狀態(
Initialized state)。
1. 如果在任何其他狀態下調用 setDataSource() ,則拋出 IllegalStateException。
2. 關注從重載的 setDataSource 方法 可能會拋出 IllegalArgumentException 和 IOException 是一種很好的編程習慣。
- 在開始播放之前,MediaPlayer 對象必須先進入准備狀態。
1. 有兩種方法(同步與異步)可以達到Prepared狀態(Prepared state):調用
prepare()(同步),一旦方法調用返回就將對象轉換為Prepared狀態(
Prepared state),或者調用prepareAsync()( 異步),它在調用返回后首先將對象轉換為Preparation狀態(
Preparing state)(幾乎正確地發生),同時內部播放器引擎繼續處理其余的准備工作,直到准備工作完成。 當准備完成或者prepare() 調用返回時,如果事先通過setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)注冊了OnPreparedListener,則內部播放器引擎會調用開發者提供的OnPreparedListener接口的回調方法onPrepared()。
2. 重要的是要注意,准備狀態是暫時狀態,並且在MediaPlayer對象處於准備狀態時調用任何具有副作用的方法的行為是未定義的。
3. 在任何其他狀態調用
prepare() 或
prepareAsync() ,則拋出 IllegalStateException。
4. 在Prepared狀態(
Prepared state)下,可以通過調用相應的set方法來調整音頻/音量,screenOnWhilePlaying,循環等屬性。
- 要開始播放,必須調用 start() ,start() 返回成功后,MediaPlayer對象則處於 Started狀態(Started state)。isPlaying()可用來測試 MediaPlayer對象是否處於 Started狀態(Started state)。
1. 處於Started狀態(Started state)時,如果事先通過 setOnBufferingUpdateListener(OnBufferingUpdateListener)注冊了OnBufferingUpdateListener,則內部播放器引擎會調用用戶提供的.OnBufferingUpdateListener.onBufferingUpdate() 回調方法。 此回調允許應用程序在流式傳輸音頻/視頻時跟蹤緩沖狀態。
2. 調用 start() 對已處於Started狀態的MediaPlayer對象沒有影響。
- 播放可以暫停和停止,並可以調整當前播放位置。 可以通過pause()暫停播放。 當對pause()的調用返回時,MediaPlayer對象進入Paused狀態(Pausedstate)。 請注意,從“已啟動”狀態(Started state)到“暫停”狀態(Paused state)的轉換(反之亦然)在播放器引擎中異步發生。 在調用isPlaying()時更新狀態可能需要一些時間,對於流內容,它可能需要幾秒鍾。
1. 調用
start()以恢復暫停的MediaPlayer對象的播放,並且恢復的播放位置與暫停的位置相同。 當對
start()的調用返回時,暫停的MediaPlayer對象將返回到Started狀態(
Started state)。
2. 調用
pause()對已處於Paused狀態的MediaPlayer對象沒有影響。
- 調用stop()會停止播放並導致處於Started,Paused,Prepared或PlaybackCompleted狀態(state)的MediaPlayer進入Stopped狀態(Stopped state)。
1. 一旦處於Stopped狀態(
Stopped state),在調用
prepare()或
prepareAsync()以將MediaPlayer對象再次設置為Prepared狀態(
Prepared state)之前,無法啟動播放。
2. 調用
stop()對已處於Stopped狀態(
Stopped state)的MediaPlayer對象沒有影響。
- 可以通過調用seekTo(long, int)調整播放位置
1. 盡管異步
seekTo(long, int)調用立即返回,但實際的尋位操作可能需要一段時間才能完成,特別是對於流式傳輸的音頻/視頻。 當實際尋位操作完成時,如果事先通過setOnSeekCompleteListener(OnSeekCompleteListener)注冊了OnSeekCompleteListener,則內部播放器引擎會調用開發者提供的OnSeekComplete.onSeekComplete() 。
2. 請注意,
seekTo(long, int)也可以在其他狀態中調用,例如
Prepared,
Paused和
PlaybackCompleted狀態(state)。 當在這些狀態中調用
seekTo(long, int)時,如果流具有視頻且請求的位置有效,則將顯示一個視頻幀。
3. 此外,可以通過調用
getCurrentPosition()來檢索實際當前播放位置,這對於需要跟蹤播放進度的音樂播放器等應用程序很有幫助。
- 當播放到達流的結尾時,播放完成。
1. 如果使用
setLooping(boolean)將循環模式設置為
true,則MediaPlayer對象應保持為Started狀態(
Started state)。
2. 如果循環模式設置為
false,則播放器引擎調用開發者提供的回調方法OnCompletion.onCompletion(),如果事先通過
setOnCompletionListener(OnCompletionListener)注冊了OnCompletionListener。 調用回調信號表示對象現在處於PlaybackCompleted狀態(
PlaybackCompleted state)。
3. 在PlaybackCompleted狀態(PlaybackCompleted state)下,調用
start()可以從音頻/視頻源的開頭重新開始播放。
有效和無效狀態
Method Name | Valid Sates | Invalid States | Comments |
attachAuxEffect | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Idle, Error} | This method must be called after setDataSource. Calling it does not change the object state. |
getAudioSessionId | any | {} | This method can be called in any state and calling it does not change the object state. |
getCurrentPosition | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
getDuration | {Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
getVideoHeight | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
getVideoWidth | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
isPlaying | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
pause | {Started, Paused, PlaybackCompleted} | {Idle, Initialized, Prepared, Stopped, Error} | Successful invoke of this method in a valid state transfers the object to the Paused state. Calling this method in an invalid state transfers the object to the Error state. |
prepare | {Initialized, Stopped} | {Idle, Prepared, Started, Paused, PlaybackCompleted, Error} | Successful invoke of this method in a valid state transfers the object to the Prepared state. Calling this method in an invalid state throws an IllegalStateException. |
prepareAsync | {Initialized, Stopped} | {Idle, Prepared, Started, Paused, PlaybackCompleted, Error} | Successful invoke of this method in a valid state transfers the object to the Preparing state. Calling this method in an invalid state throws an IllegalStateException. |
release | any | {} | After release(), the object is no longer available. |
reset | {Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} | {} | After reset(), the object is like being just created. |
seekTo | {Prepared, Started, Paused, PlaybackCompleted} | {Idle, Initialized, Stopped, Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
setAudioAttributes | {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} | {Error} | Successful invoke of this method does not change the state. In order for the target audio attributes type to become effective, this method must be called before prepare() or prepareAsync(). |
setAudioSessionId | {Idle} | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} | This method must be called in idle state as the audio session ID must be known before calling setDataSource. Calling it does not change the object state. |
setAudioStreamType (deprecated) | {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} | {Error} | Successful invoke of this method does not change the state. In order for the target audio stream type to become effective, this method must be called before prepare() or prepareAsync(). |
setAuxEffectSendLevel | any | {} | Calling this method does not change the object state. |
setDataSource | {Idle} | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error} | Successful invoke of this method in a valid state transfers the object to the Initialized state. Calling this method in an invalid state throws an IllegalStateException. |
setDisplay | any | {} | This method can be called in any state and calling it does not change the object state. |
setSurface | any | {} | This method can be called in any state and calling it does not change the object state. |
setVideoScalingMode | {Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} | {Idle, Error} | Successful invoke of this method does not change the state. |
setLooping | {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} | {Error} | Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state. |
isLooping | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnBufferingUpdateListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnCompletionListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnErrorListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnPreparedListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setOnSeekCompleteListener | any | {} | This method can be called in any state and calling it does not change the object state. |
setPlaybackParams | {Initialized, Prepared, Started, Paused, PlaybackCompleted, Error} | {Idle, Stopped} | This method will change state in some cases, depending on when it's called. |
setScreenOnWhilePlaying | any | {} | This method can be called in any state and calling it does not change the object state. |
setVolume | {Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted} | {Error} | Successful invoke of this method does not change the state. |
setWakeMode | any | {} | This method can be called in any state and calling it does not change the object state. |
start | {Prepared, Started, Paused, PlaybackCompleted} | {Idle, Initialized, Stopped, Error} | Successful invoke of this method in a valid state transfers the object to the Started state. Calling this method in an invalid state transfers the object to the Error state. |
stop | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method in a valid state transfers the object to the Stopped state. Calling this method in an invalid state transfers the object to the Error state. |
getTrackInfo | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
addTimedTextSource | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
selectTrack | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
deselectTrack | {Prepared, Started, Stopped, Paused, PlaybackCompleted} | {Idle, Initialized, Error} | Successful invoke of this method does not change the state. |
權限
可能需要聲明相應的WAKE_LOCK權限
<uses-permission>元素。
當使用網絡內容時該類要求聲明
Manifest.permission.INTERNET 權限。
回調
應用程序可能希望注冊信息和錯誤事件,以便在播放或流式傳輸期間獲知某些內部狀態更新和可能的運行時錯誤。注冊這些事件是由正確設置相應的監聽器(通過調用
setOnPreparedListener(OnPreparedListener) setOnPreparedListener,
setOnVideoSizeChangedListener(OnVideoSizeChangedListener) setOnVideoSizeChangedListener,
setOnSeekCompleteListener(OnSeekCompleteListener)setOnSeekCompleteListener,
setOnCompletionListener(OnCompletionListener) setOnCompletionListener,
setOnBufferingUpdateListener(OnBufferingUpdateListener) setOnBufferingUpdateListener,
setOnInfoListener(OnInfoListener) setOnInfoListener,
setOnErrorListener(OnErrorListener) setOnErrorListener等完成)。 為了接收與這些偵聽器關聯的相應回調,應用程序需要在運行自己的Looper線程上創建MediaPlayer對象(默認情況下,主UI線程正在運行Looper)。