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:
- Zdefiniuj
MediaItemz typem MIMEAPPLICATION_EXTERNALLY_LOADED_IMAGE. - Podaj dekoder obrazu, aby pobrać
Bitmapz biblioteki do wczytywania obrazów. - 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();