onMediaBrowserChanged not called when setting MediaMetadata first
Version
Media3 1.4.1
Summary
We have a stream from a radio station that supplies data about the currently playing track. The standard way to observe or receive updates is through the onMediaMetadataChanged callback.
This approach works well, as I can see the title being updated. However, if I set some metadata on the MediaItem initially, the callback is never triggered.
I am wondering if this behavior is by design and, if so, what the purpose is, or if it might be a bug.
Devices that reproduce the issue
Pixel 7 Android 15
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
No, because you need to set MediaMetaData to prevent an exception.
java.lang.IllegalArgumentException: mediaMetadata must specify isBrowsable. So you will never see MetaData changes coming through.
Reproduction steps
1: Play a media item without setting the MetaData:
val mediaItemWithOutMetaData = MediaItem.Builder()
.setMediaId("some_id")
.setMimeType(MimeTypes.AUDIO_UNKNOWN)
.setUri("https://icecast-qmusicnl-cdp.triple-it.nl/Qmusic_nl_live_high.aac")
.build()
2: Listen to onMediaMetadataChanged
player?.addListener(object : Player.Listener {
override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) {
super.onMediaMetadataChanged(mediaMetadata)
Log.d("[DEBUG]", "onMediaMetadataChanged: ${mediaMetadata.title}")
}
})
3: Observe that the mediaMetadata.title is coming through.
4: Now play the mediaItem with Metadata
val mediaItemWithMetaData = MediaItem.Builder()
.setMediaId("some_id")
.setMimeType(MimeTypes.AUDIO_UNKNOWN)
.setMediaMetadata(MediaMetadata.Builder().setTitle("a title").build())
.setUri("https://icecast-qmusicnl-cdp.triple-it.nl/Qmusic_nl_live_high.aac")
.build()
5: Observe that the title is not coming through.
Expected result
onMediaMetadataChanged is called, with or without setting MediaMetaData on the MediaItem we are playing.__
Actual result
onMediaMetadataChanged is only triggered if we are not setting MediaMetaData first.
Media
https://icecast-qmusicnl-cdp.triple-it.nl/Qmusic_nl_live_high.aac
Bug Report
- [ ] You will email the zip file produced by
adb bugreportto [email protected] after filing this issue.
Thanks for your question!
Yeah, I think this behaviour is by design.
The JavaDoc of Player.getMetadata and Player.Listener.onMediuaMetadataChanged() together explains it. I wonder whether we should mention this on the listener more clearly. Because the important part is documented on the getter.
The listener is only called when the metadata changes. When you don't have metadata in the MediaItem, then the stream that contains ICY or other metadata sets the title, the metadata changes and the listener is called.
If you have metdata set, then getMediaMetadata() documents that the value in the item takes precedence. So the in-band metadata doesn't change the metdata obect returned by the getter and hence it won't call the listener.
This means the value that you set in the media item is kept. Even if other changes in the metadata object would happen, and the listener is called the title wouldn't be overridden I think.
/**
* Returns the current combined {@link MediaMetadata}, or {@link MediaMetadata#EMPTY} if not
* supported.
*
* <p>This {@link MediaMetadata} is a combination of the {@link MediaItem#mediaMetadata MediaItem
* metadata}, the static metadata in the media's {@link Format#metadata Format}, and any timed
* metadata that has been parsed from the media and output via {@link
* Listener#onMetadata(Metadata)}. If a field is populated in the {@link MediaItem#mediaMetadata},
* it will be prioritised above the same field coming from static or timed metadata.
*
* <p>This method must only be called if {@link #COMMAND_GET_METADATA} is {@linkplain
* #getAvailableCommands() available}.
*
* @see Listener#onMediaMetadataChanged(MediaMetadata)
*/
MediaMetadata getMediaMetadata();
@marcbaechinger Thanks for your response, its clear and i have some stuff to think about.
There is Player.replaceMediaItem(index, MediaItem) that you may consider. You can update the MediaMetadata and replace the metadata in the existing MediaItem. Then use that method to update the media item. So you could set the titel there as well. I ahven't tested but probably worth including into the thinking process. :)