메타데이터 검색

MetadataRetriever은 재생 없이 MediaItem에서 정보 (예: 재생 시간, 동영상 해상도, 코덱, 사용 가능한 트랙, 샘플링 레이트)를 가져옵니다.

일반적인 사용 사례는 다음과 같습니다.

  • 모션 사진 메타데이터 가져오기: 파일의 이미지 및 동영상 부분의 오프셋과 길이를 포함합니다.
  • 미디어 라이브러리 빌드: 풍부한 MediaItem 세부정보 (예: 재생 시간 및 제목)로 MediaLibraryService를 채워 Android Auto와 같은 클라이언트에 전체 미디어 카탈로그를 제공합니다.
  • 미리 가져오기 UI 세부정보: 재생이 시작되기 전에 UI를 준비하기 위해 동영상 해상도나 길이와 같은 정보를 가져옵니다.
  • 미디어 파일 검증: 파일을 처리하기 전에 필수 오디오 또는 동영상 트랙이나 특정 메타데이터가 포함되어 있는지 확인합니다.

개요

MetadataRetriever 사용은 다음 두 단계로 이루어집니다.

  1. 리트리버 빌드: MetadataRetriever.Builder를 사용하여 인스턴스를 만듭니다. 검사하려는 ContextMediaItem을 빌더에 전달합니다. 맞춤 네트워킹 또는 캐싱과 같은 고급 사용 사례의 경우 맞춤 MediaSource.Factory를 제공할 수도 있습니다.
  2. 메타데이터 가져오기: retrieveDurationUs(), retrieveTimeline() 또는 retrieveTrackGroups()과 같은 메서드를 호출하여 필요한 정보를 가져옵니다. 이러한 메서드는 비동기적이며 네트워크 또는 I/O 작업이 기본 스레드를 차단하지 않도록 ListenableFuture를 반환합니다.

Kotlin

suspend fun retrieveMetadata(context: Context, mediaItem: MediaItem) {
    try {
        // 1. Build the retriever.
        // `MetadataRetriever` implements `AutoCloseable`, so wrap it in
        // a Kotlin `.use` block, which calls `close()` automatically.
        MetadataRetriever.Builder(context, mediaItem).build().use { retriever ->
            // 2. Retrieve metadata asynchronously.
            val trackGroups = retriever.retrieveTrackGroups().await()
            val timeline = retriever.retrieveTimeline().await()
            val durationUs = retriever.retrieveDurationUs().await()
            handleMetadata(trackGroups, timeline, durationUs)
        }
    } catch (e: Exception) {
        throw RuntimeException(e)
    }
}

Java

public void retrieveMetadata(Context context, MediaItem mediaItem) {
    // 1. Build the retriever.
    // `MetadataRetriever` implements `AutoCloseable`, so use try-with-resources
    // so that the resources are automatically released.
    try (MetadataRetriever retriever = new MetadataRetriever.Builder(context, mediaItem).build()) {
        // 2. Retrieve metadata asynchronously.
        ListenableFuture<TrackGroupArray> trackGroupsFuture = retriever.retrieveTrackGroups();
        ListenableFuture<Timeline> timelineFuture = retriever.retrieveTimeline();
        ListenableFuture<Long> durationUsFuture = retriever.retrieveDurationUs();

        ListenableFuture<List<Object>> allFutures = Futures.allAsList(trackGroupsFuture, timelineFuture, durationUsFuture);
        Futures.addCallback(allFutures, new FutureCallback<>() {
            @Override
            public void onSuccess(List<Object> result) {
                handleMetadata(
                        Futures.getUnchecked(trackGroupsFuture),
                        Futures.getUnchecked(timelineFuture),
                        Futures.getUnchecked(durationUsFuture)
                );
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                handleFailure(t);
            }
        }, MoreExecutors.directExecutor());
    }
}