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

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

Closed
1 task
vanniktech opened this issue Aug 18, 2022 · 7 comments
Assignees
Labels

Comments

@vanniktech
Copy link

vanniktech commented Aug 18, 2022

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.
@marcbaechinger
Copy link
Contributor

marcbaechinger commented Aug 18, 2022

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.

@vanniktech
Copy link
Author

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
Copy link
Author

vanniktech commented Aug 20, 2022

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

@marcbaechinger
Copy link
Contributor

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.

@PaulWoitaschek
Copy link
Contributor

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.

@marcbaechinger
Copy link
Contributor

marcbaechinger commented May 16, 2023

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
Copy link
Contributor

Closing as the initial issue is fixed.

@androidx androidx locked and limited conversation to collaborators Aug 1, 2023
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