Images

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 proporcionar compatibilidad con un conjunto diferente de formatos.

Formato de imagen Compatible Notas
BMP SÍ
GIF NO No hay compatibilidad con Extractor
JPEG SÍ
Foto en movimiento JPEG SÍ Admite imágenes estáticas y videos
JPEG Ultra HDR SÍ Se 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 SÍ
AVIF (modelo de referencia) SÍ Se decodifica solo en Android 14 y versiones posteriores

Reproducir imágenes en una playlist

Para reproducir una imagen como parte de una playlist, crea un MediaItem con el URI de la imagen y pásalo al reproductor. El 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();

Cómo reproducir fotos en movimiento

Las fotos en movimiento son archivos que combinan una imagen estática con un video corto.

  • Si la duración de la imagen se define con setImageDuration, la foto en movimiento se muestra durante el tiempo declarado como una imagen fija.
  • Si no se define la duración de la imagen, la foto en movimiento se reproduce como un video.

Cómo personalizar la carga de imágenes con una fuente de contenido multimedia

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: DataSource.Factory = 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();

Personaliza la reproducción

ExoPlayer ofrece varias formas de adaptar la experiencia de reproducción a las necesidades de tu app. Consulta la página de personalización para ver ejemplos.

Integra bibliotecas de carga de imágenes externas

Las imágenes suelen administrarse con bibliotecas de carga de imágenes externas, como Glide o Coil.

La integración de estas bibliotecas en la canalización de reproducción requiere 3 pasos:

  1. Define un MediaItem con el tipo de MIME APPLICATION_EXTERNALLY_LOADED_IMAGE.
  2. Proporciona un decodificador de imágenes para recuperar un Bitmap de la biblioteca de carga de imágenes.
  3. Proporcionar un cargador externo para activar el almacenamiento en caché y la carga previa

Configura elementos multimedia para la carga externa

El MediaItem que se agrega al Player debe definir el tipo de MIME APPLICATION_EXTERNALLY_LOADED_IMAGE de forma explícita para usar las instrucciones 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();

Decodifica imágenes con una biblioteca externa

El renderizador de imágenes necesita un ExternallyLoadedImageDecoder para recuperar el Bitmap del Uri. Este decodificador se puede proporcionar anulando DefaultRenderersFactory.getImageDecoderFactory.

En el siguiente ejemplo, se usa Glide para cargar una imagen, lo que limita el resultado al tamaño de visualización para evitar crear objetos Bitmap muy grandes:

Kotlin

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()

Java

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();

Carga imágenes de forma previa con una biblioteca externa

Durante la reproducción, el reproductor solicita que se cargue previamente la siguiente imagen una vez que se haya cargado por completo el elemento anterior de la playlist. Cuando uses una biblioteca externa de carga de imágenes, 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)
  )
}
val player: Player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setExternalImageLoader(glidePreloader)
    )
    .build()

Java

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();