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ợ nhiều định dạng.
Định dạng hình ảnh | Có thể làm | 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 phải 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ỉ giải mã được 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 tệp độc lập.
Sử dụng MediaItem
Để phát hình ảnh trong danh sách phát, hãy tạo MediaItem
bằng URI hình ảnh rồi truyền URI đó đến trình phát. MediaItem
phải có imageDurationMs
để chỉ định thời lượng 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à tệp kết hợp ảnh tĩnh với video ngắn.
- Nếu thời lượng hình ảnh được xác định bằng
setImageDuration
, thì ảnh độ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 hình ảnh không được xác định, ảnh động sẽ được phát dưới dạng video.
Sử dụng ProgressiveMediaSource
Để có thêm các tuỳ chọn tuỳ chỉnh, bạn có thể tạo ProgressiveMediaSource
và truyền trực tiếp ProgressiveMediaSource
đó đến người chơi 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 sao cho phù hợp với nhu cầu của ứng dụng. Hãy xem trang Tuỳ chỉnh để tham khảo 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, ví dụ: Glide hoặc Coil.
Bạn cần thực hiện 3 bước để tích hợp các thư viện này vào quy trình phát:
- Xác định
MediaItem
bằng loại MIMEAPPLICATION_EXTERNALLY_LOADED_IMAGE
. - Cung cấp bộ giải mã hình ảnh để truy xuất
Bitmap
từ thư viện tải hình ảnh. - Cung cấp 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 từ 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 đườ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 sử dụng thư viện tải hình ảnh
Trình kết xuất hình ảnh cần có 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 hình ảnh:
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();
Tải trước hình ảnh bằng thư viện tải hình ảnh
Trong khi 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 thư viện tải hình ảnh bên ngoài, bạn phải chỉ định ExternalLoader
để kích hoạt tính năng 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 thể làm gì cả.
Ví dụ sau đây sử dụng Glide để đảm bảo 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) ) }
Java
ExternalLoader glidePreloader = request -> GlideFutures.submit( Glide.with(context) .asFile() .apply( diskCacheStrategyOf(DiskCacheStrategy.DATA) .priority(Priority.HIGH) .skipMemoryCache(true)) .load(request.uri));