播放器介面

播放器是應用程式的元件,可協助播放媒體項目。Media3 Player 介面會設定播放器一般處理的功能大綱。包括:

  • 影響播放控制項,例如播放、暫停及搜尋
  • 查詢目前播放媒體的屬性,例如播放位置
  • 管理媒體項目的播放清單/佇列
  • 設定播放屬性,例如隨機播放、重複播放、速度和音量
  • 將影片轉譯至螢幕

Media3 也提供 Player 介面的實作,稱為 ExoPlayer

元件之間的通用介面

Media3 中的多個元件會實作 Player 介面,例如:

元件 說明與行為附註
ExoPlayer 媒體播放器 API,以及 Player 介面的預設實作。
MediaController MediaSession 互動,傳送播放指令。如果 PlayerMediaSession 位於與 Service 不同的 ActivityFragment 中,您可將 MediaController 指派為 PlayerView UI 的播放器。播放和播放清單方法呼叫會透過 MediaSession 傳送至 Player
MediaBrowser 除了 MediaController 提供的功能外,還會與 MediaLibrarySession 互動,瀏覽可用的媒體內容。
SimpleBasePlayer Player 實作方式,可將實作的方法數量降到最低。使用要連線至 MediaSession 的自訂播放器時,這項功能會很有幫助。
ForwardingSimpleBasePlayer SimpleBasePlayer 子類別,用於將播放作業轉送至另一個 Player,同時允許與 � 相同的行為自訂項目。SimpleBasePlayer使用這個類別可禁止或修改特定播放作業。
CastPlayer Player 實作項目,可與 Cast 接收器應用程式通訊。行為取決於基礎 Cast 工作階段。

雖然 MediaSession 不會實作 Player 介面,但建立時需要 Player。其目的是提供其他程序或執行緒的存取權。Player

Media3 播放架構

如果您可以存取 Player,請直接呼叫其方法來發出播放指令。您可以導入 MediaSession,宣傳播放功能並授予外部來源播放控制權。這些外部來源會實作 MediaController,方便連線至媒體工作階段及發出播放指令要求。

在背景播放媒體時,您需要在以前景服務執行的 MediaSessionServiceMediaLibraryService 中,存放媒體工作階段和播放器。這樣一來,您就能將播放器與應用程式中含有播放控制項 UI 的 Activity 分開。這時可能需要使用媒體控制器。

這張圖表顯示 Media3 播放元件如何融入媒體應用程式架構。
圖 1Player 介面在 Media3 的架構中扮演重要角色。

播放器狀態

實作 Player 介面的媒體播放器狀態主要包含 4 類資訊:

  1. 播放狀態
  2. 媒體項目播放清單
  3. 播放/暫停屬性,例如:
    • playWhenReady:指出使用者是否希望媒體在可能的情況下播放,或保持暫停狀態
    • 播放受限原因: 指出播放受限的原因 (如適用),即使 playWhenReadytrue
    • isPlaying:表示播放器目前是否正在播放內容,只有在播放狀態為 STATE_READYplayWhenReadytrue 且播放未遭禁止時,才會是 true
  4. 播放位置,包括:

此外,Player 介面可存取可用軌媒體中繼資料播放速度音量,以及播放的其他輔助屬性。

監聽變更

使用 Player.Listener 監聽 Player 中的變更。如要瞭解如何建立及使用事件監聽器,請參閱 ExoPlayer 說明文件中的「播放器事件」。

請注意,監聽器介面不包含任何回呼,可追蹤正常播放進度。如要持續監控播放進度 (例如設定進度列 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 介面提供多種方法來操控狀態和控制播放:

自訂 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_ITEMCOMMAND_SEEK_TO_NEXT_MEDIA_ITEM 等作業。

修改 Player 實作方式

您可以選擇使用 ForwardingSimpleBasePlayer 修改現有 Player 的狀態和行為,不必完全自訂 Player。詳情請參閱自訂頁面指南。