轨道选择

当媒体项包含多个轨道时,轨道选择就是 来决定选择哪个文件进行播放轨道选择流程 由 TrackSelectionParameters 配置,以允许许多不同的 用于影响要指定的轨道选择。

查询可用轨道

您可以监听Player.Listener.onTracksChanged,以便在有更改时收到通知 包括:

  • 在准备媒体项时了解可用的轨道 完整播放次数。请注意,播放器需要准备一个媒体项 其中包含哪些曲目
  • 播放模式从一种媒体播放时,可用曲目会发生变化 复制到另一个对象
  • 对所选轨道的更改。
KotlinJava
player.addListener(
 
object : Player.Listener {
   
override fun onTracksChanged(tracks: Tracks) {
     
// Update UI using current tracks.
   
}
 
}
)
player.addListener(
   
new Player.Listener() {
     
@Override
     
public void onTracksChanged(Tracks tracks) {
       
// Update UI using current tracks.
     
}
   
});

您还可以通过调用 player.getCurrentTracks() 查询当前轨道。 返回的 Tracks 包含 Track.Group 对象列表,其中 单个 Group 以不同的格式呈现相同的内容。

下面举例说明如何对曲目进行分组,我们以自适应播放为例, 一个主视频 Feed 有五种比特率,另一个视频 Feed (例如,体育比赛中的不同镜头角度)以两种比特率提供。 在本示例中,将有两个视频轨道组,一个对应于主视频轨道 包含 5 首曲目的视频 Feed,另有 1 秒的备用视频 Feed 包含两个轨道

由于语言不同的音轨内容 语言并不相同。相反,音轨 只不过在比特率、采样等属性方面存在差异 速率、通道数等都可以分组这也适用于文本轨道。

可以查询每个 Group,以确定支持哪些轨道 播放,当前所选的曲目,以及每首曲目使用的 Format

KotlinJava
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)
 
}
}
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 替换为修改后的结果:

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

基于约束条件的轨道选择

TrackSelectionParameters 中的大多数选项都允许您指定约束条件, 这些轨道与实际可用的轨道无关可用 限制包括:

  • 最大和最小视频宽度、高度、帧速率和比特率。
  • 最大音频声道数量和比特率。
  • 视频和音频的首选 MIME 类型。
  • 首选音频语言和角色标志。
  • 首选文本语言和角色标志。

ExoPlayer 会针对这些限制使用合理的默认值,例如 与显示器尺寸调整视频分辨率,并优先选择 与用户的系统语言区域设置一致。

与使用基于约束条件的轨道选择相比有几个好处 从现有的曲目中选择特定的曲目:

  • 您可以在了解媒体项提供的跟踪内容之前指定限制条件。 这意味着,可以在播放器准备好 媒体项,而选择特定轨道需要应用代码 等到已知可用轨道。
  • 限制条件会应用于播放列表中的所有媒体项,即使 项具有不同的可用轨道。例如,首选音频语言 限制条件将自动应用于所有媒体项,即使 该语言的曲目 Format 因媒体项而异。 如下所述,选择特定轨道时并不会出现这种情况。

选择特定轨道

您可以使用 TrackSelectionParameters 选择特定轨道。首先, 应使用 Player.getCurrentTracks。其次,确定了要选择的曲目后 您可以使用 TrackSelectionOverrideTrackSelectionParameters 上设置它们。 例如,如需从特定 audioTrackGroup 中选择第一首曲目,请使用以下代码:

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

TrackSelectionOverride 只会应用于包含 TrackGroup 与替换中指定的值完全匹配。因此, 如果后续媒体内容包含 不同曲目

停用轨道类型或轨道组

您可以使用视频、音频或文字等音轨类型 TrackSelectionParameters.Builder.setTrackTypeDisabled。已停用的轨道类型 将对所有媒体项停用:

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

或者,也可以阻止 TrackGroup,方法是为该组指定空替换项:

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

自定义轨道选择器

轨道的选择由 TrackSelector(一个实例)负责 每当构建 ExoPlayer 并在稍后获得 与ExoPlayer.getTrackSelector()共享。

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

DefaultTrackSelector 是一个适合大多数用途的灵活 TrackSelector 案例它使用 Player 中设置的 TrackSelectionParameters,还使用 提供了一些高级自定义选项, DefaultTrackSelector.ParametersBuilder:

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

隧道

如果渲染程序和 所选曲目支持该功能。为此,请使用 DefaultTrackSelector.ParametersBuilder.setTunnelingEnabled(true)

音频分流 (offload)

在以下情况下,您可以启用分流音频播放: 渲染程序和所选轨道支持它为此,请指定 您的TrackSelectionParameters中的AudioOffloadModePreferences

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