如果媒體項目包含多個音軌,系統會透過音軌選取程序,決定要播放哪個音軌。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());