androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
https://developer.android.com/media/media3
Apache License 2.0
1.74k stars 416 forks source link

content:// URI set with setArtworkUri not displayed in Notification #1386

Closed pawaom closed 6 months ago

pawaom commented 6 months ago

setArtworkUri(imageUri) for MediaMetadata.Builder() doesnot render Image In PlayerView and Notification

I am trying to play songs from Phone Local storage I am trying to set theImageuri for MediaMetadata`

This is the code I am using

 val metadata = MediaMetadata.Builder().setAlbumTitle(album).setTitle(title)
            .setArtist(artist).setGenre(genre).setIsBrowsable(isBrowsable).setIsPlayable(isPlayable)
           //   .setArtworkUri(imageUri)
            .setMediaType(mediaType).build()

When I set the setArtworkUri(imageUri) Where ImageUri is

val albumId = getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.ALBUM_ID))

val ImageUri = ContentUris.withAppendedId( MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, albumId )

The Artwork is not displayed either in the Playerview or the notification

The other code used is from the Demo sessions app only the Mediaitemtree is created using the mediastore from localstorage instead of JSONObject

The question is how can we set the imageUri for the Uri that we get from the local storage

We have lazy column displaying a list of all the mediaitems In order to Maintain consistency we use the mediaMetadata.artworkUri with AsyncImage in coil , If I set the ImageUri the AsyncImage is able to show the Image but the Playerview and Notification wont show any image

If we don't set the imageuri the asyncimage wont show the image since mediaMetadata.artworkUri is null which is expected behavior` but the playerview and notification does show it

We want 2 options 1) set the imageuri using mediastore uri to show in Playerview, notification 2) if imageuri is not set allow access to the image that is displayed by the notification and playerviw that we can show in Asyncimage

marcbaechinger commented 6 months ago

Thanks for reporting!

Rendering the image referenced in the MediaItem in PlayerView isn't supported yet and regarding that this issue is a duplicate of issue #195. The issue is marked as an enhancement.

val ImageUri = ContentUris.withAppendedId( MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, albumId )

I think this results in a URI with a content://-schema. I'd expect that content://-URI is supported by DataSourceBitmapLoader.

Can you confirm and paste the URI that is the result in ImageUri for confirming? Did you change the BitmapLoader that can be set with MediaSession.Builder.setBitmapLoader(loader)?

This would help to repro in case this is a bug.

And to avoid another round-trip: can you send a bugreport just after the issue happens, so we can look intot he logs?

if imageuri is not set allow access to the image that is displayed by the notification and playerviw that we can show in Asyncimage

I don't really understand what this means I'm afraid. If you are refering to the image that is shown by the PlayerView then this is the image that is part of the media you are playing. You can listen to Player.LIstener.onMediaMetadata(MediaMetadata) and check metadata.artworkData. The image that's in the media is merged into the medua metadata by the player.

Please clarify if I misundertood your statement.

pawaom commented 6 months ago

Rendering the image referenced in the MediaItem in PlayerView isn't supported yet and regarding that this issue is a duplicate of issue #195. The issue is marked as an enhancement.

You mentioned that Rendering the image referenced in theMediaIteminPlayerViewisn't supported but this works if we don't use .setArtworkUri(imageUri)

So I don't understand why this is being considered even now, I had raised this issue earlier and after testing it later on I thought this issue was resolved here is an example it works both for notification and Playerview Screenshot_20240522_154536_MediaSessionLocalDemoLatest

Screenshot_20240522_154516_MediaSessionLocalDemoLatest

My question is specific 1) How can we access this image that is being shown in both playerview and Notification using mediaMetadata.artworkUri or any other way which we can display in the Lazy column using AsyncImage of coil library, this is the case when we don't use .setArtworkUri(imageUri) while creating the mediaitem

2) If we use the .setArtworkUri(imageUri) for mediastore as explained above the image is not shown in Playerview or Notification how can we address this issue.

marcbaechinger commented 6 months ago

Sorry for not being clear.

If you reference an image as artworkUri then the PlayerView doesn't support this. What you see is when the actual bitmap is put into the metadata with artworkData.

When artworkUri is set, then a BitmapLoader is attempting to download the image and puts the resulting bytes into artworkData. From there PlayerView and System UI is reading it. If there isn't an artworkUri then the BitmapLoader isn't doing anything, In case that the media has some metadata with the artwork bitmap, the player merges this into the MediaMetadata.artworkData.

How can we access this image that is being shown in both playerview and Notification using mediaMetadata.artworkUri

You can't. You can use mediaMetadata.artworkData that is filled with the bitmap in the media as soon as the metadata is read. Then the metdata from the media is merged into the MediaMetadata from the MediaItem and onMediaMetadataChanged(MediaMetdata) is called.

If we use the .setArtworkUri(imageUri) for mediastore as explained above the image is not shown in Playerview or Notification how can we address this issue.

Like I said:

artworkUri is not supported with PlayerView. Only artworkData is. We have #195 as an enhancement for this.

We need more information as mentioned above:

Can you paste the URI that is the result in ImageUri? Did you change the BitmapLoader that can be set with MediaSession.Builder.setBitmapLoader(loader)?

pawaom commented 6 months ago

the Uri is in the content://-schema

here is the example

For the same song when we use .setArtworkUri(imageUri) check the uri that is displayed below the player

You can see the image is not displayed in the Playerview similar for the Notification

Screenshot_20240522_162050_MediaSessionLocalDemoLatest

marcbaechinger commented 6 months ago

Thanks!

It's expected that the PlayerView doesn't show the image referenced by URI.

I'll try to repro this. If you want me to send a bug report this can speed up investigation for your case. The URI needs to be processed by your content provider. A bug report can help us ruling out that the URI isn't correct and that the content provider works as expected.

pawaom commented 6 months ago

The Uri is correct I have tried with multiple files and Uris, I know Playerview doesnot show the image , but notification is expected to show , I will test how we can show metadata.artworkData in asyncimage in Coil.

thanks for the reply.

marcbaechinger commented 6 months ago

I tested this with the ContentProvider that is part of the automotive app. I moved it to the demo session and changed the URIs of the mediat items to a content://-URI:

    <provider
      android:name="BitmapContentProvider"
      android:authorities="androidx.media3"
      android:exported="true" />

URI: content://androidx.media3/artwork/album_kyoto_connection.png

With this I see that the DataSourceBitmapLoader is calling ContentProvider.openFile():

openFile:41, BitmapContentProvider (androidx.media3.demo.session)
openAssetFile:2239, ContentProvider (android.content)
openTypedAssetFile:2417, ContentProvider (android.content)
openTypedAssetFile:2484, ContentProvider (android.content)
openTypedAssetFile:667, ContentProvider$Transport (android.content)
openTypedAssetFileDescriptor:2043, ContentResolver (android.content)
openTypedAssetFileDescriptor:1981, ContentResolver (android.content)
open:85, ContentDataSource (androidx.media3.datasource)
open:275, DefaultDataSource (androidx.media3.datasource)
load:112, DataSourceBitmapLoader (androidx.media3.datasource)
lambda$loadBitmap$2$androidx-media3-datasource-DataSourceBitmapLoader:105, DataSourceBitmapLoader (androidx.media3.datasource)
call:0, DataSourceBitmapLoader$$ExternalSyntheticLambda2 (androidx.media3.datasource)
runInterruptibly:131, TrustedListenableFutureTask$TrustedFutureInterruptibleTask (com.google.common.util.concurrent)
run:76, InterruptibleTask (com.google.common.util.concurrent)
run:82, TrustedListenableFutureTask (com.google.common.util.concurrent)
runWorker:1145, ThreadPoolExecutor (java.util.concurrent)
run:644, ThreadPoolExecutor$Worker (java.util.concurrent)
run:1012, Thread (java.lang)

Can you please check:

  1. Whether you are using DataSourceBitmapLoader
  2. Whether the URI matches the authority in the manifest?
  3. Whether DatasourceBitmapLoader is calling your content provider's openFile method?

In case I forgot to say that a bugreport would be helpful for us for investigation I mention this now. For now I think this is working as intended from the library side.

pawaom commented 6 months ago

I am not using DataSourceBitmapLoader it was simple .setArtworkUri(imageUri) which I expected to show the albumart atleast in the Notification As I have noticed in the details that you have provided above, the Uri is

URI: content://androidx.media3/artwork/album_kyoto_connection.png

Where as for Libraries Like Glide, Coil etc we provided the Uri with AlbumId

content://media/external/audio/albums/359288605841912543 Is this causing an error, If so how can I fix this