Fix thumbnail quality in notification and use proper metadata

This commit is contained in:
Bnyro 2023-05-18 16:37:00 +02:00
parent 03d712d834
commit 024d55dd16
4 changed files with 42 additions and 56 deletions

View File

@ -0,0 +1,31 @@
package com.github.libretube.extensions
import android.content.res.Resources
import android.graphics.BitmapFactory
import android.support.v4.media.MediaMetadataCompat
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import com.github.libretube.R
import com.github.libretube.api.obj.Streams
fun MediaItem.Builder.setMetadata(streams: Streams) = apply {
val appIcon = BitmapFactory.decodeResource(
Resources.getSystem(),
R.drawable.ic_launcher_monochrome,
)
val extras = bundleOf(
MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON to appIcon,
MediaMetadataCompat.METADATA_KEY_TITLE to streams.title,
MediaMetadataCompat.METADATA_KEY_ARTIST to streams.uploader,
)
setMediaMetadata(
MediaMetadata.Builder()
.setTitle(streams.title)
.setArtist(streams.uploader)
.setArtworkUri(streams.thumbnailUrl.toUri())
.setExtras(extras)
.build()
)
}

View File

@ -27,6 +27,7 @@ import com.github.libretube.constants.PLAYER_NOTIFICATION_ID
import com.github.libretube.db.DatabaseHolder.Database
import com.github.libretube.db.obj.WatchPosition
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.setMetadata
import com.github.libretube.extensions.toID
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.helpers.PlayerHelper.checkForSegments
@ -294,8 +295,7 @@ class OnlinePlayerService : LifecycleService() {
* Sets the [MediaItem] with the [streams] into the [player]
*/
private fun setMediaItem() {
val streams = streams
streams ?: return
val streams = streams ?: return
val uri = if (streams.audioStreams.isNotEmpty()) {
PlayerHelper.getAudioSource(this, streams.audioStreams)
@ -305,6 +305,7 @@ class OnlinePlayerService : LifecycleService() {
val mediaItem = MediaItem.Builder()
.setUri(ProxyHelper.rewriteUrl(uri))
.setMetadata(streams)
.build()
player?.setMediaItem(mediaItem)
}

View File

@ -121,6 +121,7 @@ import retrofit2.HttpException
import java.io.IOException
import java.util.*
import java.util.concurrent.Executors
import com.github.libretube.extensions.setMetadata
import kotlin.math.abs
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
@ -1246,10 +1247,11 @@ class PlayerFragment : Fragment(), OnlinePlayerOptions {
}
private fun setMediaSource(uri: Uri, mimeType: String) {
val mediaItem: MediaItem = MediaItem.Builder()
val mediaItem = MediaItem.Builder()
.setUri(uri)
.setMimeType(mimeType)
.setSubtitleConfigurations(subtitles)
.setMetadata(streams)
.build()
exoPlayer.setMediaItem(mediaItem)
}

View File

@ -6,13 +6,9 @@ import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Build
import android.os.Bundle
import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.util.Log
import androidx.annotation.DrawableRes
import androidx.core.app.NotificationCompat
import androidx.core.app.PendingIntentCompat
@ -22,7 +18,6 @@ import androidx.core.os.bundleOf
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.session.CommandButton
import androidx.media3.session.DefaultMediaNotificationProvider
import androidx.media3.session.MediaSession
import androidx.media3.session.SessionCommand
import androidx.media3.session.SessionResult
@ -36,7 +31,6 @@ import com.github.libretube.helpers.ImageHelper
import com.github.libretube.helpers.PlayerHelper
import com.github.libretube.obj.PlayerNotificationData
import com.github.libretube.ui.activities.MainActivity
import com.google.common.collect.ImmutableList
import com.google.common.util.concurrent.ListenableFuture
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
@ -102,10 +96,10 @@ class NowPlayingNotification(
player: Player,
callback: PlayerNotificationManager.BitmapCallback,
): Bitmap? {
if (DataSaverMode.isEnabled(context)) return null
// On Android 13 and up, the metadata is responsible for the thumbnail
if (DataSaverMode.isEnabled(context) ||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) return null
if (bitmap == null) enqueueThumbnailRequest(callback)
return bitmap
}
@ -119,7 +113,7 @@ class NowPlayingNotification(
// online image
notificationData?.thumbnailPath?.let { path ->
ImageHelper.getDownloadedImage(context, path)?.let {
bitmap = processThumbnailBitmap(it)
bitmap = ImageHelper.getSquareBitmap(it)
callback.onBitmap(bitmap!!)
}
return
@ -128,7 +122,7 @@ class NowPlayingNotification(
val request = ImageRequest.Builder(context)
.data(notificationData?.thumbnailUrl)
.target {
bitmap = processThumbnailBitmap(it.toBitmap())
bitmap = ImageHelper.getSquareBitmap(it.toBitmap())
callback.onBitmap(bitmap!!)
}
.build()
@ -159,17 +153,6 @@ class NowPlayingNotification(
}
}
/**
* Returns the bitmap on Android 13+, for everything below scaled down to a square
*/
private fun processThumbnailBitmap(bitmap: Bitmap): Bitmap {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
ImageHelper.getSquareBitmap(bitmap)
} else {
bitmap
}
}
private fun createNotificationAction(
drawableRes: Int,
actionName: String,
@ -260,24 +243,6 @@ class NowPlayingNotification(
createMediaSessionAction(R.drawable.ic_forward_md, FORWARD),
)
private fun getMediaDescription(): MediaDescriptionCompat {
val appIcon = BitmapFactory.decodeResource(
context.resources,
R.drawable.ic_launcher_monochrome,
)
val extras = bundleOf(
MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON to appIcon,
MediaMetadataCompat.METADATA_KEY_TITLE to notificationData?.title,
MediaMetadataCompat.METADATA_KEY_ARTIST to notificationData?.uploaderName,
)
return MediaDescriptionCompat.Builder()
.setTitle(notificationData?.title)
.setSubtitle(notificationData?.uploaderName)
.setIconBitmap(appIcon)
.setExtras(extras)
.build()
}
private fun handlePlayerAction(action: String) {
when (action) {
NEXT -> {
@ -324,19 +289,6 @@ class NowPlayingNotification(
}
}
class NotificationProvider(val context: Context) : DefaultMediaNotificationProvider(context) {
override fun getMediaButtons(
session: MediaSession,
playerCommands: Player.Commands,
customLayout: ImmutableList<CommandButton>,
showPauseButton: Boolean,
): ImmutableList<CommandButton> {
val buttons = super.getMediaButtons(session, playerCommands, customLayout, showPauseButton)
buttons.removeFirst()
return buttons
}
}
/**
* Initializes the [playerNotification] attached to the [player] and shows it.
*/