1*30877f79SAndroid Build Coastguard Worker--- 2*30877f79SAndroid Build Coastguard Workertitle: Retrieving metadata 3*30877f79SAndroid Build Coastguard Worker--- 4*30877f79SAndroid Build Coastguard Worker 5*30877f79SAndroid Build Coastguard Worker## During playback ## 6*30877f79SAndroid Build Coastguard Worker 7*30877f79SAndroid Build Coastguard WorkerThe metadata of the media can be retrieved during playback in multiple ways. The 8*30877f79SAndroid Build Coastguard Workermost straightforward is to listen for the 9*30877f79SAndroid Build Coastguard Worker`Player.Listener#onMediaMetadataChanged` event; this will provide a 10*30877f79SAndroid Build Coastguard Worker[`MediaMetadata`][] object for use, which has fields such as `title` and 11*30877f79SAndroid Build Coastguard Worker`albumArtist`. Alternatively, calling `Player#getMediaMetadata` returns the same 12*30877f79SAndroid Build Coastguard Workerobject. 13*30877f79SAndroid Build Coastguard Worker 14*30877f79SAndroid Build Coastguard Worker~~~ 15*30877f79SAndroid Build Coastguard Workerpublic void onMediaMetadataChanged(MediaMetadata mediaMetadata) { 16*30877f79SAndroid Build Coastguard Worker if (mediaMetadata.title != null) { 17*30877f79SAndroid Build Coastguard Worker handleTitle(mediaMetadata.title); 18*30877f79SAndroid Build Coastguard Worker } 19*30877f79SAndroid Build Coastguard Worker} 20*30877f79SAndroid Build Coastguard Worker 21*30877f79SAndroid Build Coastguard Worker~~~ 22*30877f79SAndroid Build Coastguard Worker{: .language-java} 23*30877f79SAndroid Build Coastguard Worker 24*30877f79SAndroid Build Coastguard WorkerIf an application needs access to specific [`Metadata.Entry`][] objects, then it 25*30877f79SAndroid Build Coastguard Workershould add a `MetadataOutput` (for dynamic metadata delivered during 26*30877f79SAndroid Build Coastguard Workerplayback) to the player. Alternatively, if there is a need to look at static 27*30877f79SAndroid Build Coastguard Workermetadata, this can be accessed through the `TrackSelections#getFormat`. Both of 28*30877f79SAndroid Build Coastguard Workerthese options are used to populate the `Player#getMediaMetadata`. 29*30877f79SAndroid Build Coastguard Worker 30*30877f79SAndroid Build Coastguard Worker## Without playback ## 31*30877f79SAndroid Build Coastguard Worker 32*30877f79SAndroid Build Coastguard WorkerIf playback is not needed, it is more efficient to use the 33*30877f79SAndroid Build Coastguard Worker[`MetadataRetriever`][] to extract the metadata because it avoids having to 34*30877f79SAndroid Build Coastguard Workercreate and prepare a player. 35*30877f79SAndroid Build Coastguard Worker 36*30877f79SAndroid Build Coastguard Worker~~~ 37*30877f79SAndroid Build Coastguard WorkerListenableFuture<TrackGroupArray> trackGroupsFuture = 38*30877f79SAndroid Build Coastguard Worker MetadataRetriever.retrieveMetadata(context, mediaItem); 39*30877f79SAndroid Build Coastguard WorkerFutures.addCallback( 40*30877f79SAndroid Build Coastguard Worker trackGroupsFuture, 41*30877f79SAndroid Build Coastguard Worker new FutureCallback<TrackGroupArray>() { 42*30877f79SAndroid Build Coastguard Worker @Override 43*30877f79SAndroid Build Coastguard Worker public void onSuccess(TrackGroupArray trackGroups) { 44*30877f79SAndroid Build Coastguard Worker handleMetadata(trackGroups); 45*30877f79SAndroid Build Coastguard Worker } 46*30877f79SAndroid Build Coastguard Worker 47*30877f79SAndroid Build Coastguard Worker @Override 48*30877f79SAndroid Build Coastguard Worker public void onFailure(Throwable t) { 49*30877f79SAndroid Build Coastguard Worker handleFailure(t); 50*30877f79SAndroid Build Coastguard Worker } 51*30877f79SAndroid Build Coastguard Worker }, 52*30877f79SAndroid Build Coastguard Worker executor); 53*30877f79SAndroid Build Coastguard Worker~~~ 54*30877f79SAndroid Build Coastguard Worker{: .language-java} 55*30877f79SAndroid Build Coastguard Worker 56*30877f79SAndroid Build Coastguard Worker## Motion photos ## 57*30877f79SAndroid Build Coastguard Worker 58*30877f79SAndroid Build Coastguard WorkerIt is also possible to extract the metadata of a motion photo, containing the 59*30877f79SAndroid Build Coastguard Workerimage and video offset and length for example. The supported formats are: 60*30877f79SAndroid Build Coastguard Worker 61*30877f79SAndroid Build Coastguard Worker* JPEG motion photos recorded by Google Pixel and Samsung camera apps. This 62*30877f79SAndroid Build Coastguard Worker format is playable by ExoPlayer and the associated metadata can therefore be 63*30877f79SAndroid Build Coastguard Worker retrieved with a player or using the `MetadataRetriever`. 64*30877f79SAndroid Build Coastguard Worker* HEIC motion photos recorded by Google Pixel and Samsung camera apps. This 65*30877f79SAndroid Build Coastguard Worker format is currently not playable by ExoPlayer and the associated metadata 66*30877f79SAndroid Build Coastguard Worker should therefore be retrieved using the `MetadataRetriever`. 67*30877f79SAndroid Build Coastguard Worker 68*30877f79SAndroid Build Coastguard WorkerFor motion photos, the `TrackGroupArray` obtained with the `MetadataRetriever` 69*30877f79SAndroid Build Coastguard Workercontains a `TrackGroup` with a single `Format` enclosing a 70*30877f79SAndroid Build Coastguard Worker[`MotionPhotoMetadata`][] metadata entry. 71*30877f79SAndroid Build Coastguard Worker 72*30877f79SAndroid Build Coastguard Worker~~~ 73*30877f79SAndroid Build Coastguard Workerfor (int i = 0; i < trackGroups.length; i++) { 74*30877f79SAndroid Build Coastguard Worker TrackGroup trackGroup = trackGroups.get(i); 75*30877f79SAndroid Build Coastguard Worker Metadata metadata = trackGroup.getFormat(0).metadata; 76*30877f79SAndroid Build Coastguard Worker if (metadata != null && metadata.length() == 1) { 77*30877f79SAndroid Build Coastguard Worker Metadata.Entry metadataEntry = metadata.get(0); 78*30877f79SAndroid Build Coastguard Worker if (metadataEntry instanceof MotionPhotoMetadata) { 79*30877f79SAndroid Build Coastguard Worker MotionPhotoMetadata motionPhotoMetadata = (MotionPhotoMetadata) metadataEntry; 80*30877f79SAndroid Build Coastguard Worker handleMotionPhotoMetadata(motionPhotoMetadata); 81*30877f79SAndroid Build Coastguard Worker } 82*30877f79SAndroid Build Coastguard Worker } 83*30877f79SAndroid Build Coastguard Worker} 84*30877f79SAndroid Build Coastguard Worker~~~ 85*30877f79SAndroid Build Coastguard Worker{: .language-java} 86*30877f79SAndroid Build Coastguard Worker 87*30877f79SAndroid Build Coastguard Worker[`MediaMetadata`]: {{ site.exo_sdk }}/MediaMetadata.html 88*30877f79SAndroid Build Coastguard Worker[`Metadata.Entry`]: {{ site.exo_sdk }}/metadata/Metadata.Entry.html 89*30877f79SAndroid Build Coastguard Worker[`MetadataRetriever`]: {{ site.exo_sdk }}/MetadataRetriever.html 90*30877f79SAndroid Build Coastguard Worker[`MotionPhotoMetadata`]: {{ site.exo_sdk }}/metadata/mp4/MotionPhotoMetadata.html 91