media
media copied to clipboard
When playing a MediaItem on Android Auto the queue only contains the currently selected MediaItem
Media3 Version
1.0.0-beta02
Devices that reproduce the issue
Android Auto with Pixel 6 Pro
Devices that do not reproduce the issue
Reproducible in the demo app?
Not tested
Reproduction steps
In my onGetLibraryRoot, I have the following code:
internal val rootMediaItem: MediaItem by lazy {
MediaItem.Builder()
.setMediaId(PARENT_ID)
.setMediaMetadata(
MediaMetadata.Builder()
.setFolderType(MediaMetadata.FOLDER_TYPE_MIXED)
.setIsPlayable(false)
.build()
)
.build()
}
override fun onGetLibraryRoot(
session: MediaLibrarySession,
browser: MediaSession.ControllerInfo,
params: LibraryParams?,
): ListenableFuture<LibraryResult<MediaItem>> {
val rootExtras = Bundle().apply {
putBoolean(
MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED,
true,
)
putBoolean("android.media.browse.CONTENT_STYLE_SUPPORTED", true)
putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM,
)
putInt(
MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM,
)
}
val libraryParams = LibraryParams.Builder().setExtras(rootExtras).build()
return Futures.immediateFuture(LibraryResult.ofItem(rootMediaItem, libraryParams))
}
in onGetChildren, I load all of my items and they are being displayed just fine:
Expected result
When selecting one, I'd expect to use the List of MediaItem so that I can automatically skip ahead
Actual result
My queue contains only the selected item:
Media
Bug Report
- [ ] You will email the zip file produced by
adb bugreportto [email protected] after filing this issue.
Thanks for reporting!
Android Auto is using the MediaLibraryService to navigate in the catalogue as you describe. When the user selects an item, Android Auto is preparing the player with the given item via MediaControllerCompat.
In Media3 this preparation request from Android Auto calls MediaLibraryService.Callback.onAddMediaItems(MediaSession mediaSession, ControllerInfo controller, List<MediaItem> mediaItems). The mediaItems parameter contains a single MediaItem that is the one the user has selected.
When you implement onAddMediaItems you return a ListenableFuture<List<MediaItem>>. From your report above I think you now return a future that only contains the selected media item. You can instead return a list of items that is then used set as the playlist/queue.
Said this, there is still an issue because playback always starts at media item index 0. This means when a user selects for instance the third item in a category, you can not set the whole category and then start playback at the third item (media item index 2). I don't have a solution for this yet I'm afraid. I tried some hacky ways but I couldn't find a solution that works reliably.
The only thing you can do for now, is putting the selected item at the begin of the list and all the other items after it. That's a regression to what was possible with media1. So keeping the bug label. We need to think about how we can enable the desired behaviour.
Thanks for answering Marc! Indeed, this does work. I've used your workaround to shuffle the list. Not perfect but far better than having no queue at all.
@marcbaechinger I also find that in the onAddMediaItems method, mediaItems.first().mediaMetadata.extras is always null. Even though I am setting extras in onGetChildren. Is this related or should I file a separate issue? In general mediaMetadata seems to be an empty object, also no title / subtitle for me.
I don't think there is something the Media3 library can do to avoid that as long as Android Auto is using Media1. When AA is browsing your catalogue they are receiving a MediaBrowserCompat.MediaItem from which they take the mediaId to call Callback.prepareByMediaId(String mediaId).
Media3 then receives this call and creates a androidx.media3.MediaItem with it that only contains the mediaId. This is all the information available. You need to resolve the mediaId to a full androidx.media3.MediaItem in onAddMediaItems.
Now with MediaItemsWithStartPosition which you can return in MediaLibraryService.MediaLibrarySession.Callback#onSetMediaItems this is kind of solved, correct?
I wonder what's the best way to prepare additional things with media3. For example I also need to set the playback speed which I persisted, depending on the media items. And for which I need to query the database which is an async operation.
The only workaround I can imagine right now is to create a delegating player and overwrite all 6 setMediaItem permutations:
Then somehow fetch from the MediaItems where they belong to and then do an runBlocking here to also set the playback speed. But that feels very hacky.
I think you can just defer completing the Future that you return from onSetMediaItems. It's fine to set the speed before the items are set into the player.
For instance:
- Create a
SettableFuture<MediaItemsWithStartPosition>(and return it) - Load the data for
MediaItemsWithStartPosition. - Load the data for speed, shuffleMode and set it to the player.
- Set the loaded
MediaItemsWithPositionto the settable future. This will prepare the player and then start with the speed you've set earlier.
I haven't tried but I think that should work.
Closing as the initial issue is fixed.