Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MediaController.replaceMedia() does not update metadata correctly #706

Closed
WSteverink opened this issue Oct 6, 2023 · 3 comments
Closed
Assignees
Labels

Comments

@WSteverink
Copy link

WSteverink commented Oct 6, 2023

We are currently in the process of developing an app for a radio station, and as a part of our project, we need to ensure that the MediaItem's MetaData is updated when there is a change in the track being played.

As suggested in this post, we are utilising version 1.2.0-alpha02 of the library, which can be found at the following link: GitHub - androidx/media/issues/615.

It has been recommended that we replace the MediaItem with updated MetaData to ensure that it is reflected in both the session and the notification. However, during our experimentation, we have observed that the replaceMediaItem() method only functions as expected when directly called on the ExoPlayer instance. When we attempt to use our MediaBrowser to invoke replaceMediaItem(), the notification does not update accordingly.

We have also conducted tests using the sample Media3 app. To facilitate the reproduction of our steps, you can modify the implementation of the shuffle button as follows:

val currentIndex = browser.currentMediaItemIndex
val current = browser.currentMediaItem ?: return@setOnClickListener

val metaCopy = current.mediaMetadata
    .buildUpon()
    .setArtist("Some new artist name")
    .setTitle("New title")
    .setAlbumTitle("Nope")
    .build()

val itemCopy = current.buildUpon()
    .setMediaMetadata(metaCopy)
    .build()

browser.replaceMediaItem(currentIndex, itemCopy)

You can find this code in the following file:

GitHub - androidx/media/demos/session/PlayableFolderActivity.kt#L87

Not sure if related but It's worth noting that, after some investigation, we discovered that the MediaBrowser is calling notifyPlayerInfoListenersWithReasons(), but it does not have any listeners to notify except for the one we have set ourselves. You can review this part of the code here:

GitHub - androidx/media/libraries/session/MediaControllerImplBase.java#L2208

We would appreciate guidance on how to proceed and confirmation as to whether our assumption that the MediaBrowser should be capable of updating the MetaData is accurate. Thank you in advance for your assistance!

@tonihei
Copy link
Collaborator

tonihei commented Oct 11, 2023

Thanks for sharing the reproduction steps!

It turns out the feature to replace media items works as intended, but there is a caveat that is easy to miss: when sending items from the MediaController to a MediaSession, they are always resolved by MediaSession.Callback.onAddMediaItems to be playable by the underlying player (e.g. add-in the real URL).

The session demo app implements this method by completely replacing the original MediaItem with the one from its MediaItemTree database. So it just drops any new metadata you sent via replaceMediaItem. If I replace this part of the logic with something like this, everything works as you expected:

null -> MediaItemTree.getItem(mediaItem.mediaId)?.let {
  if (mediaItem.mediaMetadata != MediaMetadata.EMPTY) {
    playlist.add(it.buildUpon().setMediaMetadata(mediaItem.mediaMetadata).build())
  } else {
    playlist.add(it)
  }
}

This isn't an implementation everyone should use, because the real logic depends on how you want to setup your media items. Depending on where the initial and updated metadata is coming from (always the controller, always a local database, or mixture?), you can build your updated media item accordingly.

I can think about whether our demo app should use a more sophisticated logic that allows merging metadata by default to avoid this pitfall during testing. But otherwise, you should be able to adjust your MediaSession.Callback.onAddMediaItems method to resolve the item as you need.

@WSteverink
Copy link
Author

We are doing something similar to the demo app and resolving the MediaItems when onAddMediaItems is called.

For us, the fix will be to ensure that the resolved MediaItem in onAddMediaItems always contains the latest MediaMetaData.

We are using replaceMediaItems in a way that more or less serves as a function to invalidate the current media item. Perhaps it would be beneficial to have an explicit function for directly updating the MediaMetaData of the current MediaItem or to invalidate the CurrentMediaItem.

Anyway, thank you for the response!

@tonihei
Copy link
Collaborator

tonihei commented Oct 16, 2023

Perhaps it would be beneficial to have an explicit function for directly updating the MediaMetaData of the current MediaItem or to invalidate the CurrentMediaItem.

Just for clarification - can you give an example of how you would imagine this methods looks like? It sounds like replaceMedaItem is doing this already but maybe I'm missing some aspect here.

copybara-service bot pushed a commit that referenced this issue Oct 16, 2023
When MediaItems are added from the controller, we currently completely
replace the item with the one from our database, overriding any
potential additional information the controller may have set.

Also forward the onAddMediaItems/onSetMediaItems callbacks to common
helper methods instead of redirecting them through super methods

#minor-release
Issue: #706
PiperOrigin-RevId: 573799351
rohitjoins pushed a commit that referenced this issue Oct 23, 2023
When MediaItems are added from the controller, we currently completely
replace the item with the one from our database, overriding any
potential additional information the controller may have set.

Also forward the onAddMediaItems/onSetMediaItems callbacks to common
helper methods instead of redirecting them through super methods

#minor-release
Issue: #706
PiperOrigin-RevId: 573799351
(cherry picked from commit 00425db)
@tonihei tonihei closed this as completed Dec 11, 2023
@androidx androidx locked and limited conversation to collaborators Feb 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants