本页介绍了如何使用预加载管理器来管理视频内容。通过使用预加载管理器,您可以为用户提供更好的体验;当用户从一个媒体项切换到另一个媒体项时,播放会更快开始,因为管理器已加载部分内容。
本页面涵盖以下主题:
将媒体内容添加到预加载管理器
您必须告知预加载管理器它将跟踪的每个媒体项。 例如,如果您的应用包含视频轮播界面,您需要将这些视频添加到预加载管理器。根据您的使用情形,您可以添加所有视频,也可以只添加当前正在播放的视频附近的视频。您也可以稍后向预加载管理器添加新项。
添加媒体项本身并不会导致预加载管理器开始加载内容。如需触发预加载,您需要使预加载管理器中的优先级失效。
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
是预加载管理器用于确定每个媒体项优先级的数值。对于DefaultPreloadManager
,rankingData
是一个整数,表示相应项在轮播界面中的位置。预加载管理器会根据每个项与当前播放项的距离来确定优先级。
使预加载管理器中的优先级失效
如需触发预加载管理器开始预加载内容,您需要调用 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
是应用用于播放内容的 Media3ExoPlayer
。您必须通过在用于创建预加载管理器的同一构建器上调用DefaultPreloadManager.Builder.buildExoPlayer()
来创建该播放器。- 当用户切换到新的媒体项时,应用会调用
getMediaSource()
以从预加载管理器获取媒体源。必须是您已添加到预加载管理器的mediaItem
。即使预加载管理器尚未开始加载内容,也没关系;在这种情况下,它会返回一个没有预加载数据的MediaSource
。例如,如果用户突然在轮播界面中跳到很远的位置,就可能会发生这种情况。 - 在用户播放新的媒体项后,调用
setCurrentPlayingIndex
以告知预加载管理器新项在轮播界面中的位置。预加载管理器需要该信息来确定加载下一项的优先级。更新当前索引后,调用invalidate()
可让预加载管理器重新确定每个项目的优先级。
从预加载管理器中移除内容
为确保预加载管理器高效运行,您应移除预加载管理器不再需要跟踪的项目。您还可以移除仍位于轮播界面中但距离用户当前位置较远的内容。例如,您可能会决定,如果某个商品与用户正在观看的内容相差超过 15 项,则无需预加载该商品。在这种情况下,您会在商品距离过远时将其移除。如果用户重新向已移除的内容靠拢,您可以随时重新添加这些内容。
preloadManager.remove(mediaItem)
代码要点
- 如果您想从预加载管理器中移除所有项,可以调用
reset()
而不是remove()
。如果您需要更改轮播界面中的所有项目,此方法非常有用。在这种情况下,移除相应项后,您需要向预加载管理器添加新项,然后使预加载管理器中的优先级失效。
在完成预加载管理器后释放它
当您不再需要预加载管理器时,必须释放它以释放其资源。特别是,请务必在 activity 被销毁时释放它。
preloadManager.release()
代码要点
- 释放对象后,您不得调用该对象的任何方法。
- 如果您需要创建另一个预加载管理器,请创建一个新的
DefaultPreloadManager.Builder
并使用它来创建DefaultPreloadManager
。请勿尝试重复使用旧的 build 对象。