이미지
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
ExoPlayer는 다음 이미지 형식을 지원합니다. 다른 형식을 지원할 수 있는 외부 라이브러리와 통합하는 방법은 이미지 로드 라이브러리를 참고하세요.
이미지 형식 |
지원됨 |
참고 |
BMP |
예 |
|
GIF |
아니요 |
추출기 지원 없음 |
JPEG |
예 |
|
JPEG 모션 포토 |
예 |
정지 이미지 및 동영상 지원 |
JPEG 울트라 HDR
|
예
|
Android 14 이전 또는 HDR이 아닌 디스플레이에서는 SDR로 대체됩니다. |
PNG |
예 |
|
WebP |
예 |
|
HEIF/HEIC |
예 |
|
HEIC 모션 사진 |
일부만 |
정지 이미지만 지원됨* |
AVIF (기준) |
예 |
Android 14 이상에서만 디코딩됨 |
* HEIC 모션 포토의 동영상 부분은 MetadataRetriever로 가져와 독립형 파일로 재생할 수 있습니다.
이미지를 재생목록의 일부로 재생하려면 이미지 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
로 정의된 경우 모션 사진이 선언된 기간 동안 스틸 이미지로 표시됩니다.
- 이미지 길이가 정의되지 않으면 모션 사진이 동영상으로 재생됩니다.
더 많은 맞춤설정 옵션을 사용하려면 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단계가 필요합니다.
APPLICATION_EXTERNALLY_LOADED_IMAGE
MIME 유형으로 MediaItem
를 정의합니다.
- 이미지 로드 라이브러리에서
Bitmap
를 검색하는 이미지 디코더를 제공합니다.
- 캐싱 및 미리 로드를 트리거하는 외부 로더를 제공합니다.
외부에서 로드된 이미지 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를 사용하여 이미지를 로드합니다.
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()
자바
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();
이미지 로드 라이브러리를 사용한 이미지 미리 로드
재생 중에 플레이어는 재생목록의 이전 항목이 완전히 로드되면 다음 이미지를 미리 로드하도록 요청합니다. 외부 이미지 로드 라이브러리를 사용하는 경우 이 미리 로드를 트리거할 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();
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-27(UTC)"],[],[],null,["# Images\n\nExoPlayer supports the following image formats. See\n[Image Loading Libraries](/media/media3/exoplayer/images#image-loading-libraries)\nfor how to integrate with external libraries that may provide support for a\ndifferent set of formats.\n\n| Image format | Supported | Notes |\n|-------------------|-----------|------------------------------------------------------------|\n| BMP | YES | |\n| GIF | NO | No Extractor support |\n| JPEG | YES | |\n| JPEG Motion Photo | YES | Still image and video supported |\n| JPEG Ultra HDR | YES | Falls back to SDR before Android 14 or on non-HDR displays |\n| PNG | YES | |\n| WebP | YES | |\n| HEIF/HEIC | YES | |\n| HEIC Motion Photo | Partially | Only still image supported\\* |\n| AVIF (baseline) | YES | Decoded on Android 14+ only |\n\n\\* The video part of HEIC motion photos can be obtained with\n[MetadataRetriever](/media/media3/exoplayer/retrieving-metadata#motion-photos)\nand played as a standalone file.\n\nUsing MediaItem\n---------------\n\nTo play an image as part of a playlist, create a `MediaItem` with the image URI\nand pass it to the player. The `MediaItem` must have a `imageDurationMs` to\nspecify for how long the image should be displayed. \n\n### Kotlin\n\n```kotlin\n// Create a player instance.\nval player = ExoPlayer.Builder(context).build()\n// Set the media item to be played with the desired duration.\nplayer.setMediaItem(\n MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build())\n// Prepare the player.\nplayer.prepare()\n```\n\n### Java\n\n```java\n// Create a player instance.\nExoPlayer player = new ExoPlayer.Builder(context).build();\n// Set the media item to be played with the desired duration.\nplayer.setMediaItem(\n new MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build());\n// Prepare the player.\nplayer.prepare();\n```\n\n\u003cbr /\u003e\n\n### Motion Photos\n\nMotion photos are files combining a still image with a short video.\n\n- If the image duration is defined with `setImageDuration`, the motion photo is displayed for the declared duration as a still image.\n- If the image duration is undefined, the motion photo is played as a video.\n\nUsing ProgressiveMediaSource\n----------------------------\n\nFor more customization options, you can create a `ProgressiveMediaSource` and\npass it directly to the player instead of a `MediaItem`. \n\n### Kotlin\n\n```kotlin\n// Create a data source factory.\nval dataSourceFactory = DefaultHttpDataSource.Factory()\n// Create a media item with the image URI and the desired duration.\nval mediaItem =\n MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build()\n// Create a progressive media source for this media item.\nval mediaSource =\n ProgressiveMediaSource.Factory(dataSourceFactory)\n .createMediaSource(mediaItem)\n// Create a player instance.\nval player = ExoPlayer.Builder(context).build()\n// Set the media source to be played.\nplayer.setMediaSource(mediaSource)\n// Prepare the player.\nplayer.prepare()\n```\n\n### Java\n\n```java\n// Create a data source factory.\nDataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();\n// Create a media item with the image URI and the desired duration.\nMediaItem mediaItem =\n new MediaItem.Builder().setUri(imageUri).setImageDurationMs(2000).build();\n// Create a progressive media source for this media item.\nMediaSource mediaSource =\n new ProgressiveMediaSource.Factory(dataSourceFactory)\n .createMediaSource(mediaItem);\n// Create a player instance.\nExoPlayer player = new ExoPlayer.Builder(context).build();\n// Set the media source to be played.\nplayer.setMediaSource(mediaSource);\n// Prepare the player.\nplayer.prepare();\n```\n\n\u003cbr /\u003e\n\nCustomizing playback\n--------------------\n\nExoPlayer provides multiple ways for you to tailor playback experience to your\napp's needs. See the [Customization page](/guide/topics/media/exoplayer/customization) for examples.\n\nImage Loading Libraries\n-----------------------\n\nImages are often managed by external image loading libraries, for example\n[Glide](https://bumptech.github.io/glide/) or\n[Coil](https://coil-kt.github.io/coil/).\n\nIntegrating these libraries into the playback pipeline requires 3 steps:\n\n1. Define a `MediaItem` with `APPLICATION_EXTERNALLY_LOADED_IMAGE` MIME type.\n2. Provide an image decoder to retrieve a `Bitmap` from the image loading library.\n3. Provide an external loader to trigger caching and preloading.\n\n### MediaItem with externally loaded image MIME type\n\nThe `MediaItem` added to the `Player` must define the\n`APPLICATION_EXTERNALLY_LOADED_IMAGE` MIME type explicitly to use the image\nloading library code paths: \n\n### Kotlin\n\n```kotlin\nval mediaItem =\n MediaItem.Builder()\n .setUri(imageUri)\n .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE)\n .build()\n```\n\n### Java\n\n```java\nMediaItem mediaItem =\n new MediaItem.Builder()\n .setUri(imageUri)\n .setMimeType(MimeTypes.APPLICATION_EXTERNALLY_LOADED_IMAGE)\n .build();\n```\n\n\u003cbr /\u003e\n\n### Image decoder using an image loading library\n\nThe image renderer needs an `ExternallyLoadedImageDecoder` to retrieve the\n`Bitmap` from the `Uri`. This decoder can be provided by overriding\n`DefaultRenderersFactory.getImageDecoderFactory`.\n\nThe following example uses Glide to load an image: \n\n### Kotlin\n\n```kotlin\nval glideImageDecoderFactory: ImageDecoder.Factory =\n ExternallyLoadedImageDecoder.Factory { request: ExternalImageRequest -\u003e\n GlideFutures.submit(Glide.with(context).asBitmap().load(request.uri))\n }\nval player: Player =\n ExoPlayer.Builder(context)\n .setRenderersFactory(\n object : DefaultRenderersFactory(context) {\n override fun getImageDecoderFactory(): ImageDecoder.Factory {\n return glideImageDecoderFactory\n }\n }\n )\n .build()\n```\n\n### Java\n\n```java\nImageDecoder.Factory glideImageDecoderFactory =\n new ExternallyLoadedImageDecoder.Factory(\n request -\u003e GlideFutures.submit(\n Glide.with(context).asBitmap().load(request.uri)));\nPlayer player =\n new ExoPlayer.Builder(context)\n .setRenderersFactory(\n new DefaultRenderersFactory(context) {\n @Override\n protected ImageDecoder.Factory getImageDecoderFactory() {\n return glideImageDecoderFactory;\n }\n })\n .build();\n```\n\n\u003cbr /\u003e\n\n### Image preloading with an image loading library\n\nDuring playback, the player requests to preload the next image once the previous\nitem in the playlist has fully loaded. When using an external image loading\nlibrary, you must specify an `ExternalLoader` to trigger this preloading. If no\npreloading is possible or required, this loader still needs to be provided, but\ncan do nothing.\n\nThe following example uses Glide to ensure that the requested image is preloaded\nto disk: \n\n### Kotlin\n\n```kotlin\nval glidePreloader = ExternalLoader { request: LoadRequest -\u003e\n GlideFutures.submit(\n Glide.with(context)\n .asFile()\n .apply(\n RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.DATA)\n .priority(Priority.HIGH)\n .skipMemoryCache(true)\n )\n .load(request.uri)\n )\n}\nval player =\n ExoPlayer.Builder(context)\n .setMediaSourceFactory(DefaultMediaSourceFactory(context)\n .setExternalImageLoader(glidePreloader))\n .build()\n```\n\n### Java\n\n```java\nExternalLoader glidePreloader =\n request -\u003e\n GlideFutures.submit(\n Glide.with(context)\n .asFile()\n .apply(\n diskCacheStrategyOf(DiskCacheStrategy.DATA)\n .priority(Priority.HIGH)\n .skipMemoryCache(true))\n .load(request.uri));\nPlayer player =\n new ExoPlayer.Builder(context)\n .setMediaSourceFactory(new DefaultMediaSourceFactory(context)\n .setExternalImageLoader(glidePreloader))\n .build();\n```\n\n\u003cbr /\u003e"]]