プレーヤーとは、メディア アイテムの再生を容易にするアプリのコンポーネントです。Media3 の Player
インターフェースは、一般的にプレーヤーによって処理される機能の概要を設定します。これには次のものが含まれます。
- 再生、一時停止、移動などの再生コントロールへの影響
- 現在再生中のメディアのプロパティ(再生位置など)をクエリする
- メディア アイテムの再生リストまたはキューの管理
- 再生プロパティの設定(シャッフル、繰り返し、速度、音量など)
- 画面に動画をレンダリングしています
Media3 は、ExoPlayer
と呼ばれる Player
インターフェースの実装も提供します。
コンポーネント間の共通インターフェース
Media3 の複数のコンポーネントは、次のようなプレーヤー インターフェースを実装します。
コンポーネント | 説明と動作に関する注意事項 |
---|---|
ExoPlayer |
メディア プレーヤー API と、Player インターフェースのデフォルト実装。 |
MediaController |
MediaSession を操作して再生コマンドを送信します。Player と MediaSession が、プレーヤーの UI が存在する Activity または Fragment とは別の Service にある場合、MediaController を PlayerView UI のプレーヤーとして割り当てることができます。再生とプレイリストのメソッドの呼び出しは、MediaSession を通じて Player に送信されます。 |
MediaBrowser |
MediaController が提供する機能に加えて、MediaLibrarySession とやり取りして、利用可能なメディア コンテンツを閲覧します。
|
ForwardingPlayer |
メソッド呼び出しを別の Player に転送する Player 実装。このクラスを使用して、それぞれのメソッドをオーバーライドすることで、特定のオペレーションを抑制または変更します。
|
SimpleBasePlayer |
実装するメソッドの数を最小限に抑える Player 実装。MediaSession に接続するカスタム プレーヤーを使用する場合に便利です。
|
CastPlayer |
キャスト レシーバー アプリと通信する Player 実装。動作は基盤となるキャスト セッションによって異なります。 |
MediaSession
は Player
インターフェースを実装していませんが、作成時に 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 のドキュメントをご覧ください。
リスナー インターフェースには、通常の再生の進行状況を追跡するコールバックは含まれていません。進行状況バー 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()
など)。 - 現在のアイテムまたは位置をシークして変更します。
- 繰り返しモードとシャッフル モードを設定します。
- トラック選択の設定を更新します。
- 再生速度を設定します。
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_ITEM
や COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
などのオペレーションをサポートするには、handleSeek()
メソッドをオーバーライドします。