На этой странице описано, как создать DefaultPreloadManager, который предварительно загружает медиаконтент для вашего приложения на основе выбранной вами стратегии.
Менеджеры предварительной загрузки, основанные на абстрактном классе BasePreloadManager, позволяют ранжировать контент по выбранным вами критериям. В этом документе рассказывается, как использовать производный класс DefaultPreloadManager, в котором каждому мультимедийному объекту присваивается целое число, соответствующее его положению в списке (например, в карусели видео). Менеджер предварительной загрузки определяет приоритет загрузки объектов в зависимости от того, насколько они близки к объекту, который пользователь воспроизводит в данный момент. Таким образом, если пользователь переходит к другому элементу, новый элемент может начать воспроизведение сразу.
Чтобы создать экземпляр DefaultPreloadManager, выполните следующие действия:
- Определите
TargetPreloadStatusControl, который менеджер предзагрузки может запрашивать, чтобы узнать, готов ли мультимедийный объект к загрузке и сколько нужно загрузить. - Создайте конструктор, который будет использоваться для создания менеджера предзагрузки и объектов
ExoPlayerвашего приложения. - Создайте менеджер предзагрузки, вызвав метод
build().
Как создать элемент управления статусом целевой предзагрузки
При создании DefaultPreloadManager.Builder вы передадите ему определенный вами объект target preload status control. Этот объект реализует интерфейс TargetPreloadStatusControl. Когда менеджер предзагрузки готовится к предзагрузке медиаконтента, он вызывает метод getTargetPreloadStatus() элемента управления статусом, чтобы определить, нужно ли подготовить, загрузить или кешировать контент для мультимедийного объекта. При загрузке медиаданные предварительно загружаются непосредственно в буфер памяти проигрывателя, что позволяет мгновенно воспроизводить их, а при кешировании медиаданные сохраняются в постоянном кеше диска для экономии памяти проигрывателя. Элемент управления статусом может возвращать один из следующих кодов:
STAGE_SPECIFIED_RANGE_LOADED– менеджер предварительной загрузки должен загрузить контент с указанной начальной позиции и указанной продолжительности (в миллисекундах) в буфер памяти проигрывателя.STAGE_SPECIFIED_RANGE_CACHED. Менеджер предварительной загрузки должен кешировать контент, начиная с указанной позиции и в течение указанного времени (в миллисекундах), в кеш диска.STAGE_TRACKS_SELECTEDМенеджер предварительной загрузки должен загрузить и обработать информацию о дорожках контента и выбрать дорожки. Менеджер предварительной загрузки не должен начинать загрузку контента.STAGE_SOURCE_PREPARED– менеджер предварительной загрузки должен подготовить источник контента. Например, если метаданные контента находятся в отдельном файле манифеста, менеджер предварительной загрузки может получить и проанализировать этот манифест.null: менеджер предварительной загрузки не должен загружать контент или метаданные для этого мультимедийного объекта.
Вам нужно будет разработать стратегию, чтобы решить, сколько контента загружать для каждого мультимедийного объекта. В этом примере загружается больше контента для объектов, ближайших к воспроизводимому в данный момент. Если пользователь воспроизводит контент с индексом n, контроллер возвращает следующие коды:
- Индекс n+1 (следующий мультимедийный объект): загрузить 3000 мс (3 секунды) с позиции начала по умолчанию.
- Индекс n-1 (предыдущий мультимедийный объект): загрузка 1000 мс (1 секунда) с позиции начала по умолчанию.
- Другие мультимедийные объекты в диапазоне от n-2 до n+2: Return.
PreloadStatus.TRACKS_SELECTED - Другие мультимедийные объекты в диапазоне от n-4 до n+4: Return
PreloadStatus.SOURCE_PREPARED - Для всех остальных мультимедийных объектов возвращается
null.
class MyTargetPreloadStatusControl(var currentPlayingIndex: Int = 0) : 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.PRELOAD_STATUS_TRACKS_SELECTED } else if (abs(index - currentPlayingIndex) <= 4) { // return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_SOURCE_PREPARED } return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_NOT_PRELOADED } }
Важные сведения о коде
- При создании менеджера предзагрузки вы передадите ему экземпляр
MyTargetPreloadStatusControl. currentPlayingIndexсодержит индекс воспроизводимого в данный момент мультимедийного объекта. Приложение должно поддерживать это значение в актуальном состоянии.- Когда менеджер предзагрузки готов загрузить контент, он вызывает
getTargetPreloadStatusи передает информацию о ранжировании, которую вы указали для соответствующего мультимедийного объекта. В случае сDefaultPreloadManagerинформация о рейтинге представляет собой целое число, указывающее позицию элемента в карусели. Метод выбирает, какой код возвращать, сравнивая этот индекс с индексом элемента, выбранного в данный момент.
Создайте менеджер предзагрузки
Чтобы создать менеджер предзагрузки, вам понадобится DefaultPreloadManager.Builder.
Этот конструктор настроен с учетом текущего контекста и целевого элемента управления статусом предварительной загрузки приложения. Вы можете создать менеджер предзагрузки со всеми настройками по умолчанию.
val targetPreloadStatusControl = MyTargetPreloadStatusControl() val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl) val preloadManager = preloadManagerBuilder.build()
В конструкторе также есть методы, с помощью которых можно задать собственные компоненты менеджера предзагрузки.
Например, вы можете настроить целевой общий размер буфера для всех источников медиаконтента с предварительной загрузкой в DefaultPreloadManager, чтобы объем предварительно загруженных данных не превышал этот лимит. Вы можете настроить это ограничение с помощью setPlayerTargetBufferBytes(String, int) в пользовательском DefaultLoadControl.Builder с названием проигрывателя "preload" и передать этот экземпляр в конструктор менеджера предзагрузки:
val targetPreloadStatusControl = MyTargetPreloadStatusControl() val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl) preloadManagerBuilder.setLoadControl( DefaultLoadControl.Builder() .setPlayerTargetBufferBytes("preload", 128 * 1024 * 1024) // 128 MiB .build() ) val preloadManager = preloadManagerBuilder.build()
Методы настройки в конструкторе необязательны, но если вы хотите кешировать медиаобъекты на диск, необходимо настроить конструктор с помощью Cache, вызвав setCache(). Если кеш не настроен, попытка кешировать медиаобъекты приведет к ошибке IllegalStateException.
Создайте ExoPlayer для воспроизведения предварительно загруженного мультимедийного объекта.
Помимо создания менеджера предзагрузки, конструктор также используется для создания объектов ExoPlayer, которые приложение использует для воспроизведения контента. Это позволяет ExoPlayer правильно использовать компоненты совместно с менеджером предзагрузки. Вы по-прежнему можете задать настройки воспроизведения для ExoPlayer, передав экземпляр ExoPlayer.Builder с этими настройками.
// Direct creation val exoPlayer = preloadManagerBuilder.buildExoPlayer() // Creation with custom playback specific configurations val skipSilenceExoPlayerBuilder = ExoPlayer.Builder(context).setSkipSilenceEnabled(true) val skipSilenceExoPlayer = preloadManagerBuilder.buildExoPlayer(skipSilenceExoPlayerBuilder)