圖片

ExoPlayer 支援下列圖片格式。如要與可能支援不同格式集的外部程式庫整合,請參閱「圖片載入程式庫」。

圖片格式 支援 附註
BMP
GIF 不支援擷取器
JPEG
JPEG 動態相片 支援靜態圖片和影片
JPEG Ultra HDR 在 Android 14 之前的版本或非 HDR 螢幕上,會改用 SDR
PNG
WebP
HEIF/HEIC
HEIC 動態相片 不盡然 僅支援靜態圖片*
AVIF (基準) 僅適用於 Android 14 以上版本

* HEIC 動態相片的影片部分可透過 MetadataRetriever 取得,並以獨立檔案播放。

使用 MediaItem

如要將圖片加入播放清單,請使用圖片 URI 建立 MediaItem,然後傳送至播放器。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 提供多種方式,讓您根據應用程式需求調整播放體驗。如需範例,請參閱自訂頁面

圖片載入程式庫

圖片通常由外部圖片載入程式庫管理,例如 GlideCoil

如要將這些程式庫整合至播放管道,需要完成 3 個步驟:

  1. 定義 MediaItem,並使用 APPLICATION_EXTERNALLY_LOADED_IMAGE MIME 類型。
  2. 提供圖片解碼器,從圖片載入程式庫擷取 Bitmap
  3. 提供外部載入器,觸發快取和預先載入。

具有外部載入圖片 MIME 類型的 MediaItem

加入 PlayerMediaItem 必須明確定義 APPLICATION_EXTERNALLY_LOADED_IMAGE MIME 類型,才能使用圖片載入程式庫程式碼路徑:

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,才能從 Uri 擷取 Bitmap。您可以覆寫 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();