管理和播放内容

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

本页涵盖以下主题:

向预加载管理器添加媒体项

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

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

val initialMediaItems = pullMediaItemsFromService(count = 20)
for (index in 0 until initialMediaItems.size) {
  preloadManager.add(initialMediaItems[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)
} else {
  // If mediaSource is null, that mediaItem hasn't been added to the preload manager
  // yet. So, send it directly to the player when it's about to play
  player.setMediaItem(mediaItem)
}
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 个项,则无需预加载。在这种情况下,当项距离用户观看的内容超过 15 个项时,您需要移除这些项。如果用户返回到这些已移除的项, 您可以随时将其重新添加回来

preloadManager.remove(mediaItem)

代码要点

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

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

preloadManager.release()

代码要点

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