再生リスト API は、すべての ExoPlayer
実装で実装される Player
インターフェースによって定義されます。プレイリストを使用すると、複数のメディア アイテムを順番に再生できます。次の例は、2 つの動画を含む再生リストの再生を開始する方法を示しています。
Kotlin
// Build the media items. val firstItem = MediaItem.fromUri(firstVideoUri) val secondItem = MediaItem.fromUri(secondVideoUri) // Add the media items to be played. player.addMediaItem(firstItem) player.addMediaItem(secondItem) // Prepare the player. player.prepare() // Start the playback. player.play()
Java
// Build the media items. MediaItem firstItem = MediaItem.fromUri(firstVideoUri); MediaItem secondItem = MediaItem.fromUri(secondVideoUri); // Add the media items to be played. player.addMediaItem(firstItem); player.addMediaItem(secondItem); // Prepare the player. player.prepare(); // Start the playback. player.play();
再生リスト内のアイテム間の遷移はシームレスに行われます。これらが同じ形式である必要はありません(たとえば、再生リストに H264 と VP9 の両方の動画が含まれていても問題ありません)。それらが異なるタイプの場合もあります(つまり、再生リストに動画と音声のみのストリームの両方が含まれていても問題ありません)。再生リスト内で同じ MediaItem
を複数回使用できます。
再生リストの変更
メディア アイテムを追加、移動、削除、置換することで、再生リストを動的に変更できます。この処理は、対応するプレイリスト API メソッドを呼び出して、再生前と再生中の両方で行うことができます。
Kotlin
// Adds a media item at position 1 in the playlist. player.addMediaItem(/* index= */ 1, MediaItem.fromUri(thirdUri)) // Moves the third media item from position 2 to the start of the playlist. player.moveMediaItem(/* currentIndex= */ 2, /* newIndex= */ 0) // Removes the first item from the playlist. player.removeMediaItem(/* index= */ 0) // Replace the second item in the playlist. player.replaceMediaItem(/* index= */ 1, MediaItem.fromUri(newUri))
Java
// Adds a media item at position 1 in the playlist. player.addMediaItem(/* index= */ 1, MediaItem.fromUri(thirdUri)); // Moves the third media item from position 2 to the start of the playlist. player.moveMediaItem(/* currentIndex= */ 2, /* newIndex= */ 0); // Removes the first item from the playlist. player.removeMediaItem(/* index= */ 0); // Replace the second item in the playlist. player.replaceMediaItem(/* index= */ 1, MediaItem.fromUri(newUri));
プレイリスト全体の置き換えと消去もサポートされています。
Kotlin
// Replaces the playlist with a new one. val newItems: List<MediaItem> = listOf(MediaItem.fromUri(fourthUri), MediaItem.fromUri(fifthUri)) player.setMediaItems(newItems, /* resetPosition= */ true) // Clears the playlist. If prepared, the player transitions to the ended state. player.clearMediaItems()
Java
// Replaces the playlist with a new one. ImmutableList<MediaItem> newItems = ImmutableList.of(MediaItem.fromUri(fourthUri), MediaItem.fromUri(fifthUri)); player.setMediaItems(newItems, /* resetPosition= */ true); // Clears the playlist. If prepared, the player transitions to the ended state. player.clearMediaItems();
プレーヤーは、再生中の変更を自動的に正しい方法で処理します。
- 現在再生中の
MediaItem
が移動された場合、再生は中断されず、完了時に新しい後継が再生されます。 - 現在再生中の
MediaItem
が削除されると、プレーヤーは残りの最初の後継動画を自動的に再生します。このような後継が存在しない場合は、終了状態に移行します。 - 現在再生中の
MediaItem
が置き換えられた場合、再生に関連するMediaItem
のプロパティが変更されても、再生は中断されません。たとえば、ほとんどの場合、再生に影響を与えることなくMediaItem.MediaMetadata
フィールドを更新できます。
再生リストのクエリ
再生リストのクエリには、Player.getMediaItemCount
と Player.getMediaItemAt
を使用します。現在再生中のメディア アイテムは、Player.getCurrentMediaItem
を呼び出すことでクエリできます。再生リスト内の移動を簡略化する Player.hasNextMediaItem
や Player.getNextMediaItemIndex
などの便利なメソッドも他にもあります。
繰り返しモード
プレーヤーは 3 つの繰り返しモードをサポートしています。これは Player.setRepeatMode
でいつでも設定できます。
Player.REPEAT_MODE_OFF
: プレイリストは繰り返されず、プレイリストの最後のアイテムが再生されるとプレーヤーはPlayer.STATE_ENDED
に移行します。Player.REPEAT_MODE_ONE
: 現在の項目は無限ループ内で繰り返されます。Player.seekToNextMediaItem
などのメソッドはこれを無視し、リスト内の次の項目までシークします。このアイテムは無限ループで繰り返されます。Player.REPEAT_MODE_ALL
: プレイリスト全体がエンドレス ループで繰り返されます。
シャッフル モード
シャッフル モードは、Player.setShuffleModeEnabled
でいつでも有効または無効にできます。シャッフル モードでは、プレーヤーは事前に計算されたランダムな順序でプレイリストを再生します。すべてのアイテムが 1 回再生されます。シャッフル モードを Player.REPEAT_MODE_ALL
と組み合わせて、ランダムな同じ順序をエンドレス ループで繰り返すこともできます。シャッフル モードをオフにすると、現在のアイテムからプレイリストの元の位置から再生が続行されます。
Player.getCurrentMediaItemIndex
などのメソッドによって返されるインデックスは、常にシャッフルされていない元の順序を参照します。同様に、Player.seekToNextMediaItem
は player.getCurrentMediaItemIndex() + 1
のアイテムではなく、シャッフルの順序に従って次のアイテムを再生します。プレイリストに新しいアイテムを挿入したり、アイテムを削除したりすると、既存のシャッフルの順序は可能な限り変更されません。
カスタムのシャッフル順序の設定
デフォルトでは、プレーヤーは DefaultShuffleOrder
を使用したシャッフルをサポートしています。これをカスタマイズするには、カスタムのシャッフル順序の実装を指定するか、DefaultShuffleOrder
コンストラクタでカスタムの順序を設定します。
Kotlin
// Set a custom shuffle order for the 5 items currently in the playlist: exoPlayer.setShuffleOrder(DefaultShuffleOrder(intArrayOf(3, 1, 0, 4, 2), randomSeed)) // Enable shuffle mode. exoPlayer.shuffleModeEnabled = true
Java
// Set a custom shuffle order for the 5 items currently in the playlist: exoPlayer.setShuffleOrder(new DefaultShuffleOrder(new int[] {3, 1, 0, 4, 2}, randomSeed)); // Enable shuffle mode. exoPlayer.setShuffleModeEnabled(/* shuffleModeEnabled= */ true);
再生リスト アイテムの特定
プレイリスト アイテムを識別するには、アイテムの作成時に MediaItem.mediaId
を設定します。
Kotlin
// Build a media item with a media ID. val mediaItem = MediaItem.Builder().setUri(uri).setMediaId(mediaId).build()
Java
// Build a media item with a media ID. MediaItem mediaItem = new MediaItem.Builder().setUri(uri).setMediaId(mediaId).build();
アプリがメディア アイテムのメディア ID を明示的に定義していない場合は、URI の文字列表現が使用されます。
アプリデータをプレイリスト アイテムに関連付ける
ID に加えて、カスタムタグ(アプリ提供の任意のオブジェクト)を使用して各メディア アイテムを構成することもできます。カスタムタグの用途の一つは、各メディア アイテムにメタデータを適用することです。
Kotlin
// Build a media item with a custom tag. val mediaItem = MediaItem.Builder().setUri(uri).setTag(metadata).build()
Java
// Build a media item with a custom tag. MediaItem mediaItem = new MediaItem.Builder().setUri(uri).setTag(metadata).build();
再生が別のメディア アイテムに遷移したときに検出する
再生が別のメディア アイテムに切り替わるとき、または同じメディア アイテムが繰り返されると、Listener.onMediaItemTransition(MediaItem,
@MediaItemTransitionReason)
が呼び出されます。このコールバックは、新しいメディア アイテムと、遷移が発生した理由を示す @MediaItemTransitionReason
を受け取ります。onMediaItemTransition
の一般的なユースケースは、新しいメディア アイテム用にアプリの UI を更新することです。
Kotlin
override fun onMediaItemTransition( mediaItem: MediaItem?, @MediaItemTransitionReason reason: Int, ) { updateUiForPlayingMediaItem(mediaItem) }
Java
@Override public void onMediaItemTransition( @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) { updateUiForPlayingMediaItem(mediaItem); }
UI の更新に必要なメタデータがカスタムタグを使用して各メディア アイテムに添付されている場合、実装は次のようになります。
Kotlin
override fun onMediaItemTransition( mediaItem: MediaItem?, @MediaItemTransitionReason reason: Int, ) { var metadata: CustomMetadata? = null mediaItem?.localConfiguration?.let { localConfiguration -> metadata = localConfiguration.tag as? CustomMetadata } updateUiForPlayingMediaItem(metadata) }
Java
@Override public void onMediaItemTransition( @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) { @Nullable CustomMetadata metadata = null; if (mediaItem != null && mediaItem.localConfiguration != null) { metadata = (CustomMetadata) mediaItem.localConfiguration.tag; } updateUiForPlayingMediaItem(metadata); }
再生リストの変更を検出する
メディア アイテムが追加、削除、移動すると、すぐに TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED
で Listener.onTimelineChanged(Timeline, @TimelineChangeReason)
が呼び出されます。このコールバックは、プレーヤーが準備が完了していなくても呼び出されます。
Kotlin
override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) { if (reason == Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED) { // Update the UI according to the modified playlist (add, move or remove). updateUiForPlaylist(timeline) } }
Java
@Override public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) { if (reason == TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED) { // Update the UI according to the modified playlist (add, move or remove). updateUiForPlaylist(timeline); } }
再生リスト内のメディア アイテムの再生時間などの情報が利用可能になると、Timeline
が更新され、TIMELINE_CHANGE_REASON_SOURCE_UPDATE
で onTimelineChanged
が呼び出されます。他にも、以下のような理由でタイムラインが更新されます。
- アダプティブ メディア アイテムの準備後にマニフェストが利用可能になる。
- ライブ ストリームの再生中に定期的に更新されるマニフェスト。