이미지

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()

자바

// 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()

자바

// 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단계를 따라야 합니다.

  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()

자바

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()

자바

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();