管理和播放内容

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

本页面涵盖以下主题:

将媒体文件添加到预加载管理器

您必须向预加载管理器告知它将跟踪的每个媒体文件。例如,如果您的应用有一个视频轮播界面,您需要将这些视频添加到预加载管理器中。根据您的应用场景,您可以添加所有视频,也可以仅添加当前播放的视频附近的视频。您也可以稍后向预加载管理器添加新内容。

为此,请使用 addMediaItems 等批量添加方法。或者,您也可以调用 add(或 addMediaSource)来单独添加媒体文件。不过,单独添加媒体文件不会自动触发预加载。使用单个方法时,您必须在添加完内容后显式调用 invalidate,以告知预加载管理器更新优先级并开始预加载。

val initialMediaItems = pullMediaItemsFromService(count = 20)
val rankingDataList = initialMediaItems.indices.toList()
preloadManager.addMediaItems(initialMediaItems, rankingDataList)

代码要点

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

提取和播放媒体

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

您还需要通过调用 setCurrentPlayingIndex 来更新预加载管理器上的当前播放索引,以便预加载管理器确定未来预加载操作的优先级。

// When a media item is about to be displayed on the screen
val mediaSource = preloadManager.getMediaSource(mediaItem)
if (mediaSource != null) {
  player.setMediaSource(mediaSource)
} else {
  // If the mediaSource is null, its mediaItem hasn't been added to the preload
  // manager yet. Send it directly to the player when it's about to play.
  player.setMediaItem(mediaItem)
}
player.prepare()

// When the media item is being displayed at the center of the screen ("in focus")
player.play()
// Update the current playing index to let the preload manager know where the user
// is in the carousel/pagination/list.
preloadManager.setCurrentPlayingIndex(currentIndex)

代码要点

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

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

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

如果您有要移除的媒体文件列表,可以使用 removeMediaItems。或者,您也可以调用 remove(或 removeMediaSource)来逐个移除媒体文件。

preloadManager.removeMediaItems(mediaItemsToRemove)

代码要点

  • 如果您想从预加载管理器中移除所有内容,可以调用 reset(),而不是 remove()。如果您需要更改轮播界面中的所有内容,此方法会很有用。在这种情况下,移除内容后,您需要向预加载管理器添加新内容。

使用完预加载管理器后,将其释放

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

preloadManager.release()

代码要点

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