選取軌道

如果媒體項目包含多個曲目,曲目選取會由系統判斷要選擇播放哪個音軌的程序。音軌選取程序由 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 內的軌跡會以不同格式呈現相同的內容。

舉例來說,如何將軌道分組,假設提供自動調節播放功能,其中主要的視訊資訊提供以五位元率提供,而替代視訊動態饋給 (例如在運動比賽中的不同鏡頭角度) 則提供兩種位元率。在此情況下,將會有兩個視訊軌群組,一個對應至包含五個曲目的主要影片動態饋給,另一個則對應至包含兩個音軌的替代視訊動態饋給。

系統不會將不同語言的內容分組,因為不同語言的內容視為相同內容。相反地,如果音軌使用相同語言,只有位元率、取樣率、聲道數等屬性不同,這兩者可分組。這也適用於文字軌。

您可查詢每個 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 查詢玩家目前可用的測試群組。其次,您已決定要選取哪些測試群組,可以使用 TrackSelectionOverrideTrackSelectionParameters 上設定這些測試群組。例如,如要選取特定 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() 取得 ExoPlayer 時,就可以提供一個例項。

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