ExoPlayer รองรับรูปแบบรูปภาพต่อไปนี้ ดูวิธีผสานรวมกับไลบรารีภายนอกที่อาจรองรับชุดรูปแบบอื่นได้ที่ไลบรารีการโหลดรูปภาพ
| รูปแบบรูปภาพ | รองรับ | หมายเหตุ |
|---|---|---|
| BMP | ใช่ | |
| GIF | ไม่ | ไม่รองรับ Extractor |
| JPEG | ใช่ | |
| ภาพเคลื่อนไหว JPEG | ใช่ | รองรับรูปภาพนิ่งและวิดีโอ |
| JPEG Ultra HDR | ใช่ | กลับไปใช้ SDR ก่อน Android 14 หรือใน จอแสดงผลที่ไม่ใช่ HDR |
| PNG | ใช่ | |
| WebP | ใช่ | |
| HEIF/HEIC | ใช่ | |
| รูปภาพเคลื่อนไหว HEIC | เพียงบางส่วน | รองรับเฉพาะภาพนิ่ง* |
| AVIF (พื้นฐาน) | ใช่ | ถอดรหัสใน Android 14 ขึ้นไปเท่านั้น |
* คุณสามารถรับส่วนวิดีโอของรูปภาพเคลื่อนไหว HEIC ได้ด้วย MetadataRetriever และเล่นเป็นไฟล์แบบสแตนด์อโลน
การใช้ MediaItem
หากต้องการเล่นรูปภาพเป็นส่วนหนึ่งของเพลย์ลิสต์ ให้สร้าง MediaItem ด้วย URI ของรูปภาพ
แล้วส่งไปยังเพลเยอร์ MediaItem ต้องมี imageDurationMs เพื่อ
ระบุระยะเวลาที่ควรแสดงรูปภาพ
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();
รูปภาพเคลื่อนไหว
รูปภาพเคลื่อนไหวคือไฟล์ที่รวมภาพนิ่งกับวิดีโอสั้นๆ
- หากกำหนดระยะเวลาของรูปภาพด้วย
setImageDurationระบบจะแสดงรูปภาพเคลื่อนไหวเป็นรูปภาพนิ่งตามระยะเวลาที่ประกาศ - หากไม่ได้กำหนดระยะเวลาของรูปภาพ ระบบจะเล่นรูปภาพเคลื่อนไหวเป็นวิดีโอ
การใช้ ProgressiveMediaSource
หากต้องการตัวเลือกการปรับแต่งเพิ่มเติม คุณสามารถสร้าง ProgressiveMediaSource และ
ส่งไปยังเพลเยอร์โดยตรงแทน 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();
การปรับแต่งการเล่น
ExoPlayer มีหลายวิธีให้คุณปรับแต่งประสบการณ์การเล่นให้ตรงกับความต้องการของแอป ดูตัวอย่างได้ที่หน้าการปรับแต่ง
ไลบรารีการโหลดรูปภาพ
โดยมักจะจัดการรูปภาพโดยไลบรารีการโหลดรูปภาพภายนอก เช่น Glide หรือ Coil
การผสานรวมไลบรารีเหล่านี้เข้ากับไปป์ไลน์การเล่นต้องมี 3 ขั้นตอนดังนี้
- กำหนด
MediaItemที่มีประเภท MIME เป็นAPPLICATION_EXTERNALLY_LOADED_IMAGE - ระบุตัวถอดรหัสรูปภาพเพื่อดึง
Bitmapจากไลบรารีการโหลดรูปภาพ - ระบุเครื่องมือโหลดภายนอกเพื่อทริกเกอร์การแคชและการโหลดล่วงหน้า
MediaItem ที่มีประเภท MIME ของรูปภาพที่โหลดจากภายนอก
MediaItem ที่เพิ่มลงใน Player ต้องกำหนดประเภท MIME ของ APPLICATION_EXTERNALLY_LOADED_IMAGE อย่างชัดเจนเพื่อใช้เส้นทางโค้ดไลบรารีการโหลดรูปภาพ
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();
ตัวถอดรหัสรูปภาพโดยใช้ไลบรารีการโหลดรูปภาพ
เครื่องมือแสดงรูปภาพต้องมี ExternallyLoadedImageDecoder เพื่อดึงข้อมูล Bitmap จาก Uri ตัวถอดรหัสนี้สามารถระบุได้โดยการลบล้าง
DefaultRenderersFactory.getImageDecoderFactory
ตัวอย่างต่อไปนี้ใช้ Glide เพื่อโหลดรูปภาพ โดยจำกัดเอาต์พุตให้มีขนาดเท่ากับจอแสดงผลเพื่อหลีกเลี่ยงการสร้างออบเจ็กต์ 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();
การโหลดรูปภาพล่วงหน้าด้วยไลบรารีการโหลดรูปภาพ
ในระหว่างการเล่น เพลเยอร์จะขอโหลดรูปภาพถัดไปล่วงหน้าเมื่อโหลดรายการก่อนหน้า
ในเพลย์ลิสต์เสร็จสมบูรณ์แล้ว เมื่อใช้ไลบรารีการโหลดรูปภาพภายนอก
คุณต้องระบุ ExternalLoader เพื่อทริกเกอร์การโหลดล่วงหน้านี้ หากไม่สามารถ
โหลดล่วงหน้าได้หรือไม่จำเป็นต้องโหลดล่วงหน้า คุณก็ยังคงต้องระบุเครื่องมือโหลดนี้ แต่
ไม่ต้องดำเนินการใดๆ
ตัวอย่างต่อไปนี้ใช้ Glide เพื่อให้แน่ใจว่าระบบจะโหลดรูปภาพที่ขอไว้ล่วงหน้า ลงในดิสก์
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();