再生イベントをリッスンする
状態の変更や再生エラーなどのイベントは、登録済みの
Player.Listener
インスタンス。このようなイベントを受信するようにリスナーを登録し、
events:
Kotlin
// Add a listener to receive events from the player. player.addListener(listener)
Java
// Add a listener to receive events from the player. player.addListener(listener);
Player.Listener
には空のデフォルト メソッドがあるので、実装する必要があるのは
確認することもできます。詳細については、Javadoc をご覧ください。
呼び出されるタイミングを指定できます。その中でも特に重要なのは、
以下で詳しく説明します。
リスナーは、個々のイベント コールバックを実装するか、
1 つ以上のイベントが発生した後に呼び出される汎用の onEvents
コールバック
説明します。どちらを選択するかについては、Individual callbacks vs onEvents
をご覧ください。
適切なオプションを選択することをおすすめします
再生状態の変更
プレーヤーの状態の変化は、次を実装することで受け取れます。
onPlaybackStateChanged(@State int state)
(登録済み)
Player.Listener
。プレーヤーは、次の 4 つの再生状態のいずれかになります。
Player.STATE_IDLE
: これは初期状態です。プレーヤーが 再生に失敗した場合などですプレーヤーは限られたリソースしか持っていない 必要があります。Player.STATE_BUFFERING
: プレーヤーはすぐに再生できない 表示できます。これはほとんどの場合、より多くのデータを読み込む必要があるために発生します。Player.STATE_READY
: プレーヤーは現在の状態からすぐに再生できる なります。Player.STATE_ENDED
: プレーヤーがすべてのメディアの再生を終了しました。
プレーヤーには、これらの状態に加えて、状態を示す playWhenReady
フラグがあります。
示します。このフラグの変更は、
onPlayWhenReadyChanged(playWhenReady, @PlayWhenReadyChangeReason int reason)
。
プレーヤーが再生中(位置が進行していて、メディアが進行している) 次の 3 つの条件がすべて満たされている場合:
- プレーヤーが
Player.STATE_READY
状態である playWhenReady
の場合はtrue
- から返された理由により再生が抑制されていない
Player.getPlaybackSuppressionReason
これらのプロパティを個別に確認する必要はありません。Player.isPlaying
呼び出すことができます。この状態の変更を受け取るには、
onIsPlayingChanged(boolean isPlaying)
:
Kotlin
player.addListener( object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.playWhenReady, // player.playbackState, player.playbackSuppressionReason and // player.playerError for details. } } } )
Java
player.addListener( new Player.Listener() { @Override public void onIsPlayingChanged(boolean isPlaying) { if (isPlaying) { // Active playback. } else { // Not playing because playback is paused, ended, suppressed, or the player // is buffering, stopped or failed. Check player.getPlayWhenReady, // player.getPlaybackState, player.getPlaybackSuppressionReason and // player.getPlaybackError for details. } } });
再生エラー
再生が失敗する原因となるエラーは、
onPlayerError(PlaybackException error)
(登録済み)
Player.Listener
。エラーが発生すると、このメソッドが呼び出されます。
再生状態が Player.STATE_IDLE
に移行する直前にトリガーされます。
失敗または停止した再生を再試行するには、ExoPlayer.prepare
を呼び出します。
一部の Player
実装では、
PlaybackException
に失敗に関する追加情報を提供します。対象
たとえば、ExoPlayer
は ExoPlaybackException
を渡します。これには type
が含まれています。
rendererIndex
、その他の ExoPlayer 固有のフィールド。
次の例は、エラーが原因で再生が失敗したことを検出し、 HTTP ネットワークの問題:
Kotlin
player.addListener( object : Player.Listener { override fun onPlayerError(error: PlaybackException) { val cause = error.cause if (cause is HttpDataSourceException) { // An HTTP error occurred. val httpError = cause // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError is InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } } )
Java
player.addListener( new Player.Listener() { @Override public void onPlayerError(PlaybackException error) { @Nullable Throwable cause = error.getCause(); if (cause instanceof HttpDataSourceException) { // An HTTP error occurred. HttpDataSourceException httpError = (HttpDataSourceException) cause; // It's possible to find out more about the error both by casting and by querying // the cause. if (httpError instanceof HttpDataSource.InvalidResponseCodeException) { // Cast to InvalidResponseCodeException and retrieve the response code, message // and headers. } else { // Try calling httpError.getCause() to retrieve the underlying cause, although // note that it may be null. } } } });
再生リストの切り替え
プレーヤーが再生リスト内の新しいメディア アイテムに変更したとき
onMediaItemTransition(MediaItem mediaItem,
@MediaItemTransitionReason int reason)
が登録済みで呼び出されます
Player.Listener
オブジェクト。自動停止であるかどうかを示します。
遷移、シーク(player.next()
の呼び出し後など)、
再生リストの変更が原因(たとえば、
削除されます)。
メタデータ
player.getCurrentMediaMetadata()
から返されるメタデータは、
再生リストの切り替え、インストリーム メタデータの更新、
現在の MediaItem
の再生中。
メタデータの変更に関心がある場合(たとえば、次を表示する UI の更新など)は、
onMediaMetadataChanged
を再生します。
シークしています
Player.seekTo
メソッドを呼び出すと、登録された一連のコールバックが呼び出されます。
Player.Listener
個のインスタンス:
onPositionDiscontinuity
はreason=DISCONTINUITY_REASON_SEEK
に置き換えます。これは、Player.seekTo
を呼び出した直接的な結果。コールバックにPositionInfo
が含まれている フィールドを返します。onPlaybackStateChanged
は、シークに関連する即時の状態変更に置き換えます。 そのような変更がない場合もあります。
個別のコールバックと onEvents
リスナーは、次のように個別のコールバックの実装を選択できます。
onIsPlayingChanged(boolean isPlaying)
、汎用
onEvents(Player player, Events events)
コールバック。汎用のコールバックでは、
Player
オブジェクトにアクセスし、発生した events
のセットを指定します。
説明します。このコールバックは常に、対応するコールバックの
個別に選択できます。
Kotlin
override fun onEvents(player: Player, events: Player.Events) { if ( events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED) ) { uiModule.updateUi(player) } }
Java
@Override public void onEvents(Player player, Events events) { if (events.contains(Player.EVENT_PLAYBACK_STATE_CHANGED) || events.contains(Player.EVENT_PLAY_WHEN_READY_CHANGED)) { uiModule.updateUi(player); } }
次の場合は、個別のイベントをおすすめします。
- リスナーは変更の理由に関心を持っています。たとえば、
onPlayWhenReadyChanged
またはonMediaItemTransition
に対して指定された理由。 - リスナーは、コールバック パラメータを通じて提供される新しい値に対してのみ動作します。 コールバックのパラメータに依存しない別の処理をトリガーします。
- リスナー実装では、何であるかをわかりやすく メソッド名のイベントをトリガーします
- リスナーはアナリティクス システムにレポートを送信します。このシステムは、 状態変化をモニタリングできます。
カテゴリでは、汎用の onEvents(Player player, Events events)
が優先されます。
次のようなケースがあります。
- リスナーは、複数のイベントに対して同じロジックをトリガーしたいと考えています。対象
たとえば、
onPlaybackStateChanged
と両方の UI を更新するとします。onPlayWhenReadyChanged
。 - リスナーは、以降のイベントをトリガーするために
Player
オブジェクトにアクセスする必要があります。 たとえばメディア アイテムの遷移後にシークします - リスナーは、報告される複数の状態値を使用することを意図しています。
個別のコールバックを一緒に使用することも、
Player
ゲッターと組み合わせて使用することもできます。 あります。たとえば、Player.getCurrentWindowIndex()
をonTimelineChanged
で指定されたTimeline
は、onEvents
コールバック。 - リスナーは、イベントが一緒に発生したかどうかを調べます。対象
メディア アイテムによる
onPlaybackStateChanged
からSTATE_BUFFERING
など 説明します。
場合によっては、リスナーは個々のコールバックを
汎用の onEvents
コールバック(メディア アイテムの変更理由を記録する場合など)
onMediaItemTransition
を使用。ただし、すべての状態変化が使用可能になった場合にのみ動作
onEvents
で一緒にプレイします。
AnalyticsListener
の使用
ExoPlayer
を使用する場合は、AnalyticsListener
をプレーヤーに登録できる。
addAnalyticsListener
を呼び出します。AnalyticsListener
個の実装で可能
分析やロギングに役立つ可能性のある詳細なイベントをリッスンする
あります。詳しくは、アナリティクス ページをご覧ください。
EventLogger
の使用
EventLogger
は、ライブラリから直接提供される AnalyticsListener
です。
使用します。EventLogger
を ExoPlayer
に追加して利便性を高める
次のように 1 行で追加します。
Kotlin
player.addAnalyticsListener(EventLogger())
Java
player.addAnalyticsListener(new EventLogger());
詳細については、デバッグ ロギングのページをご覧ください。
指定した再生位置でイベントを発生させる
ユースケースによっては、指定した再生位置でイベントを発生させる必要があります。これは、
PlayerMessage
を使用してサポートされます。PlayerMessage
は、次のコマンドを使用して作成できます。
ExoPlayer.createMessage
。実行する再生位置
PlayerMessage.setPosition
を使用して設定できます。メッセージは、
デフォルトですが、次のコマンドを使用してカスタマイズできます。
PlayerMessage.setLooper
。PlayerMessage.setDeleteAfterDelivery
を使用できます。
指定した日時のたびにメッセージを実行するかどうかを
再生位置に到達した(これは再生位置の移動が原因で複数回発生する場合がある)
リピート モードなど)、または初回のみに設定できます。PlayerMessage
の設定が完了したら、
PlayerMessage.send
を使用してスケジュールできます。
Kotlin
player .createMessage { messageType: Int, payload: Any? -> } .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send()
Java
player .createMessage( (messageType, payload) -> { // Do something at the specified playback position. }) .setLooper(Looper.getMainLooper()) .setPosition(/* mediaItemIndex= */ 0, /* positionMs= */ 120_000) .setPayload(customPayloadData) .setDeleteAfterDelivery(false) .send();