메타데이터 가져오기
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
재생 중
미디어의 메타데이터는 재생하는 동안 여러 가지 방법으로 가져올 수 있습니다. 이
가장 간단한 방법은
Player.Listener#onMediaMetadataChanged
이벤트, 이렇게 하면
사용할 MediaMetadata
객체. 여기에는 title
및
albumArtist
또는 Player#getMediaMetadata
를 호출하면
객체를 지정합니다.
Kotlin
override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) {
mediaMetadata.title?.let(::handleTitle)
}
자바
@Override
public void onMediaMetadataChanged(MediaMetadata mediaMetadata) {
if (mediaMetadata.title != null) {
handleTitle(mediaMetadata.title);
}
}
앱이 특정 Metadata.Entry
객체에 액세스해야 하는 경우
전달된 동적 메타데이터를 위해 Player.Listener#onMetadata
를 수신 대기해야 합니다.
)을 설정할 수 있습니다. 또는 정적 메타데이터를 살펴봐야 하는 경우
TrackSelections#getFormat
를 통해 액세스할 수 있습니다.
Player#getMediaMetadata
는 이러한 두 소스 모두에서 채워집니다.
재생하지 않음
재생이 필요하지 않은 경우
MetadataRetriever
:
준비시키는 것이 좋습니다.
Kotlin
suspend fun retrievingMetadataRetrieveMetadataWithoutPlayback(
context: Context,
mediaItem: MediaItem,
) {
try {
MetadataRetriever.Builder(context, mediaItem).build().use { metadataRetriever ->
val trackGroups = metadataRetriever.retrieveTrackGroups().await()
val timeline = metadataRetriever.retrieveTimeline().await()
val durationUs = metadataRetriever.retrieveDurationUs().await()
handleMetadata(trackGroups, timeline, durationUs)
}
} catch (e: IOException) {
handleFailure(e)
}
}
자바
try (MetadataRetriever metadataRetriever =
new MetadataRetriever.Builder(context, mediaItem).build()) {
ListenableFuture<TrackGroupArray> trackGroupsFuture = metadataRetriever.retrieveTrackGroups();
ListenableFuture<Timeline> timelineFuture = metadataRetriever.retrieveTimeline();
ListenableFuture<Long> durationUsFuture = metadataRetriever.retrieveDurationUs();
ListenableFuture<List<Object>> allFutures =
Futures.allAsList(trackGroupsFuture, timelineFuture, durationUsFuture);
Futures.addCallback(
allFutures,
new FutureCallback<List<Object>>() {
@Override
public void onSuccess(List<Object> result) {
handleMetadata(
Futures.getUnchecked(trackGroupsFuture),
Futures.getUnchecked(timelineFuture),
Futures.getUnchecked(durationUsFuture));
}
@Override
public void onFailure(Throwable t) {
handleFailure(t);
}
},
executor);
}
모션 사진
또한 오프셋과 동영상 분류를 포함한 모션 사진 메타데이터를 추출할 수 있습니다.
파일의 이미지 부분과 동영상 부분의 길이입니다.
모션 사진의 경우 MetadataRetriever
로 얻은 TrackGroupArray
다음을 포함하는 단일 Format
가 있는 TrackGroup
를 포함합니다.
MotionPhotoMetadata
메타데이터 항목.
Kotlin
0.until(trackGroups.length)
.asSequence()
.mapNotNull { trackGroups[it].getFormat(0).metadata }
.filter { metadata -> metadata.length() == 1 }
.map { metadata -> metadata[0] }
.filterIsInstance<MotionPhotoMetadata>()
.forEach(::handleMotionPhotoMetadata)
Java
for (int i = 0; i < trackGroups.length; i++) {
TrackGroup trackGroup = trackGroups.get(i);
Metadata metadata = trackGroup.getFormat(0).metadata;
if (metadata != null && metadata.length() == 1) {
Metadata.Entry metadataEntry = metadata.get(0);
if (metadataEntry instanceof MotionPhotoMetadata) {
MotionPhotoMetadata motionPhotoMetadata = (MotionPhotoMetadata) metadataEntry;
handleMotionPhotoMetadata(motionPhotoMetadata);
}
}
}
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-08-01(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-08-01(UTC)"],[],[],null,["# Retrieving metadata\n\nDuring playback\n---------------\n\nThe metadata of the media can be retrieved during playback in multiple ways. The\nmost straightforward is to listen for the\n`Player.Listener#onMediaMetadataChanged` event; this will provide a\n[`MediaMetadata`](/reference/androidx/media3/common/MediaMetadata) object for use, which has fields such as `title` and\n`albumArtist`. Alternatively, calling `Player#getMediaMetadata` returns the same\nobject. \n\n### Kotlin\n\n```kotlin\noverride fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) {\n mediaMetadata.title?.let(::handleTitle)\n}\n```\n\n### Java\n\n```java\n@Override\npublic void onMediaMetadataChanged(MediaMetadata mediaMetadata) {\n if (mediaMetadata.title != null) {\n handleTitle(mediaMetadata.title);\n }\n}\n```\n\n\u003cbr /\u003e\n\nIf your app needs access to specific [`Metadata.Entry`](/reference/androidx/media3/common/Metadata.Entry) objects, then it\nshould listen to `Player.Listener#onMetadata` (for dynamic metadata delivered\nduring playback). Alternatively, if there is a need to look at static metadata,\nthis can be accessed through the `TrackSelections#getFormat`.\n`Player#getMediaMetadata` is populated from both of these sources.\n\nWithout playback\n----------------\n\nIf playback is not needed, it is more efficient to use the\n[`MetadataRetriever`](/reference/androidx/media3/exoplayer/MetadataRetriever) to extract the metadata because it avoids having to\ncreate and prepare a player. \n\n### Kotlin\n\n```kotlin\nsuspend fun retrievingMetadataRetrieveMetadataWithoutPlayback(\n context: Context,\n mediaItem: MediaItem,\n) {\n try {\n MetadataRetriever.Builder(context, mediaItem).build().use { metadataRetriever -\u003e\n val trackGroups = metadataRetriever.retrieveTrackGroups().await()\n val timeline = metadataRetriever.retrieveTimeline().await()\n val durationUs = metadataRetriever.retrieveDurationUs().await()\n handleMetadata(trackGroups, timeline, durationUs)\n }\n } catch (e: IOException) {\n handleFailure(e)\n }\n}\n```\n\n### Java\n\n```java\ntry (MetadataRetriever metadataRetriever =\n new MetadataRetriever.Builder(context, mediaItem).build()) {\n ListenableFuture\u003cTrackGroupArray\u003e trackGroupsFuture = metadataRetriever.retrieveTrackGroups();\n ListenableFuture\u003cTimeline\u003e timelineFuture = metadataRetriever.retrieveTimeline();\n ListenableFuture\u003cLong\u003e durationUsFuture = metadataRetriever.retrieveDurationUs();\n ListenableFuture\u003cList\u003cObject\u003e\u003e allFutures =\n Futures.allAsList(trackGroupsFuture, timelineFuture, durationUsFuture);\n Futures.addCallback(\n allFutures,\n new FutureCallback\u003cList\u003cObject\u003e\u003e() {\n @Override\n public void onSuccess(List\u003cObject\u003e result) {\n handleMetadata(\n Futures.getUnchecked(trackGroupsFuture),\n Futures.getUnchecked(timelineFuture),\n Futures.getUnchecked(durationUsFuture));\n }\n\n @Override\n public void onFailure(Throwable t) {\n handleFailure(t);\n }\n },\n executor);\n}\n```\n\n\u003cbr /\u003e\n\nMotion photos\n-------------\n\n| **Note:** For motion photo **playback** , see [Media Items](/media/media3/exoplayer/images#motion-photos) and for motion photo **format support** , see [Supported formats](/media/media3/exoplayer/supported-formats#images).\n\nIt is also possible to extract motion photo metadata, including the offsets and\nlengths of the image and video parts of the file.\n\nFor motion photos, the `TrackGroupArray` obtained with the `MetadataRetriever`\ncontains a `TrackGroup` with a single `Format` enclosing a\n[`MotionPhotoMetadata`](/reference/androidx/media3/extractor/metadata/mp4/MotionPhotoMetadata) metadata entry. \n\n### Kotlin\n\n```kotlin\n0.until(trackGroups.length)\n .asSequence()\n .mapNotNull { trackGroups[it].getFormat(0).metadata }\n .filter { metadata -\u003e metadata.length() == 1 }\n .map { metadata -\u003e metadata[0] }\n .filterIsInstance\u003cMotionPhotoMetadata\u003e()\n .forEach(::handleMotionPhotoMetadata)\n```\n\n### Java\n\n```java\nfor (int i = 0; i \u003c trackGroups.length; i++) {\n TrackGroup trackGroup = trackGroups.get(i);\n Metadata metadata = trackGroup.getFormat(0).metadata;\n if (metadata != null && metadata.length() == 1) {\n Metadata.Entry metadataEntry = metadata.get(0);\n if (metadataEntry instanceof MotionPhotoMetadata) {\n MotionPhotoMetadata motionPhotoMetadata = (MotionPhotoMetadata) metadataEntry;\n handleMotionPhotoMetadata(motionPhotoMetadata);\n }\n }\n}\n```\n\n\u003cbr /\u003e"]]