ExoPlayer admite los siguientes formatos de imagen. Consulta Bibliotecas de carga de imágenes para obtener información sobre cómo realizar la integración con bibliotecas externas que pueden admitir un conjunto diferente de formatos.
Formato de imagen | Compatible | Notas |
---|---|---|
BMP | SÍ | |
GIF | NO | No es compatible con Extractor |
JPEG | SÍ | |
Foto en movimiento JPEG | SÍ | Se admiten imágenes fijas y videos |
JPEG Ultra HDR | SÍ | Recurre a SDR antes de Android 14 o en pantallas que no son HDR. |
PNG | SÍ | |
WebP | SÍ | |
HEIF/HEIC | SÍ | |
Foto en movimiento HEIC | Parcialmente | Solo se admiten imágenes fijas* |
AVIF (referencia) | SÍ | Solo se decodifica en Android 14 y versiones posteriores |
* La parte de video de las fotos en movimiento HEIC se puede obtener con MetadataRetriever y reproducir como un archivo independiente.
Cómo usar MediaItem
Para reproducir una imagen como parte de una playlist, crea un MediaItem
con el URI de la imagen y pásalo al reproductor. MediaItem
debe tener un imageDurationMs
para especificar durante cuánto tiempo se debe mostrar la imagen.
Kotlin
// 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()
Java
// 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();
Fotos en movimiento
Las fotos en movimiento son archivos que combinan una imagen fija con un video corto.
- Si la duración de la imagen se define con
setImageDuration
, la foto en movimiento se muestra durante la duración declarada como una imagen fija. - Si la duración de la imagen no está definida, la foto en movimiento se reproduce como un video.
Cómo usar ProgressiveMediaSource
Para obtener más opciones de personalización, puedes crear un ProgressiveMediaSource
y pasarlo directamente al reproductor en lugar de un MediaItem
.
Kotlin
// 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()
Java
// 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();
Cómo personalizar la reproducción
ExoPlayer ofrece varias formas de personalizar la experiencia de reproducción según las necesidades de tu app. Consulta la página Personalización para ver ejemplos.
Bibliotecas de carga de imágenes
A menudo, las imágenes se administran con bibliotecas externas de carga de imágenes, por ejemplo, Glide o Coil.
La integración de estas bibliotecas en la canalización de reproducción requiere 3 pasos:
- Define un
MediaItem
con el tipo de MIMEAPPLICATION_EXTERNALLY_LOADED_IMAGE
. - Proporciona un decodificador de imágenes para recuperar un
Bitmap
de la biblioteca de carga de imágenes. - Proporciona un cargador externo para activar la caché y la carga previa.
MediaItem con un tipo de MIME de imagen cargado de forma externa
El MediaItem
agregado al Player
debe definir el tipo de MIME APPLICATION_EXTERNALLY_LOADED_IMAGE
de forma explícita para usar las rutas de acceso de código de la biblioteca de carga de imágenes:
Kotlin
val mediaItem = MediaItem.Builder() .setUri(imageUri) .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE) .build()
Java
MediaItem mediaItem = new MediaItem.Builder() .setUri(imageUri) .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE) .build();
Decodificador de imágenes con una biblioteca de carga de imágenes
El renderizador de imágenes necesita un ExternallyLoadedImageDecoder
para recuperar el Bitmap
de Uri
. Para proporcionar este decodificador, anula DefaultRenderersFactory.getImageDecoderFactory
.
En el siguiente ejemplo, se usa Glide para cargar una imagen:
Kotlin
val glideImageDecoderFactory: ImageDecoder.Factory = ExternallyLoadedImageDecoder.Factory { request: ExternalImageRequest -> GlideFutures.submit(Glide.with(context).asBitmap().load(request.uri)) } val player: Player = ExoPlayer.Builder(context) .setRenderersFactory( object : DefaultRenderersFactory(context) { override fun getImageDecoderFactory(): ImageDecoder.Factory { return glideImageDecoderFactory } } ) .build()
Java
ImageDecoder.Factory glideImageDecoderFactory = new ExternallyLoadedImageDecoder.Factory( request -> GlideFutures.submit( Glide.with(context).asBitmap().load(request.uri))); Player player = new ExoPlayer.Builder(context) .setRenderersFactory( new DefaultRenderersFactory(context) { @Override protected ImageDecoder.Factory getImageDecoderFactory() { return glideImageDecoderFactory; } }) .build();
Carga previa de imágenes con una biblioteca de carga de imágenes
Durante la reproducción, el reproductor solicita la carga previa de la siguiente imagen una vez que se cargó por completo el elemento anterior de la playlist. Cuando usas una biblioteca de carga de imágenes externa, debes especificar un ExternalLoader
para activar esta carga previa. Si no es posible o no se requiere la carga previa, este cargador aún debe proporcionarse, pero no puede hacer nada.
En el siguiente ejemplo, se usa Glide para garantizar que la imagen solicitada se cargue previamente en el disco:
Kotlin
val glidePreloader = ExternalLoader { request: LoadRequest -> GlideFutures.submit( Glide.with(context) .asFile() .apply( RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.DATA) .priority(Priority.HIGH) .skipMemoryCache(true) ) .load(request.uri) ) }
Java
ExternalLoader glidePreloader = request -> GlideFutures.submit( Glide.with(context) .asFile() .apply( diskCacheStrategyOf(DiskCacheStrategy.DATA) .priority(Priority.HIGH) .skipMemoryCache(true)) .load(request.uri));