During playback
The metadata of the media can be retrieved during playback in multiple ways. The
most straightforward is to listen for the
Player.Listener#onMediaMetadataChanged
event; this will provide a
MediaMetadata
object for use, which has fields such as title
and
albumArtist
. Alternatively, calling Player#getMediaMetadata
returns the same
object.
Kotlin
override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) { mediaMetadata.title?.let(::handleTitle) }
Java
@Override public void onMediaMetadataChanged(MediaMetadata mediaMetadata) { if (mediaMetadata.title != null) { handleTitle(mediaMetadata.title); } }
If your app needs access to specific Metadata.Entry
objects, then it
should listen to Player.Listener#onMetadata
(for dynamic metadata delivered
during playback). Alternatively, if there is a need to look at static metadata,
this can be accessed through the TrackSelections#getFormat
.
Player#getMediaMetadata
is populated from both of these sources.
Without playback
If playback is not needed, it is more efficient to use the
MetadataRetriever
to extract the metadata because it avoids having to
create and prepare a player.
Kotlin
val trackGroupsFuture = MetadataRetriever.retrieveMetadata(context, mediaItem) Futures.addCallback( trackGroupsFuture, object : FutureCallback<TrackGroupArray?> { override fun onSuccess(trackGroups: TrackGroupArray?) { if (trackGroups != null) handleMetadata(trackGroups) } override fun onFailure(t: Throwable) { handleFailure(t) } }, executor )
Java
ListenableFuture<TrackGroupArray> trackGroupsFuture = MetadataRetriever.retrieveMetadata(context, mediaItem); Futures.addCallback( trackGroupsFuture, new FutureCallback<TrackGroupArray>() { @Override public void onSuccess(TrackGroupArray trackGroups) { handleMetadata(trackGroups); } @Override public void onFailure(Throwable t) { handleFailure(t); } }, executor);
Motion photos
It is also possible to extract motion photo metadata, including the offsets and lengths of the image and video parts of the file.
For motion photos, the TrackGroupArray
obtained with the MetadataRetriever
contains a TrackGroup
with a single Format
enclosing a
MotionPhotoMetadata
metadata entry.
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); } } }