ExoPlayer поддерживает следующие форматы изображений. Подробнее об интеграции с внешними библиотеками, которые могут поддерживать другие форматы, см. в разделе «Библиотеки загрузки изображений».
| Формат изображения | Поддерживается | Примечания |
|---|---|---|
| БМП | ДА | |
| GIF | НЕТ | Нет поддержки Extractor |
| JPEG | ДА | |
| JPEG-фото движения | ДА | Поддерживаются неподвижные изображения и видео |
| JPEG Ультра HDR | ДА | Возвращается к SDR до Android 14 или на дисплеях без HDR |
| PNG | ДА | |
| WebP | ДА | |
| HEIF/HEIC | ДА | |
| HEIC Motion Photo | Частично | Поддерживаются только неподвижные изображения* |
| AVIF (базовый) | ДА | Декодируется только на Android 14+ |
* Видеочасть фотографий движения HEIC можно получить с помощью MetadataRetriever и воспроизвести как отдельный файл.
Использование MediaItem
Чтобы воспроизвести изображение из плейлиста, создайте MediaItem с URI изображения и передайте его плееру. У MediaItem должно быть свойство imageDurationMs , определяющее длительность отображения изображения.
Котлин
// Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media item to be played with the desired duration. player.setMediaItem( MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build()) // Prepare the player. player.prepare()
Ява
// Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media item to be played with the desired duration. player.setMediaItem( new MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build()); // Prepare the player. player.prepare();
Фотографии движения
Движущиеся фотографии — это файлы, объединяющие неподвижное изображение с коротким видеороликом.
- Если длительность изображения определена с помощью
setImageDuration, движущееся фото будет отображаться в течение указанной длительности как неподвижное изображение. - Если длительность изображения не определена, движущееся фото воспроизводится как видео.
Использование ProgressiveMediaSource
Для дополнительных возможностей настройки вы можете создать ProgressiveMediaSource и передать его непосредственно проигрывателю вместо MediaItem .
Котлин
// Create a data source factory. val dataSourceFactory = DefaultHttpDataSource.Factory() // Create a media item with the image URI and the desired duration. val mediaItem = MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build() // Create a progressive media source for this media item. val mediaSource = ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem) // Create a player instance. val player = ExoPlayer.Builder(context).build() // Set the media source to be played. player.setMediaSource(mediaSource) // Prepare the player. player.prepare()
Ява
// Create a data source factory. DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory(); // Create a media item with the image URI and the desired duration. MediaItem mediaItem = new MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build(); // Create a progressive media source for this media item. MediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(mediaItem); // Create a player instance. ExoPlayer player = new ExoPlayer.Builder(context).build(); // Set the media source to be played. player.setMediaSource(mediaSource); // Prepare the player. player.prepare();
Настройка воспроизведения
ExoPlayer предоставляет множество способов настроить воспроизведение в соответствии с потребностями вашего приложения. Примеры см. на странице настроек .
Библиотеки загрузки изображений
Изображения часто управляются внешними библиотеками загрузки изображений, например Glide или Coil .
Интеграция этих библиотек в конвейер воспроизведения требует 3 шагов:
- Определите
MediaItemс типом MIMEAPPLICATION_EXTERNALLY_LOADED_IMAGE. - Предоставить декодер изображений для извлечения
Bitmapиз библиотеки загрузки изображений. - Предоставить внешний загрузчик для запуска кэширования и предварительной загрузки.
MediaItem с внешним загруженным типом изображения MIME
Для использования путей кода библиотеки загрузки изображений в элементе MediaItem , добавленном в Player необходимо явно определить тип MIME APPLICATION_EXTERNALLY_LOADED_IMAGE :
Котлин
val mediaItem = MediaItem.Builder() .setUri(imageUri) .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE) .build()
Ява
MediaItem mediaItem = new MediaItem.Builder() .setUri(imageUri) .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE) .build();
Декодер изображений с использованием библиотеки загрузки изображений
Для получения Bitmap изображения из Uri рендереру изображений необходим декодер ExternallyLoadedImageDecoder . Этот декодер можно получить, переопределив метод DefaultRenderersFactory.getImageDecoderFactory .
В следующем примере Glide используется для загрузки изображения, ограничивая вывод размером дисплея, чтобы избежать создания очень больших объектов Bitmap :
Котлин
val glideImageDecoderFactory: ImageDecoder.Factory = ExternallyLoadedImageDecoder.Factory { request: ExternalImageRequest -> val displaySize = Util.getCurrentDisplayModeSize(context) GlideFutures.submit( Glide.with(context) .asBitmap() .load(request.uri) .override(max(displaySize.x, displaySize.y))) } val player: Player = ExoPlayer.Builder(context) .setRenderersFactory( object : DefaultRenderersFactory(context) { override fun getImageDecoderFactory(context: Context): ImageDecoder.Factory { return glideImageDecoderFactory } } ) .build()
Ява
ImageDecoder.Factory glideImageDecoderFactory = new ExternallyLoadedImageDecoder.Factory( request -> { Point displaySize = Util.getCurrentDisplayModeSize(context); return GlideFutures.submit( Glide.with(context) .asBitmap() .load(request.uri) .override(max(displaySize.x, displaySize.y))); }); Player player = new ExoPlayer.Builder(context) .setRenderersFactory( new DefaultRenderersFactory(context) { @Override protected ImageDecoder.Factory getImageDecoderFactory(Context context) { return glideImageDecoderFactory; } }) .build();
Предварительная загрузка изображений с помощью библиотеки загрузки изображений
Во время воспроизведения плеер запрашивает предварительную загрузку следующего изображения после полной загрузки предыдущего элемента плейлиста. При использовании внешней библиотеки загрузки изображений необходимо указать загрузчик ExternalLoader для запуска этой предзагрузки. Если предварительная загрузка невозможна или не требуется, этот загрузчик всё равно необходимо предоставить, но он ничего не сделает.
В следующем примере Glide используется для обеспечения предварительной загрузки запрошенного изображения на диск:
Котлин
val glidePreloader = ExternalLoader { request: LoadRequest -> GlideFutures.submit( Glide.with(context) .asFile() .apply( RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.DATA) .priority(Priority.HIGH) .skipMemoryCache(true) ) .load(request.uri) ) } val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context) .setExternalImageLoader(glidePreloader)) .build()
Ява
ExternalLoader glidePreloader = request -> GlideFutures.submit( Glide.with(context) .asFile() .apply( diskCacheStrategyOf(DiskCacheStrategy.DATA) .priority(Priority.HIGH) .skipMemoryCache(true)) .load(request.uri)); Player player = new ExoPlayer.Builder(context) .setMediaSourceFactory(new DefaultMediaSourceFactory(context) .setExternalImageLoader(glidePreloader)) .build();