Metadaten abrufen

Während der Wiedergabe

Die Metadaten der Media können während der Wiedergabe auf verschiedene Arten abgerufen werden. Am einfachsten ist es, auf das Player.Listener#onMediaMetadataChanged-Ereignis zu warten. Dadurch wird ein MediaMetadata-Objekt zur Verwendung bereitgestellt, das Felder wie title und albumArtist enthält. Alternativ wird durch Aufrufen von Player#getMediaMetadata dasselbe Objekt zurückgegeben.

Kotlin

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

Java

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

Wenn Ihre App Zugriff auf bestimmte Metadata.Entry-Objekte benötigt, sollte sie auf Player.Listener#onMetadata hören (für dynamische Metadaten, die während der Wiedergabe bereitgestellt werden). Alternativ kann auf statische Metadaten über die TrackSelections#getFormat zugegriffen werden. Player#getMediaMetadata wird aus beiden Quellen generiert.

Ohne Wiedergabe

Wenn keine Wiedergabe erforderlich ist, ist es effizienter, die Metadaten mit MetadataRetriever zu extrahieren, da kein Player erstellt und vorbereitet werden muss.

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

Fotos mit Bewegtbild

Es ist auch möglich, Metadaten von Fotos mit Bewegtbild zu extrahieren, einschließlich der Offsets und Längen der Bild- und Videoteile der Datei.

Bei Bewegtbildern enthält das mit MetadataRetriever abgerufene TrackGroupArray ein TrackGroup mit einem einzelnen Format, das einen MotionPhotoMetadata-Metadateneintrag einschließt.

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