選取軌道

如果媒體項目包含多個音軌,系統會透過音軌選取程序,決定要播放哪些音軌。音軌選擇程序是由 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 包含 Tracks.Group 物件的清單,其中單一 Group 中的曲目會以不同格式呈現相同內容。

舉例來說,在自適應播放功能中,主要影片動態饋給會以五種位元率提供,而替代影片動態饋給 (例如體育賽事中不同鏡頭角度的影片) 則會以兩種位元率提供。在這種情況下,系統會建立兩個影片軌群組,一個對應至包含五個軌的影片動態饋給,另一個則對應至包含兩個軌的替代影片動態饋給。

系統不會將語言不同的音軌分組,因為不同語言的內容不屬於相同內容。相反地,如果音訊曲目使用相同的語言,且僅在位元率、取樣率、聲道數等屬性上有所差異,則可以將這些音訊曲目分組。這也適用於文字音軌。

您可以查詢每個 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());
);