mirror of
https://github.com/androidx/media.git
synced 2025-05-13 10:39:51 +08:00
Add artwork to stored preferences
This allows it to be displayed after reboot when we can't reload it safely over network. PiperOrigin-RevId: 753122948
This commit is contained in:
parent
8d87a69351
commit
deb466c496
@ -17,7 +17,9 @@ package androidx.media3.demo.session
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.core.net.toUri
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.MediaMetadata
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.demo.session.service.R
|
||||
import androidx.media3.session.CommandButton
|
||||
@ -189,7 +191,16 @@ open class DemoMediaLibrarySessionCallback(val service: DemoPlaybackService) :
|
||||
return CoroutineScope(Dispatchers.Unconfined).future {
|
||||
service.retrieveLastStoredMediaUidAndPosition()?.let {
|
||||
maybeExpandSingleItemToPlaylist(
|
||||
mediaItem = MediaItem.Builder().setMediaId(it.mediaId).build(),
|
||||
mediaItem =
|
||||
MediaItem.Builder()
|
||||
.setMediaId(it.mediaId)
|
||||
.setMediaMetadata(
|
||||
MediaMetadata.Builder()
|
||||
.setArtworkUri(it.artworkOriginalUri.toUri())
|
||||
.setArtworkData(it.artworkData.toByteArray(), MediaMetadata.PICTURE_TYPE_MEDIA)
|
||||
.build()
|
||||
)
|
||||
.build(),
|
||||
startIndex = 0,
|
||||
startPositionMs = it.positionMs,
|
||||
)
|
||||
@ -229,8 +240,8 @@ open class DemoMediaLibrarySessionCallback(val service: DemoPlaybackService) :
|
||||
// Try to get the parent and its children.
|
||||
MediaItemTree.getParentId(mediaId)?.let {
|
||||
playlist =
|
||||
MediaItemTree.getChildren(it).map { mediaItem ->
|
||||
if (mediaItem.mediaId == mediaId) MediaItemTree.expandItem(mediaItem)!! else mediaItem
|
||||
MediaItemTree.getChildren(it).map { childItem ->
|
||||
if (childItem.mediaId == mediaId) MediaItemTree.expandItem(mediaItem)!! else childItem
|
||||
}
|
||||
indexInPlaylist = MediaItemTree.getIndexInMediaItems(mediaId, playlist)
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.core.app.NotificationCompat
|
||||
@ -40,11 +41,13 @@ import androidx.media3.session.MediaConstants
|
||||
import androidx.media3.session.MediaLibraryService
|
||||
import androidx.media3.session.MediaSession
|
||||
import androidx.media3.session.MediaSession.ControllerInfo
|
||||
import com.google.protobuf.ByteString
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.guava.await
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
open class DemoPlaybackService : MediaLibraryService() {
|
||||
@ -167,15 +170,30 @@ open class DemoPlaybackService : MediaLibraryService() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(UnstableApi::class) // BitmapLoader
|
||||
private fun storeCurrentMediaUidAndPosition() {
|
||||
val mediaID = mediaLibrarySession.player.currentMediaItem?.mediaId
|
||||
if (mediaID == null) {
|
||||
return
|
||||
}
|
||||
val artworkUri = mediaLibrarySession.player.currentMediaItem?.mediaMetadata?.artworkUri
|
||||
val positionMs = mediaLibrarySession.player.currentPosition
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
PreferenceDataStore.get(this@DemoPlaybackService).updateData { _ ->
|
||||
Preferences.newBuilder().setMediaId(mediaID).setPositionMs(positionMs).build()
|
||||
PreferenceDataStore.get(this@DemoPlaybackService).updateData { preferences ->
|
||||
val builder = preferences.toBuilder().setMediaId(mediaID).setPositionMs(positionMs)
|
||||
val artworkUriString = artworkUri?.toString() ?: ""
|
||||
if (artworkUriString != preferences.artworkOriginalUri) {
|
||||
builder.setArtworkOriginalUri(artworkUriString)
|
||||
if (artworkUri == null) {
|
||||
builder.setArtworkData(ByteString.EMPTY)
|
||||
} else {
|
||||
val bitmap = mediaLibrarySession.bitmapLoader.loadBitmap(artworkUri).await()
|
||||
val outputStream = ByteString.newOutput()
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, /* quality= */ 90, outputStream)
|
||||
builder.setArtworkData(outputStream.toByteString())
|
||||
}
|
||||
}
|
||||
builder.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,4 +25,8 @@ message Preferences {
|
||||
string media_id = 1;
|
||||
// The position in the last played item in milliseconds.
|
||||
int64 position_ms = 2;
|
||||
// The original artwork URI of the last played item.
|
||||
string artwork_original_uri = 3;
|
||||
// The artwork image data of the last played item.
|
||||
bytes artwork_data = 4;
|
||||
}
|
||||
|
@ -1696,9 +1696,14 @@ public class MediaSession {
|
||||
* play without a current {@link MediaItem}.
|
||||
*
|
||||
* <p>This happens, for example, if <a
|
||||
* href="https://developer.android.com/guide/topics/media/session/mediasession#resumption">playback
|
||||
* href="https://developer.android.com/media/media3/session/background-playback#resumption">playback
|
||||
* resumption</a> is requested from a media button receiver or the System UI notification.
|
||||
*
|
||||
* <p>Use {@link MediaMetadata#artworkData} or {@link MediaMetadata#artworkUri} with a content
|
||||
* URI to set locally available artwork data for the System UI notification after reboot of the
|
||||
* device. Note that network access may not be available when this method is called during boot
|
||||
* time.
|
||||
*
|
||||
* <p>The method will only be called if the {@link Player} has {@link
|
||||
* Player#COMMAND_GET_CURRENT_MEDIA_ITEM} and either {@link Player#COMMAND_SET_MEDIA_ITEM} or
|
||||
* {@link Player#COMMAND_CHANGE_MEDIA_ITEMS} available.
|
||||
|
Loading…
x
Reference in New Issue
Block a user