画像

ExoPlayer は次の画像形式をサポートしています。別の形式のセットをサポートする外部ライブラリと統合する方法については、画像読み込みライブラリをご覧ください。

イメージの形式 サポート対象 備考
BMP
GIF いいえ 抽出ツールはサポートされていません
JPEG
JPEG モーション フォト 静止画像と動画に対応
JPEG ウルトラ 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 の使用

カスタマイズ オプションを増やすには、MediaItem の代わりに ProgressiveMediaSource を作成してプレーヤーに直接渡すことができます。

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. APPLICATION_EXTERNALLY_LOADED_IMAGE MIME タイプで MediaItem を定義します。
  2. 画像読み込みライブラリから Bitmap を取得するための画像デコーダを提供します。
  3. キャッシュ保存とプリロードをトリガーする外部ローダーを提供します。

外部で読み込まれた画像の MIME タイプを含む MediaItem

Player に追加された MediaItem は、画像読み込みライブラリのコードパスを使用するために、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();

画像読み込みライブラリを使用する画像デコーダ

画像レンダラは、Uri から Bitmap を取得するために ExternallyLoadedImageDecoder を必要とします。このデコーダは、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();