Grafika

ExoPlayer obsługuje te formaty obrazów. Informacje o tym, jak zintegrować biblioteki zewnętrzne, które mogą obsługiwać inny zestaw formatów, znajdziesz w artykule Biblioteki do wczytywania obrazów.

Format obrazu Obsługiwane Uwagi
BMP TAK
GIF NIE Brak obsługi ekstraktora
JPEG TAK
Zdjęcie ruchome JPEG TAK Obsługiwane są obrazy statyczne i filmy
JPEG Ultra HDR TAK Przed Androidem 14 lub na wyświetlaczach bez HDR przełącza się na SDR
PNG TAK
WebP TAK
HEIF/HEIC TAK
Zdjęcie ruchome HEIC TAK
AVIF (podstawowy) TAK Dekodowane tylko na Androidzie 14 lub nowszym

Odtwarzanie obrazów na playliście

Aby odtworzyć obraz jako część playlisty, utwórz MediaItem z identyfikatorem URI obrazu i przekaż go do odtwarzacza. MediaItem musi mieć imageDurationMs, aby określić, jak długo obraz ma być wyświetlany.

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

Odtwarzanie zdjęć ruchomych

Zdjęcia ruchome to pliki łączące obraz statyczny z krótkim filmem.

  • Jeśli czas trwania obrazu jest zdefiniowany za pomocą setImageDuration, zdjęcie ruchome jest wyświetlane przez zadeklarowany czas jako obraz statyczny.
  • Jeśli czas trwania obrazu jest niezdefiniowany, zdjęcie ruchome jest odtwarzane jako film.

Dostosowywanie wczytywania obrazów za pomocą źródła multimediów

Aby uzyskać więcej opcji dostosowywania, możesz utworzyć ProgressiveMediaSource i przekazać go bezpośrednio do odtwarzacza zamiast 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();

Dostosowywanie odtwarzania

ExoPlayer udostępnia wiele sposobów dostosowania odtwarzania do potrzeb aplikacji. Przykłady znajdziesz na stronie Dostosowywanie.

Integracja zewnętrznych bibliotek do wczytywania obrazów

Obrazy są często zarządzane przez zewnętrzne biblioteki do wczytywania obrazów, np. Glide lub Coil.

Integracja tych bibliotek z potokiem odtwarzania wymaga 3 kroków:

  1. Zdefiniuj MediaItem z typem MIME APPLICATION_EXTERNALLY_LOADED_IMAGE.
  2. Podaj dekoder obrazu, aby pobrać Bitmap z biblioteki do wczytywania obrazów.
  3. Podaj zewnętrzny moduł wczytujący, aby uruchomić buforowanie i wstępne wczytywanie.

Konfigurowanie elementów multimedialnych do wczytywania zewnętrznego

MediaItem dodany do Player musi wyraźnie definiować typ MIME APPLICATION_EXTERNALLY_LOADED_IMAGE, aby używać ścieżek kodu biblioteki do wczytywania obrazów:

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

Dekodowanie obrazów za pomocą biblioteki zewnętrznej

Renderer obrazu potrzebuje ExternallyLoadedImageDecoder, aby pobrać Bitmap z Uri. Ten dekoder można podać, zastępując DefaultRenderersFactory.getImageDecoderFactory.

W tym przykładzie używamy Glide do wczytywania obrazu, ograniczając dane wyjściowe do rozmiaru wyświetlacza, aby uniknąć tworzenia bardzo dużych obiektów Bitmap:

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

Wstępne wczytywanie obrazów za pomocą biblioteki zewnętrznej

Podczas odtwarzania odtwarzacz wysyła prośbę o wstępne wczytanie następnego obrazu, gdy poprzedni element na playliście zostanie w pełni wczytany. Jeśli używasz zewnętrznej biblioteki do wczytywania obrazów zewnętrznych, musisz określić ExternalLoader, aby uruchomić wstępne wczytywanie. Jeśli wstępne wczytywanie nie jest możliwe lub wymagane, ten moduł wczytujący nadal musi być dostępny, ale może nic nie robić.

W tym przykładzie używamy Glide, aby zapewnić wstępne wczytanie żądanego obrazu na dysk:

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