Cómo recuperar metadatos

Durante la reproducción

Los metadatos del contenido multimedia se pueden recuperar durante la reproducción de varias maneras. La forma más sencilla es escuchar el evento Player.Listener#onMediaMetadataChanged, que proporcionará un objeto MediaMetadata para usar, que tiene campos como title y albumArtist. Como alternativa, llamar a Player#getMediaMetadata devuelve el mismo objeto.

Kotlin

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

Java

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

Si tu app necesita acceder a objetos Metadata.Entry específicos, debe escuchar Player.Listener#onMetadata (para los metadatos dinámicos que se entregan durante la reproducción). Como alternativa, si es necesario consultar metadatos estáticos, se puede acceder a ellos a través de TrackSelections#getFormat. Player#getMediaMetadata se completa con ambas fuentes.

Sin reproducción

Si no se necesita la reproducción, es más eficiente usar MetadataRetriever para extraer los metadatos, ya que evita tener que crear y preparar un reproductor.

Kotlin

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

Java

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

Fotos en movimiento

También es posible extraer metadatos de las Fotos en movimiento, incluidos los desplazamientos y las longitudes de las partes de imagen y video del archivo.

En el caso de las fotos en movimiento, el objeto TrackGroupArray obtenido con MetadataRetriever contiene un objeto TrackGroup con un solo objeto Format que incluye una entrada de metadatos 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);
    }
  }
}