播放器是應用程式中的元件,可協助播放媒體項目。Media3 Player
介面會為通常由播放器處理的功能設定大綱。包括:
- 影響播放控制項,例如播放、暫停和跳轉
- 查詢目前播放媒體的屬性,例如播放位置
- 管理媒體項目的播放清單/佇列
- 設定播放屬性,例如隨機播放、重複播放、速度和音量
- 將影片轉譯至螢幕
Media3 也提供 Player
介面的實作項目,稱為 ExoPlayer
。
元件之間的通用介面
Media3 中的幾個元件會實作 Player 介面,例如:
元件 | 說明與行為附註 |
---|---|
ExoPlayer |
媒體播放器 API,以及 Player 介面的預設實作方式。 |
MediaController |
與 MediaSession 互動,以便傳送播放指令。如果 Player 和 MediaSession 位於 Service 中,而 Service 與播放器 UI 所在的 Activity 或 Fragment 不同,您可以將 MediaController 指派為 PlayerView UI 的播放器。播放和播放清單方法呼叫會透過 MediaSession 傳送至 Player 。 |
MediaBrowser |
除了 MediaController 提供的功能外,還可與 MediaLibrarySession 互動,瀏覽可用的媒體內容。 |
ForwardingPlayer |
將方法呼叫轉送至其他 Player 的 Player 實作。使用這個類別覆寫相應方法,藉此抑制或修改特定作業。 |
SimpleBasePlayer |
Player 實作項目,可將要實作的函式數量降至最低。當您要使用要連線至 MediaSession 的自訂播放器時,這項屬性就很實用。 |
CastPlayer |
與 Cast 接收器應用程式通訊的 Player 實作項目。行為取決於基礎的 Cast 工作階段。 |
雖然 MediaSession
不會實作 Player
介面,但建立 MediaSession
時需要 Player
。其目的是透過其他程序或執行緒提供對 Player
的存取權。
Media3 播放架構
如果您有權存取 Player
,請直接呼叫其方法,以便發出播放指令。您可以實作 MediaSession
,宣傳您的播放功能並授予外部來源播放控制權。這些外部來源會實作 MediaController
,方便連線至媒體工作階段並發出播放指令請求。
在背景播放媒體時,您必須在以前景服務執行的 MediaSessionService
或 MediaLibraryService
中安置媒體工作階段和播放器。這樣一來,您就能將播放器與應用程式中的活動分開,後者包含播放控制項的 UI。因此,您可能需要使用媒體控制器。
播放器狀態
實作 Player
介面的媒體播放器狀態主要包含 4 類資訊:
- 播放狀態
- 使用
getPlaybackState()
擷取。 - 介面定義的狀態值為
STATE_IDLE
、STATE_BUFFERING
、STATE_READY
和STATE_ENDED
。
- 使用
- 媒體項目播放清單
- 用於播放的
MediaItem
例項序列。 - 使用
getCurrentTimeline()
擷取 Player
例項可提供播放清單作業方法,例如新增或移除MediaItem
,以及getCurrentMediaItem()
等便利方法。
- 用於播放的
- 播放/暫停屬性,例如:
playWhenReady
:指出使用者是否希望媒體在可播放時播放,或保持暫停狀態- 播放抑制原因:指出播放內容遭到抑制的原因 (如果適用),即使
playWhenReady
為true
也一樣 isPlaying
:指出播放器目前是否正在播放,只有在播放狀態為STATE_READY
、playWhenReady
為true
,且播放未遭到抑制時,才會是true
- 播放位置,包括:
- 目前的媒體項目索引:播放清單中目前
MediaItem
的索引。 isPlayingAd
:指出插入的廣告是否正在播放。- 目前的播放位置:目前
MediaItem
或插入廣告中的目前播放位置。
- 目前的媒體項目索引:播放清單中目前
此外,Player
介面可讓您存取可用的音軌、媒體中繼資料、播放速度、音量和其他播放輔助屬性。
監聽變更
使用 Player.Listener
監聽 Player
中的變更。如需建立及使用事件監聽器的詳細資訊,請參閱 ExoPlayer 說明文件中的「Player 事件」一節。
請注意,監聽器介面不包含任何回呼,無法追蹤正常的播放進度。如要持續監控播放進度 (例如設定進度列 UI),您應以適當的間隔查詢目前位置。
Kotlin
val handler = Handler(Looper.getMainLooper()) fun checkPlaybackPosition(delayMs: Long): Boolean = handler.postDelayed( { val currentPosition = player.currentPosition // Update UI based on currentPosition checkPlaybackPosition(delayMs) }, delayMs)
Java
Handler handler = new Handler(Looper.getMainLooper()); boolean checkPlaybackPosition(long delayMs) { return handler.postDelayed(() -> { long currentPosition = player.getCurrentPosition(); // Update UI based on currentPosition checkPlaybackPosition(delayMs); }, delayMs); }
控制播放功能
Player
介面提供多種方法,可用於操控狀態及控制播放:
- 基本播放控制項,例如
play()
、pause()
、prepare()
和stop()
。 - 播放清單作業,例如
addMediaItem()
或removeMediaItem()
。 - Seeking:變更目前的項目或位置。
- 設定重複播放模式和隨機播放模式。
- 更新曲目選取偏好設定。
- 設定播放速度。
自訂 Player
實作
如要建立自訂播放器,您可以擴充 Media3 中的 SimpleBasePlayer
。這個類別提供 Player
介面的基礎實作項目,可將您需要實作的函式數量降至最低。
首先,覆寫 getState()
方法。這個方法在呼叫時應填入目前的播放器狀態,包括:
- 可用的指令集
- 播放屬性,例如播放器應在播放狀態為
STATE_READY
時開始播放、目前播放的媒體項目索引,以及目前項目中的播放位置
Kotlin
class CustomPlayer : SimpleBasePlayer(looper) { override fun getState(): State { return State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build() } }
Java
public class CustomPlayer extends SimpleBasePlayer { public CustomPlayer(Looper looper) { super(looper); } @Override protected State getState() { return new State.Builder() .setAvailableCommands(...) // Set which playback commands the player can handle // Configure additional playback properties .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST) .setCurrentMediaItemIndex(0) .setContentPositionMs(0) .build(); } }
SimpleBasePlayer
會強制使用有效的狀態值組合建立 State
。它也會處理監聽器,並通知監聽器狀態變更。如果需要手動觸發狀態更新,請呼叫 invalidateState()
。
除了 getState()
方法之外,您只需實作用於玩家宣告可用的命令的方法。找出對應於要實作功能的覆寫處理常式方法。舉例來說,您可以覆寫 handleSeek()
方法,以支援 COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
和 COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
等作業。