재생목록

playlist API는 다음과 같이 구현되는 Player 인터페이스로 정의됩니다. 모든 ExoPlayer 구현을 포함합니다. 재생목록을 사용하면 여러 동영상을 연속적으로 재생할 수 있습니다. 미디어 항목입니다. 다음 예는 재생목록 재생을 시작하는 방법을 보여줍니다. 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()

자바

// 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))

자바

// 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()

자바

// 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.getMediaItemCountPlayer.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 셔플 모드에서는 플레이어가 미리 계산된 임의의 순서로 재생목록을 만듭니다. 모든 항목이 한 번 재생되며 셔플 모드를 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

자바

// 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()

자바

// Build a media item with a media ID.
MediaItem mediaItem = new MediaItem.Builder().setUri(uri).setMediaId(mediaId).build();

앱이 미디어 항목의 미디어 ID를 명시적으로 정의하지 않는 경우 사용됩니다

앱 데이터를 재생목록 항목과 연결

ID 외에도 각 미디어 항목은 맞춤 태그, 이는 앱에서 제공하는 모든 객체일 수 있습니다. 맞춤 태그의 용도 중 하나는 메타데이터로 각 미디어 항목에 대한 메타데이터를 제공합니다

Kotlin

// Build a media item with a custom tag.
val mediaItem = MediaItem.Builder().setUri(uri).setTag(metadata).build()

자바

// 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)
}

자바

@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)
}

자바

@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);
}

재생목록 변경 감지

미디어 항목이 추가, 삭제 또는 이동될 때 Listener.onTimelineChanged(Timeline, @TimelineChangeReason)가 호출됩니다. TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED로 즉시. 이 콜백은 플레이어가 아직 준비되지 않은 경우에도 호출됩니다.

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)
  }
}

자바

@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가 업데이트되고 onTimelineChanged가 호출됩니다. TIMELINE_CHANGE_REASON_SOURCE_UPDATE. ANR을 일으킬 수 있는 다른 이유 타임라인 업데이트에는 다음이 포함됩니다.

  • 적응형 미디어 항목을 준비한 후 매니페스트를 사용할 수 있게 됩니다.
  • 라이브 스트림 재생 중 주기적으로 업데이트되는 매니페스트