Open OxygenCobalt opened 3 months ago
Hi @OxygenCobalt,
Thanks for diving deep around the MediaSession
and BitmapLoader
! Please see my answers below to some of your points but feel free to correct me if I misunderstood anything:
Since ExoPlayer does auto-parse metadata, it's also possible for cover art data extracted from there to be used as well. I don't know when this is triggered and it's not configurable from what I know.
Our current strategy is always prioritizing to use artworkUri
or artworkData
from the MediaItem.mediaMetadata
in the presence of any of them, and when none of them are set with the MediaItem.mediaMetadata
, we will use the artwork extracted from the stream if it is available. However, for now we haven't had more flexibility than that - eg. let the app set their preferred source of the bitmap, which is tracked as an enhancement for later https://github.com/androidx/media/issues/1221.
And if you have both artworkUri
and artworkData
set, the default implementation of BitmapLoader
will prioritize to decode the one from artworkData
than loading from artworkUri
, but this behaviour is customizable by app's implementation.
BitmapLoader will only apply to the notification, not the MediaSessionCompat
The BitmapLoader
injected with MediaSession.Builder
is also used for updating the metadata on MediaSessionCompat
. In fact, for Android 13+, the bitmap on the media notification is updated exactly via this way.
And I also saw that you've mentioned that from Android 11 onwards, the media notification picks the random covers. Could you please elaborate this issue a bit?
@tianyif
Since Android 11, media notifications draw from either the notification data (content title, content text, bitmap) or the MediaSession's current MediaMetadata. The issue is that the data picked depends on several factors, such as the OEM build, internal race conditions, or notification rate limiting. I discovered this on my own before I was using Media3, where if I did not synchronize metadata updates to be in the order of MediaSession and THEN the medianNotification, the metadata would not properly update. My final system was something like:
MediaSession
metadataAs far as I am aware, Media3 still launches two cover loads from BitmapLoader
in parallel, so you're going to run into similar confusing metadata desynchronizations if cover sources differ.
I have a hunch that this issue is at least related to new ones I've discovered when moving to Media3:
artworkUri
to a URI to a cover that differed from the one I was loading with my custom BitmapLoader
, and on some devices that have different timing the notification would prefer artworkUri
over BitmapLoader
, but others would do the opposite.BitmapLoader
returns full-resolution images, but if I were to force a metadata update with replaceMediaItems
, suddenly the notification cover would turn low-resolution despite it not meaningfully change.I'm not fully confident about the root cause, but both of these seem to me that there is no way to guarantee cover consistency here without causing confusing behavior. I've just been forced to fall back to whatever ExoPlayer does instead rather than using my own internal loader until I can effectively rebuild the entire MediaStore image system and just pass URIs everywhere.
[REQUIRED] Use case description
My app has two sources of cover art. It has a Coil setup with a bunch of extensions/settings options that would ideally be provided by
BitmapLoader
, and just plainMediaStore
URIs stored inMediaItem
s. However, It seems as if ExoPlayer seemingly erratically uses three different cover art sources depending on what's being applied.MediaSessionCompat
cover metadata is directly read from theMediaMetadata.artworkUri
orMediaMetadata.artworkData
of aMediaItem
, judging by this code. This is not configurable.BitmapLoader
, which can be configurable.This leads to several issues.
BitmapLoader
will only apply to the notification, not theMediaSessionCompat
.BitmapLoader
in it's current form, since you have no idea if it's going to randomly pick some other cover source.Please correct me if I don't fully understand the behavior or reasoning here.
Proposed solution
Make updates to the covers in media notification,
MediaSessionCompat
, and other places rely on a synchronized call toBitmapLoader
that allows full configuration on what cover data should be used. The only place this can be excluded is anything related to theMediaBrowser
, since I know that's a little infeasible.Alternatives considered
I can somewhat alleviate this on my end by unifying my cover sources with my own internal URI-based system, but this is extremely complicated and I can't do this right now. It also doesn't rule out the case of ExoPlayer auto-parsing it's own metadata and overriding mine, since I don't know what conditions trigger that.