プレーヤー インターフェース

プレーヤーとは、メディア アイテムの再生を容易にするアプリのコンポーネントです。Media3 の Player インターフェースは、一般的にプレーヤーによって処理される機能の概要を設定します。これには次のものが含まれます。

  • 再生、一時停止、移動などの再生コントロールへの影響
  • 現在再生中のメディアのプロパティ(再生位置など)をクエリする
  • メディア アイテムの再生リストまたはキューの管理
  • 再生プロパティの設定(シャッフル、繰り返し、速度、音量など)
  • 画面に動画をレンダリングしています

Media3 は、ExoPlayer と呼ばれる Player インターフェースの実装も提供します。

コンポーネント間の共通インターフェース

Media3 の複数のコンポーネントは、次のようなプレーヤー インターフェースを実装します。

コンポーネント 説明と動作に関する注意事項
ExoPlayer メディア プレーヤー API と、Player インターフェースのデフォルト実装。
MediaController MediaSession を操作して再生コマンドを送信します。PlayerMediaSession が、プレーヤーの UI が存在する Activity または Fragment とは別の Service にある場合、MediaControllerPlayerView UI のプレーヤーとして割り当てることができます。再生とプレイリストのメソッドの呼び出しは、MediaSession を通じて Player に送信されます。
MediaBrowser MediaController が提供する機能に加えて、MediaLibrarySession とやり取りして、利用可能なメディア コンテンツを閲覧します。
ForwardingPlayer メソッド呼び出しを別の Player に転送する Player 実装。このクラスを使用して、それぞれのメソッドをオーバーライドすることで、特定のオペレーションを抑制または変更します。
SimpleBasePlayer 実装するメソッドの数を最小限に抑える Player 実装。MediaSession に接続するカスタム プレーヤーを使用する場合に便利です。
CastPlayer キャスト レシーバー アプリと通信する Player 実装。動作は基盤となるキャスト セッションによって異なります。

MediaSessionPlayer インターフェースを実装していませんが、作成時に Player が必要です。その目的は、他のプロセスやスレッドから Player にアクセスできるようにすることです。

Media3 再生アーキテクチャ

Player にアクセスできる場合は、そのメソッドを直接呼び出して再生コマンドを発行する必要があります。MediaSession を実装すると、再生をアドバタイズし、外部ソースの再生制御を付与できます。これらの外部ソースは MediaController を実装します。これにより、メディア セッションへの接続と再生コマンド リクエストの発行が容易になります。

バックグラウンドでメディアを再生する場合、フォアグラウンド サービスとして実行される MediaSessionService または MediaLibraryService 内にメディア セッションとプレーヤーを格納する必要があります。その場合、再生コントロールの UI を含むアプリ内のアクティビティからプレーヤーを分離できます。この場合、メディア コントローラの使用が必要になる場合があります。

Media3 再生コンポーネントがメディアアプリのアーキテクチャにどのように適合するかを示す図。
図 1: Player インターフェースは Media3 のアーキテクチャで重要な役割を果たしています。

プレーヤーの状態

Player インターフェースを実装するメディア プレーヤーの状態は、主に次の 4 つのカテゴリの情報で構成されます。

  1. 再生状態
  2. メディア アイテムの再生リスト
    • 再生用の MediaItem インスタンスのシーケンス。
    • getCurrentTimeline() で取得する
    • Player インスタンスでは、MediaItem追加削除などのプレイリスト操作メソッドや、getCurrentMediaItem() などのコンビニエンス メソッドを提供できます。
  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() メソッド以外に実装する必要があるのは、プレーヤーが利用可能と宣言しているコマンドに使用するメソッドのみです。実装する機能に対応するオーバーライド可能なハンドラ メソッドを見つけます。たとえば、COMMAND_SEEK_IN_CURRENT_MEDIA_ITEMCOMMAND_SEEK_TO_NEXT_MEDIA_ITEM などのオペレーションをサポートするには、handleSeek() メソッドをオーバーライドします。