プレーヤーは、メディア アイテムの再生を容易にするアプリのコンポーネントです。Media3 の Player
インターフェースは、プレーヤーが一般的に処理する機能の概要を設定します。これには、次のものが含まれます。
- 再生、一時停止、シークなどの再生コントロールに影響する
- 現在再生中のメディアのプロパティ(再生位置など)のクエリ
- メディア アイテムの再生リスト/キューを管理する
- シャッフル、リピート、速度、音量などの再生プロパティの構成
- 画面への動画のレンダリング
Media3 には、ExoPlayer
という Player
インターフェースの実装も用意されています。
コンポーネント間の共通インターフェース
Media3 のいくつかのコンポーネントは、Player インターフェースを実装しています。たとえば、次のようなコンポーネントがあります。
コンポーネント | 説明と動作に関するメモ |
---|---|
ExoPlayer |
メディア プレーヤー API と Player インターフェースのデフォルト実装。 |
MediaController |
MediaSession とやり取りして再生コマンドを送信します。Player と MediaSession が、プレーヤーの UI が存在する Activity または Fragment とは別の Service にある場合、MediaController を PlayerView UI のプレーヤーとして割り当てることができます。再生とプレイリストのメソッド呼び出しは、MediaSession を介して Player に送信されます。 |
MediaBrowser |
MediaController が提供する機能に加えて、MediaLibrarySession とやり取りして利用可能なメディア コンテンツを閲覧します。 |
SimpleBasePlayer |
実装するメソッドの数を最小限に抑える Player 実装。MediaSession に接続するカスタム プレーヤーを使用する場合に便利です。 |
ForwardingSimpleBasePlayer |
再生オペレーションを別の Player に転送するように設計された SimpleBasePlayer サブクラス。SimpleBasePlayer と同じ一貫性のある動作のカスタマイズを可能にします。このクラスを使用して、特定の再生オペレーションを抑制または変更します。 |
CastPlayer |
Cast レシーバー アプリと通信する Player 実装。動作は基盤となる Cast セッションによって異なります。 |
MediaSession
は Player
インターフェースを実装していませんが、作成時に Player
が必要です。その目的は、他のプロセスやスレッドから Player
へのアクセスを提供することです。
Media3 の再生アーキテクチャ
Player
にアクセスできる場合は、そのメソッドを直接呼び出して再生コマンドを発行する必要があります。MediaSession
を実装することで、再生をアドバタイズし、外部ソースに再生制御を許可できます。これらの外部ソースは MediaController
を実装しており、メディア セッションへの接続と再生コマンド リクエストの発行を容易にしています。
バックグラウンドでメディアを再生する場合は、フォアグラウンド サービスとして実行される MediaSessionService
または MediaLibraryService
内にメディア セッションとプレーヤーを配置する必要があります。そうすることで、アプリ内の再生制御用の UI を含むアクティビティからプレーヤーを分離できます。この場合、メディア コントローラを使用する必要があります。
Player
インターフェースは Media3 のアーキテクチャで重要な役割を果たします。プレーヤーの状態
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()
メソッド以外に実装する必要があるのは、プレーヤーが利用可能と宣言したコマンドに使用されるメソッドのみです。実装する機能に対応するオーバーライド可能なハンドラ メソッドを見つけます。たとえば、handleSeek()
メソッドをオーバーライドして、COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM
や COMMAND_SEEK_TO_NEXT_MEDIA_ITEM
などのオペレーションをサポートします。
Player
実装を変更する
完全にカスタムの Player
を作成する代わりに、ForwardingSimpleBasePlayer
を使用して既存の Player
の状態と動作を変更できます。詳しくは、カスタマイズ ページのガイドをご覧ください。