创建并配置 DefaultPreloadManager

本文介绍了如何创建 DefaultPreloadManager,该预加载管理器会根据您选择的策略预加载应用中的媒体内容。

通过使用基于 BasePreloadManager 抽象类的预加载管理器,您可以根据所选条件对内容进行排名。本文档介绍了如何使用派生类 DefaultPreloadManager,其中每个媒体项都按整数进行排名,该整数表示相应媒体项在列表中的位置(例如,在视频轮播界面中的位置)。预加载管理器会根据用户当前播放的内容与待加载内容的接近程度,来确定待加载内容的加载优先级。采取这种方式时,如果用户移至另一项内容,新内容可以立即开始播放。

创建 DefaultPreloadManager 实例需要执行以下三个步骤:

  • 定义一个 TargetPreloadStatusControl,预加载管理器可以查询该对象,以确定媒体项是否已准备好加载以及要加载多少内容。
  • 创建一个构建器,您将使用该构建器来创建预加载管理器,并创建应用的 ExoPlayer 对象。
  • 使用该构建器通过调用构建器的 build() 方法来创建预加载管理器。

创建目标预加载状态控件

创建 DefaultPreloadManager.Builder 时,您需要向其传递自定义的目标预加载状态控件对象。此对象会实现 TargetPreloadStatusControl 接口。预加载管理器准备好预加载媒体时,会调用此状态控件的 getTargetPreloadStatus() 方法来确定要加载多少内容。此状态控件可回复以下任一状态代码:

  • STAGE_SPECIFIED_RANGE_LOADED:预加载管理器应从指定的开始位置加载内容,且加载时长应达到指定的时长(以毫秒为单位)。
  • STAGE_TRACKS_SELECTED:预加载管理器应加载并处理内容轨道的信息,然后选择轨道。预加载管理器不应开始加载内容。
  • STAGE_SOURCE_PREPARED:预加载管理器应准备内容来源。例如,如果内容的元数据位于单独的清单文件中,则预加载管理器可能会提取并解析该清单。
  • null:预加载管理器不应加载相应媒体项的任何内容或元数据。

您需要制定策略来决定为每个媒体项加载多少内容。在此示例中,系统会为最接近当前播放项的媒体项加载更多内容。如果用户正在播放索引为 n 的内容,则控制器会返回以下代码:

  • 索引 n+1(下一个媒体项):从默认起始位置加载 3000 毫秒(3 秒)
  • 索引 n-1(上一个媒体项):从默认起始位置加载 1000 毫秒(1 秒)
  • 范围为 n-2n+2 的其他媒体项:返回 PreloadStatus.TRACKS_SELECTED
  • 范围为 n-4n+4 的其他媒体项:返回 PreloadStatus.SOURCE_PREPARED
  • 对于所有其他媒体项,返回 null

class MyTargetPreloadStatusControl(
    currentPlayingIndex: Int = C.INDEX_UNSET
) : TargetPreloadStatusControl<Int, DefaultPreloadManager.PreloadStatus> {

    override fun getTargetPreloadStatus(index: Int): DefaultPreloadManager.PreloadStatus? {
        if (index - currentPlayingIndex == 1) { // next track
            // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and
            // suggest loading 3000ms from the default start position
            return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L)
        } else if (index - currentPlayingIndex == -1) { // previous track
            // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and
            // suggest loading 3000ms from the default start position
            return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L)
        } else if (abs(index - currentPlayingIndex) == 2) {
            // return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED
            return DefaultPreloadManager.PreloadStatus.TRACKS_SELECTED
        } else if (abs(index - currentPlayingIndex) <= 4) {
            // return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED
            return DefaultPreloadManager.PreloadStatus.SOURCE_PREPARED
        }
        return null
    }
}

代码要点

  • 创建预加载管理器构建器时,您需要向其传递 MyTargetPreloadStatusControl 的实例。
  • currentPlayingIndex 用于存储当前正在播放的媒体项的索引。应用须确保该值保持最新状态。
  • 预加载管理器准备好加载内容时,会调用 getTargetPreloadStatus 并传递您为相应媒体项指定的排名信息。对于 DefaultPreloadManager,相应排名信息是一个整数,用于指定相应媒体项在轮播界面中的位置。该方法通过将该索引与当前所选媒体项的索引进行比较,来选择要返回的代码。

创建预加载管理器

如需创建预加载管理器,您需要一个 DefaultPreloadManager.Builder。 该构建器配置了当前上下文和应用的目标预加载状态控件。该构建器还提供 setter 方法,您可以使用这些方法来设置预加载管理器的自定义组件。

除了使用该构建器来创建预加载管理器之外,您还可以使用它来创建应用用于播放内容的 ExoPlayer 对象。

val targetPreloadStatusControl = MyTargetPreloadStatusControl()
val preloadManagerBuilder =
    DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
val preloadManager = preloadManagerBuilder.build()

代码要点

  • MyTargetPreloadStatusControl 是您在创建目标预加载状态控件中定义的类。
  • 您将使用相同的 DefaultPreloadManager.Builder 来创建 ExoPlayer 对象,这些对象将播放由相应预加载管理器管理的内容。