Mengambil metadata

Selama pemutaran

Metadata media dapat diambil selama pemutaran dengan berbagai cara. Cara paling mudah adalah memproses peristiwa Player.Listener#onMediaMetadataChanged; hal ini akan memberikan objek MediaMetadata untuk digunakan, yang memiliki kolom seperti title dan albumArtist. Atau, memanggil Player#getMediaMetadata akan menampilkan objek yang sama.

Kotlin

override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) {
  mediaMetadata.title?.let(::handleTitle)
}

Java

@Override
public void onMediaMetadataChanged(MediaMetadata mediaMetadata) {
  if (mediaMetadata.title != null) {
    handleTitle(mediaMetadata.title);
  }
}

Jika aplikasi Anda memerlukan akses ke objek Metadata.Entry tertentu, aplikasi tersebut harus memproses Player.Listener#onMetadata (untuk metadata dinamis yang dikirimkan selama pemutaran). Atau, jika ada kebutuhan untuk melihat metadata statis, metadata ini dapat diakses melalui TrackSelections#getFormat. Player#getMediaMetadata diisi dari kedua sumber ini.

Tanpa pemutaran

Jika pemutaran tidak diperlukan, akan lebih efisien menggunakan MetadataRetriever untuk mengekstrak metadata karena tidak perlu membuat dan menyiapkan pemutar.

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) {
    handleFailure(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<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);
          }
        },
        directExecutor());
  }
}

Foto motion

Metadata foto motion juga dapat diekstrak, termasuk offset dan panjang bagian gambar dan video dari file.

Untuk foto bergerak, TrackGroupArray yang diperoleh dengan MetadataRetriever berisi TrackGroup dengan satu Format yang melampirkan entri metadata 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);
    }
  }
}