ExoPlayer hỗ trợ các định dạng hình ảnh sau. Hãy xem phần Thư viện tải hình ảnh để biết cách tích hợp với các thư viện bên ngoài có thể hỗ trợ một nhóm định dạng khác.
| Định dạng hình ảnh | Được hỗ trợ | Ghi chú |
|---|---|---|
| BMP | CÓ | |
| GIF | KHÔNG | Không hỗ trợ Trình trích xuất |
| JPEG | CÓ | |
| Ảnh động JPEG | CÓ | Hỗ trợ ảnh tĩnh và video |
| JPEG Ultra HDR | CÓ | Quay lại SDR trước Android 14 hoặc trên màn hình không hỗ trợ HDR |
| PNG | CÓ | |
| WebP | CÓ | |
| HEIF/HEIC | CÓ | |
| Ảnh chuyển động HEIC | Một phần | Chỉ hỗ trợ hình ảnh tĩnh* |
| AVIF (cơ sở) | CÓ | Chỉ được giải mã trên Android 14 trở lên |
* Bạn có thể lấy phần video của ảnh động HEIC bằng MetadataRetriever và phát dưới dạng một tệp độc lập.
Sử dụng MediaItem
Để phát một hình ảnh trong danh sách phát, hãy tạo một MediaItem bằng URI hình ảnh và truyền URI đó đến trình phát. MediaItem phải có imageDurationMs để chỉ định thời gian hiển thị hình ảnh.
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();
Ảnh chuyển động
Ảnh chuyển động là những tệp kết hợp một ảnh tĩnh với một video ngắn.
- Nếu thời lượng của hình ảnh được xác định bằng
setImageDuration, thì ảnh chuyển động sẽ hiển thị dưới dạng ảnh tĩnh trong thời lượng đã khai báo. - Nếu thời lượng của hình ảnh không xác định, ảnh chuyển động sẽ được phát dưới dạng video.
Sử dụng ProgressiveMediaSource
Để có thêm các lựa chọn tuỳ chỉnh, bạn có thể tạo một ProgressiveMediaSource và truyền trực tiếp đến trình phát thay vì 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();
Tuỳ chỉnh chế độ phát
ExoPlayer cung cấp nhiều cách để bạn điều chỉnh trải nghiệm phát cho phù hợp với nhu cầu của ứng dụng. Hãy xem trang Tuỳ chỉnh để tham khảo các ví dụ.
Thư viện tải hình ảnh
Hình ảnh thường được quản lý bằng các thư viện tải hình ảnh bên ngoài, chẳng hạn như Glide hoặc Coil.
Để tích hợp các thư viện này vào quy trình phát, bạn cần thực hiện 3 bước:
- Xác định
MediaItembằng loại MIMEAPPLICATION_EXTERNALLY_LOADED_IMAGE. - Cung cấp một bộ giải mã hình ảnh để truy xuất
Bitmaptừ thư viện tải hình ảnh. - Cung cấp một trình tải bên ngoài để kích hoạt tính năng lưu vào bộ nhớ đệm và tải trước.
MediaItem có loại MIME hình ảnh được tải bên ngoài
MediaItem được thêm vào Player phải xác định rõ loại MIME APPLICATION_EXTERNALLY_LOADED_IMAGE để sử dụng các đường dẫn mã thư viện tải hình ảnh:
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();
Trình giải mã hình ảnh bằng thư viện tải hình ảnh
Trình kết xuất hình ảnh cần có một ExternallyLoadedImageDecoder để truy xuất Bitmap từ Uri. Bạn có thể cung cấp bộ giải mã này bằng cách ghi đè DefaultRenderersFactory.getImageDecoderFactory.
Ví dụ sau đây sử dụng Glide để tải một hình ảnh, giới hạn đầu ra ở kích thước màn hình để tránh tạo các đối tượng Bitmap có kích thước rất lớn:
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();
Tải trước hình ảnh bằng thư viện tải hình ảnh
Trong quá trình phát, trình phát sẽ yêu cầu tải trước hình ảnh tiếp theo sau khi mục trước đó trong danh sách phát đã tải xong. Khi sử dụng một thư viện tải hình ảnh bên ngoài, bạn phải chỉ định một ExternalLoader để kích hoạt quá trình tải trước này. Nếu không thể hoặc không cần tải trước, bạn vẫn cần cung cấp trình tải này nhưng không cần làm gì cả.
Ví dụ sau đây sử dụng Glide để đảm bảo rằng hình ảnh được yêu cầu đã được tải trước vào ổ đĩa:
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 = 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();