Mengambil metadata

MetadataRetriever mengambil informasi (seperti durasi, resolusi video, codec, trek yang tersedia, dan kecepatan sampling) dari MediaItem tanpa pemutaran.

Kasus penggunaan umum mencakup:

  • Mengambil metadata foto bergerak: termasuk offset dan panjang bagian gambar dan video dari file.
  • Membangun library media: Mengisi MediaLibraryService dengan detail MediaItem yang kaya (seperti durasi dan judul) untuk menyajikan katalog media lengkap kepada klien seperti Android Auto.
  • Detail UI pengambilan data awal: Mengambil informasi seperti resolusi atau durasi video untuk menyiapkan UI sebelum pemutaran dimulai.
  • Memvalidasi file media: Memeriksa apakah file berisi trek audio atau video yang diperlukan atau metadata tertentu sebelum memprosesnya.

Ringkasan

Penggunaan MetadataRetriever adalah proses dua langkah:

  1. Bangun retriever: Buat instance menggunakan MetadataRetriever.Builder. Teruskan Context dan MediaItem yang ingin Anda periksa ke builder. Untuk kasus penggunaan lanjutan, seperti jaringan atau penyimpanan data dalam cache kustom, Anda juga dapat menyediakan MediaSource.Factory kustom.
  2. Mengambil metadata: Panggil metode seperti retrieveDurationUs(), retrieveTimeline(), atau retrieveTrackGroups() untuk mengambil informasi yang diperlukan. Metode ini bersifat asinkron, menampilkan ListenableFuture sehingga operasi jaringan atau I/O tidak memblokir thread utama.

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