管理和播放内容

本页介绍了如何使用预加载管理器来管理视频内容。通过使用预加载管理器,您可以为用户提供更好的体验;当用户从一个媒体项切换到另一个媒体项时,播放会更快开始,因为管理器已加载部分内容。

本页面涵盖以下主题:

将媒体内容添加到预加载管理器

您必须告知预加载管理器它将跟踪的每个媒体项。 例如,如果您的应用包含视频轮播界面,您需要将这些视频添加到预加载管理器。根据您的使用情形,您可以添加所有视频,也可以只添加当前正在播放的视频附近的视频。您也可以稍后向预加载管理器添加新项。

添加媒体项本身并不会导致预加载管理器开始加载内容。如需触发预加载,您需要使预加载管理器中的优先级失效

val initialMediaItems = pullMediaItemsFromService(/* count= */ 20);
for (index in 0 until initialMediaItems.size) {
  preloadManager.add(initialMediaItems.get(index), /* rankingData= */ index)
}
// items aren't actually loaded yet! need to call invalidate() after this

代码要点

  • 此代码段展示了如何在创建预加载管理器后对其进行初始填充。您还可以调用 add() 将项添加到已填充的现有预加载管理器。
  • 在此代码段中,pullMediaItemsFromService() 是用于获取要播放的内容列表的应用逻辑。该代码会调用相应方法来提取最多 20 项的列表。
  • preloadManager 是在创建 DefaultPreloadManager 中创建的 DefaultPreloadManager。该代码会调用相应管理器的 add() 方法来添加轮播界面中的每个项。
  • rankingData 是预加载管理器用于确定每个媒体项优先级的数值。对于 DefaultPreloadManagerrankingData 是一个整数,表示相应项在轮播界面中的位置。预加载管理器会根据每个项与当前播放项的距离来确定优先级。

使预加载管理器中的优先级失效

如需触发预加载管理器开始预加载内容,您需要调用 invalidate() 来告知预加载管理器,各项的优先级已过时。在以下情况下,您应执行此操作:

  • 向预加载管理器添加新的媒体项或移除媒体项时。 如果您要添加或移除多个项,应先添加所有项,然后调用 invalidate()
  • 当用户从一个媒体项切换到另一个媒体项时。在这种情况下,您应确保在调用 invalidate() 之前更新当前播放索引,如提取和播放内容中所述。

当您使预加载管理器失效时,它会调用您创建的 TargetPreloadStatusControl,以确定应从每个项中加载多少内容。然后,它会按优先级从高到低的顺序加载每个项的内容。

preloadManager.invalidate()

代码要点

  • 调用 invalidate() 会触发预加载管理器重新评估其了解的每项媒体内容的优先级。因此,如果您要对预加载管理器进行大量更改,则应在调用 invalidate() 之前完成更改。

获取和播放媒体

当用户前进到新的媒体项时,您需要从预加载管理器中获取该媒体项。如果预加载管理器已加载任何内容,则内容播放速度会比您未使用预加载管理器时更快。如果预加载管理器尚未从相应项加载内容,则内容会正常播放。

// When a media item is about to display on the screen
val mediaSource = preloadManager.getMediaSource(mediaItem)
if (mediaSource != null) {
    player.setMediaSource(mediaSource)
}
player.prepare()

// When the media item is displaying at the center of the screen
player.play()
preloadManager.setCurrentPlayingIndex(currentIndex)

// Need to call invalidate() to update the priorities
preloadManager.invalidate()

代码要点

  • player 是应用用于播放内容的 Media3 ExoPlayer。您必须通过在用于创建预加载管理器的同一构建器上调用 DefaultPreloadManager.Builder.buildExoPlayer() 来创建该播放器。
  • 当用户切换到新的媒体项时,应用会调用 getMediaSource() 以从预加载管理器获取媒体源。必须是您已添加到预加载管理器mediaItem。即使预加载管理器尚未开始加载内容,也没关系;在这种情况下,它会返回一个没有预加载数据的 MediaSource。例如,如果用户突然在轮播界面中跳到很远的位置,就可能会发生这种情况。
  • 在用户播放新的媒体项后,调用 setCurrentPlayingIndex 以告知预加载管理器新项在轮播界面中的位置。预加载管理器需要该信息来确定加载下一项的优先级。更新当前索引后,调用 invalidate() 可让预加载管理器重新确定每个项目的优先级。

从预加载管理器中移除内容

为确保预加载管理器高效运行,您应移除预加载管理器不再需要跟踪的项目。您还可以移除仍位于轮播界面中但距离用户当前位置较远的内容。例如,您可能会决定,如果某个商品与用户正在观看的内容相差超过 15 项,则无需预加载该商品。在这种情况下,您会在商品距离过远时将其移除。如果用户重新向已移除的内容靠拢,您可以随时重新添加这些内容

preloadManager.remove(mediaItem)

代码要点

在完成预加载管理器后释放它

当您不再需要预加载管理器时,必须释放它以释放其资源。特别是,请务必在 activity 被销毁时释放它。

preloadManager.release()

代码要点

  • 释放对象后,您不得调用该对象的任何方法。
  • 如果您需要创建另一个预加载管理器,请创建一个新的 DefaultPreloadManager.Builder 并使用它来创建 DefaultPreloadManager。请勿尝试重复使用旧的 build 对象。