트랙 선택

미디어 항목에 여러 트랙이 포함된 경우 트랙 선택은 그중 어떤 트랙을 재생할지 결정하는 프로세스입니다. 트랙 선택 프로세스는 TrackSelectionParameters로 구성되며, 이를 통해 다양한 제약 조건을 허용하고 트랙 선택에 영향을 미치는 재정의를 지정할 수 있습니다.

사용 가능한 트랙 쿼리

Player.Listener.onTracksChanged를 수신 대기하여 다음을 포함한 트랙 변경 관련 알림을 받을 수 있습니다.

  • 재생 중인 미디어 항목의 준비가 완료될 때 확인되는 사용 가능한 트랙 플레이어는 미디어 항목에 포함된 트랙을 파악하기 위해 미디어 항목을 준비해야 합니다.
  • 한 미디어 항목에서 다른 미디어 항목으로의 재생 전환으로 인해 사용 가능한 트랙이 변경됨
  • 선택한 트랙의 변경사항입니다.

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTracksChanged(tracks: Tracks) {
      // Update UI using current tracks.
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onTracksChanged(Tracks tracks) {
        // Update UI using current tracks.
      }
    });

player.getCurrentTracks()를 호출하여 현재 트랙을 쿼리할 수도 있습니다. 반환된 Tracks에는 Track.Group 객체의 목록이 포함되며, 여기서 단일 Group 내의 트랙은 동일한 콘텐츠를 다른 형식으로 나타냅니다.

트랙을 그룹화하는 방법의 예로 기본 동영상 피드가 5가지 비트 전송률로 제공되고 대체 동영상 피드(예: 스포츠 경기에서 다른 카메라 각도)가 2비트 비트 전송률로 제공되는 적응형 재생을 고려해 보세요. 이 경우 동영상 트랙 그룹이 2개 있습니다. 하나는 트랙 5개가 포함된 기본 동영상 피드에 해당하고 다른 하나는 트랙 2개가 포함된 대체 동영상 피드에 해당합니다.

다른 언어의 콘텐츠는 동일한 것으로 간주되지 않으므로 언어가 다른 오디오 트랙은 그룹화되지 않습니다. 반대로 동일한 언어로 된 오디오 트랙은 비트 전송률, 샘플링 레이트, 채널 수 등의 속성만 다른 경우 그룹화할 수 있습니다. 이는 텍스트 트랙에도 적용됩니다.

Group를 쿼리하여 재생이 지원되는 트랙, 현재 선택된 트랙, 각 트랙에서 사용하는 Format를 확인할 수 있습니다.

Kotlin

for (trackGroup in tracks.groups) {
  // Group level information.
  val trackType = trackGroup.type
  val trackInGroupIsSelected = trackGroup.isSelected
  val trackInGroupIsSupported = trackGroup.isSupported
  for (i in 0 until trackGroup.length) {
    // Individual track information.
    val isSupported = trackGroup.isTrackSupported(i)
    val isSelected = trackGroup.isTrackSelected(i)
    val trackFormat = trackGroup.getTrackFormat(i)
  }
}

Java

for (Tracks.Group trackGroup : tracks.getGroups()) {
  // Group level information.
  @C.TrackType int trackType = trackGroup.getType();
  boolean trackInGroupIsSelected = trackGroup.isSelected();
  boolean trackInGroupIsSupported = trackGroup.isSupported();
  for (int i = 0; i < trackGroup.length; i++) {
    // Individual track information.
    boolean isSupported = trackGroup.isTrackSupported(i);
    boolean isSelected = trackGroup.isTrackSelected(i);
    Format trackFormat = trackGroup.getTrackFormat(i);
  }
}

  • Player가 샘플을 디코딩하고 렌더링할 수 있으면 트랙이 지원됩니다. 동일한 유형의 여러 트랙 그룹 (예: 여러 오디오 트랙 그룹)이 지원되는 경우에도 이는 개별적으로 지원되며 플레이어가 동시에 재생할 수 없는 것은 아닙니다.
  • 트랙이 현재 TrackSelectionParameters을 고려하여 재생용으로 선택된 경우 트랙이 선택됩니다. 한 트랙 그룹 내의 여러 트랙이 선택된 경우 플레이어는 이 트랙을 적응형 재생에 사용합니다 (예: 비트 전송률이 다른 동영상 트랙 여러 개). 이러한 트랙 중 한 번에 하나만 재생됩니다.

트랙 선택 매개변수 수정

트랙 선택 프로세스는 Player.setTrackSelectionParameters를 사용하여 구성할 수 있습니다. 재생 전과 재생 중에 이 작업을 할 수 있습니다. 다음 예는 플레이어에서 현재 TrackSelectionParameters를 가져와서 수정한 후 수정된 결과로 Player를 업데이트하는 방법을 보여줍니다.

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setMaxVideoSizeSd()
    .setPreferredAudioLanguage("hu")
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setMaxVideoSizeSd()
        .setPreferredAudioLanguage("hu")
        .build());

제약 조건 기반 트랙 선택

TrackSelectionParameters의 옵션 대부분을 사용하면 제약 조건을 지정할 수 있습니다. 제약 조건은 실제로 사용 가능한 트랙과 별개입니다. 사용 가능한 제약조건은 다음과 같습니다.

  • 최대 및 최소 동영상 너비, 높이, 프레임 속도, 비트 전송률
  • 최대 오디오 채널 수 및 비트 전송률입니다.
  • 동영상 및 오디오의 기본 MIME 유형입니다.
  • 선호하는 오디오 언어 및 역할 플래그
  • 기본 텍스트 언어 및 역할 플래그

ExoPlayer는 이러한 제약 조건에 적절한 기본값을 사용합니다. 예를 들어 동영상 해상도를 디스플레이 크기로 제한하고 사용자의 시스템 언어 설정과 일치하는 오디오 언어를 선호합니다.

사용 가능한 트랙 중에서 특정 트랙을 선택하는 대신 제약 조건 기반 트랙 선택을 사용하면 다음과 같은 여러 이점이 있습니다.

  • 미디어 항목이 제공하는 트랙을 알기 전에 제약 조건을 지정할 수 있습니다. 즉, 플레이어가 미디어 항목을 준비하기 전에 제약조건을 지정할 수 있는 반면, 특정 트랙을 선택하려면 사용 가능한 트랙이 알려질 때까지 애플리케이션 코드를 기다려야 합니다.
  • 제약 조건은 재생목록의 모든 미디어 항목에 사용 가능한 다른 트랙이 있는 경우에도 적용됩니다. 예를 들어 기본 오디오 언어 제약 조건은 해당 언어로 된 트랙의 Format가 미디어 항목마다 다르더라도 모든 미디어 항목에 자동으로 적용됩니다. 아래 설명과 같이 특정 트랙을 선택하는 경우에는 적용되지 않습니다.

특정 트랙 선택하기

TrackSelectionParameters를 사용하여 특정 트랙을 선택할 수 있습니다. 첫째, 플레이어의 현재 사용 가능한 트랙을 Player.getCurrentTracks를 사용하여 쿼리해야 합니다. 둘째, 선택할 트랙을 식별했으면 TrackSelectionOverride를 사용하여 TrackSelectionParameters에 설정할 수 있습니다. 예를 들어 특정 audioTrackGroup에서 첫 번째 트랙을 선택하려면 다음을 실행합니다.

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setOverrideForType(
      TrackSelectionOverride(audioTrackGroup.mediaTrackGroup, /* trackIndex= */ 0)
    )
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setOverrideForType(
            new TrackSelectionOverride(
                audioTrackGroup.getMediaTrackGroup(), /* trackIndex= */ 0))
        .build());

TrackSelectionOverride는 재정의에 지정된 것과 정확하게 일치하는 TrackGroup가 포함된 미디어 항목에만 적용됩니다. 따라서 후속 미디어 항목에 다른 트랙이 포함된 경우 재정의가 후속 미디어 항목에 적용되지 않을 수도 있습니다.

트랙 유형 또는 그룹 사용 중지

동영상, 오디오, 텍스트와 같은 트랙 유형은 TrackSelectionParameters.Builder.setTrackTypeDisabled를 사용하여 완전히 사용 중지할 수 있습니다. 사용 중지된 트랙 유형은 모든 미디어 항목에서 사용 중지됩니다.

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true)
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .setTrackTypeDisabled(C.TRACK_TYPE_VIDEO, /* disabled= */ true)
        .build());

또는 특정 그룹에 빈 재정의를 지정하여 특정 TrackGroup에서 트랙을 선택하지 못하게 할 수 있습니다.

Kotlin

player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .addOverride(
      TrackSelectionOverride(disabledTrackGroup.mediaTrackGroup, /* trackIndices= */ listOf())
    )
    .build()

Java

player.setTrackSelectionParameters(
    player
        .getTrackSelectionParameters()
        .buildUpon()
        .addOverride(
            new TrackSelectionOverride(
                disabledTrackGroup.getMediaTrackGroup(),
                /* trackIndices= */ ImmutableList.of()))
        .build());

트랙 선택기 맞춤설정

트랙 선택은 TrackSelector를 담당합니다. 이 인스턴스는 ExoPlayer가 빌드되고 나중에 ExoPlayer.getTrackSelector()로 획득될 때마다 제공될 수 있습니다.

Kotlin

val trackSelector = DefaultTrackSelector(context)
val player = ExoPlayer.Builder(context).setTrackSelector(trackSelector).build()

Java

DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
ExoPlayer player = new ExoPlayer.Builder(context).setTrackSelector(trackSelector).build();

DefaultTrackSelector는 대부분의 사용 사례에 적합한 유연한 TrackSelector입니다. Player에 설정된 TrackSelectionParameters를 사용하지만 DefaultTrackSelector.ParametersBuilder에 지정할 수 있는 고급 맞춤설정 옵션도 제공합니다.

Kotlin

trackSelector.setParameters(
  trackSelector.buildUponParameters().setAllowVideoMixedMimeTypeAdaptiveness(true))
)

Java

trackSelector.setParameters(
    trackSelector.buildUponParameters().setAllowVideoMixedMimeTypeAdaptiveness(true));

터널링

렌더기와 선택된 트랙의 조합에서 지원되는 경우 터널링된 재생을 사용 설정할 수 있습니다. 이렇게 하려면 DefaultTrackSelector.ParametersBuilder.setTunnelingEnabled(true)를 사용하세요.

오디오 오프로드

렌더러와 선택한 트랙의 조합에서 지원되는 경우 오프로드된 오디오 재생을 사용 설정할 수 있습니다. 이렇게 하려면 TrackSelectionParameters에서 AudioOffloadModePreferences를 지정합니다.

Kotlin

val audioOffloadPreferences =
  AudioOffloadPreferences.Builder()
      .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
      // Add additional options as needed
      .setIsGaplessSupportRequired(true)
      .build()
player.trackSelectionParameters =
  player.trackSelectionParameters
    .buildUpon()
    .setAudioOffloadPreferences(audioOffloadPreferences)
    .build()

Java

AudioOffloadPreferences audioOffloadPreferences =
  new AudioOffloadPreferences.Builder()
      .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
      // Add additional options as needed
      .setIsGaplessSupportRequired(true)
      .build();
player.setTrackSelectionParameters(
  player.getTrackSelectionParameters()
    .buildUpon()
    .setAudioOffloadPreferences(audioOffloadPreferences)
    .build());
);