Downloaded media does not set RequestMetadata which is required for Media Session Callback
When accessing downloaded media for offline mode you make a request to downloadRequest.toMediaItem() https://github.com/androidx/media/blob/2c7201024ebdbfccf32e291f816fe426cc5540d8/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/offline/DownloadRequest.java#L230-L238 However when using a MediaSession for background playing it is required to set the media item in the MediaSession.Callback and access the URI from the RequestMetadata that was set on the mediaItem. Since you don't create the mediaItem in the offline scenario instead it is created in the above code the requestMetadata never gets set. I'm wondering if there is a way to manually set the requestMetadata on a download request item so that background playing in offline mode can still work. Or if it would be possible to add a requestMetadata to the toMediaItem() method.
Here is a diff of kind of what I had in mind https://github.com/androidx/media/pull/144
@marcbaechinger can you take a look? Would there be any side effects if we always set the MediaItem's RequestMetadata from the uri in DownloadRequest.toMediaItem()?
Just wanted to note that I will be out on vacation for the next two weeks so if I'm not responding it's not because I don't want this issue fixed it's just that I'm away from my keyboard. Thanks!
thanks for the update, it's the same more or less here too :)
@nplasterer Thanks. Can you add some more context why this is required? I'm asking because DownloadRequest.toMediaItem() is only called from a single call site in the library, which is in the DownloadHelper to create a MediaSource. This is on the player side of things, rather than the MediaController side.
I'm wondering if there is a way to manually set the requestMetadata on a download request item so that background playing in offline mode can still work.
My current understanding of your explanation above is that your app calls DownloadRequest.toMediaItem() and then passes the media item to a method like MediaController.setMediaItem(MediaItem). That's why the RequestMetadata is missing when the media item arrives at onAddMediaItems.
If this is the case you can already manually set the requestMetadata if I understand correctly:
MediaItem mediaItem = downloadRequest.toMediaItem();
MediaItem.RequestMetadata requestMetadata =
new MediaItem.RequestMetadata.Builder()
.setMediaUri(checkNotNull(mediaItem.localConfiguration).uri)
.build();
mediaController.setMediaItem(
mediaItem
.buildUpon()
.setRequestMetadata(requestMetadata)
.build());
This way an app can set whatever RequestMetadata the app needs to have. If we bake this into the toMediaItem we can probably not solve this for all apps, so the generic way from above seems preferable.
Please accept my apologies if I misunderstand something or I don't see the use case for which the change would be needed. I kindly ask for clarification from your side in that case. :)
Thanks @marcbaechinger this worked perfectly for some reason I thought request metadata was private and I wasn't able to set it but I think I was just doing it wrong.