media icon indicating copy to clipboard operation
media copied to clipboard

When playing a MediaItem on Android Auto the queue only contains the currently selected MediaItem

Open vanniktech opened this issue 2 years ago • 4 comments

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:

Screen Shot 2022-08-17 at 23 27 20

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:

Screen Shot 2022-08-17 at 23 28 20

Media

Bug Report

  • [ ] You will email the zip file produced by adb bugreport to [email protected] after filing this issue.

vanniktech avatar Aug 18 '22 17:08 vanniktech

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.

marcbaechinger avatar Aug 18 '22 22:08 marcbaechinger

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.

vanniktech avatar Aug 19 '22 13:08 vanniktech

@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.

vanniktech avatar Aug 20 '22 14:08 vanniktech

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.

marcbaechinger avatar Aug 22 '22 10:08 marcbaechinger

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:

image

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.

PaulWoitaschek avatar May 16 '23 21:05 PaulWoitaschek

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:

  1. Create a SettableFuture<MediaItemsWithStartPosition> (and return it)
  2. Load the data for MediaItemsWithStartPosition.
  3. Load the data for speed, shuffleMode and set it to the player.
  4. Set the loaded MediaItemsWithPosition to 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.

marcbaechinger avatar May 16 '23 22:05 marcbaechinger

Closing as the initial issue is fixed.

marcbaechinger avatar Jun 01 '23 20:06 marcbaechinger