Fix incorrect thumbnail url and song metadata inference

This commit is contained in:
vfsfitvnm
2022-06-16 15:25:14 +02:00
parent abf2be6c9a
commit 6dbc57aa53
9 changed files with 64 additions and 21 deletions

View File

@@ -367,7 +367,7 @@ class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller,
coroutineScope.launch(Dispatchers.IO) {
lastBitmap = Coil.imageLoader(applicationContext).execute(
ImageRequest.Builder(applicationContext)
.data("${mediaMetadata.artworkUri}-w${notificationThumbnailSize}-h${notificationThumbnailSize}")
.data(mediaMetadata.artworkUri.thumbnail(notificationThumbnailSize))
.build()
).drawable?.let {
lastArtworkUri = mediaMetadata.artworkUri

View File

@@ -13,7 +13,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.graphicsLayer
@@ -102,7 +101,7 @@ fun PlayerView(
}
) {
AsyncImage(
model = "${player.mediaMetadata.artworkUri}-w$smallThumbnailSize-h$smallThumbnailSize",
model = player.mediaMetadata.artworkUri.thumbnail(smallThumbnailSize),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier
@@ -220,11 +219,11 @@ fun PlayerView(
.align(Alignment.CenterHorizontally)
) {
val artworkUri = remember(it) {
player.mediaController.getMediaItemAt(it).mediaMetadata.artworkUri
player.mediaController.getMediaItemAt(it).mediaMetadata.artworkUri.thumbnail(thumbnailSizePx)
}
AsyncImage(
model = "$artworkUri-w$thumbnailSizePx-h$thumbnailSizePx",
model = artworkUri,
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier

View File

@@ -26,6 +26,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
import it.vfsfitvnm.vimusic.utils.color
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.thumbnail
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -54,7 +55,7 @@ fun PlaylistPreviewItem(
) {
if (thumbnails.toSet().size == 1) {
AsyncImage(
model = "${thumbnails.first()}-w${thumbnailSizePx * 2}-h${thumbnailSizePx * 2}",
model = thumbnails.first().thumbnail(thumbnailSizePx * 2),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier
@@ -68,7 +69,7 @@ fun PlaylistPreviewItem(
Alignment.BottomEnd
).forEachIndexed { index, alignment ->
AsyncImage(
model = "${thumbnails.getOrNull(index)}-w$thumbnailSizePx-h$thumbnailSizePx",
model = thumbnails.getOrNull(index).thumbnail(thumbnailSizePx),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier

View File

@@ -32,6 +32,7 @@ import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette
import it.vfsfitvnm.vimusic.ui.styling.LocalTypography
import it.vfsfitvnm.vimusic.utils.secondary
import it.vfsfitvnm.vimusic.utils.semiBold
import it.vfsfitvnm.vimusic.utils.thumbnail
@ExperimentalAnimationApi
@@ -49,7 +50,7 @@ fun SongItem(
SongItem(
thumbnailModel = ImageRequest.Builder(LocalContext.current)
.diskCacheKey(mediaItem.mediaId)
.data("${mediaItem.mediaMetadata.artworkUri}-w$thumbnailSize-h$thumbnailSize")
.data(mediaItem.mediaMetadata.artworkUri.thumbnail(thumbnailSize))
.build(),
title = mediaItem.mediaMetadata.title!!.toString(),
authors = mediaItem.mediaMetadata.artist.toString(),
@@ -75,7 +76,7 @@ fun SongItem(
onThumbnailContent: (@Composable BoxScope.() -> Unit)? = null,
) {
SongItem(
thumbnailModel = "${song.song.thumbnailUrl}-w$thumbnailSize-h$thumbnailSize",
thumbnailModel = song.song.thumbnailUrl?.thumbnail(thumbnailSize),
title = song.song.title,
authors = song.authors?.joinToString("") { it.text } ?: "",
durationText = song.song.durationText,

View File

@@ -2,6 +2,7 @@ package it.vfsfitvnm.vimusic.utils
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.media3.common.MediaItem
@@ -171,4 +172,16 @@ fun YouTube.PlaylistOrAlbum.Item.toMediaItem(
)
.setMediaId(info.endpoint?.videoId ?: return null)
.build()
}
fun String?.thumbnail(size: Int): String? {
return when {
this?.startsWith("https://lh3.googleusercontent.com") == true -> "$this-w$size-h$size"
this?.startsWith("https://yt3.ggpht.com") == true -> "$this-s$size"
else -> this
}
}
fun Uri?.thumbnail(size: Int): Uri? {
return toString().thumbnail(size)?.toUri()
}

View File

@@ -159,18 +159,32 @@ object YouTube {
override fun from(content: MusicShelfRenderer.Content): Song {
val (mainRuns, otherRuns) = content.runs
// Possible configurations:
// "song" • author(s) • album • duration
// "song" • author(s) • duration
// author(s) • album • duration
// author(s) • duration
val album: Info<NavigationEndpoint.Endpoint.Browse>? = otherRuns
.getOrNull(otherRuns.lastIndex - 1)
?.firstOrNull()
?.takeIf { run ->
run
.navigationEndpoint
?.browseEndpoint
?.type == "MUSIC_PAGE_TYPE_ALBUM"
}
?.let(Info.Companion::from)
return Song(
info = Info.from(mainRuns.first()),
authors = otherRuns
.getOrNull(otherRuns.lastIndex - 2)
.getOrNull(otherRuns.lastIndex - if (album == null) 1 else 2)
?.map(Info.Companion::from)
?: emptyList(),
album = otherRuns
.getOrNull(otherRuns.lastIndex - 1)
?.firstOrNull()
?.let(Info.Companion::from),
album = album,
durationText = otherRuns
.getOrNull(otherRuns.lastIndex)
.lastOrNull()
?.firstOrNull()?.text,
thumbnail = content
.thumbnail
@@ -603,8 +617,13 @@ object YouTube {
thumbnail = renderer
.thumbnail
.thumbnails
.getOrNull(0),
durationText = renderer.lengthText.text
.also {
println(it)
}
.firstOrNull(),
durationText = renderer
.lengthText
.text
)
},
lyrics = NextResult.Lyrics(

View File

@@ -56,10 +56,8 @@ data class NavigationEndpoint(
val endpoint: Endpoint?
get() = watchEndpoint ?: browseEndpoint ?: watchPlaylistEndpoint ?: searchEndpoint
@Serializable
sealed class Endpoint {
@Serializable
data class Watch(
val params: String? = null,
@@ -69,6 +67,10 @@ data class NavigationEndpoint(
val playlistSetVideoId: String? = null,
val watchEndpointMusicSupportedConfigs: WatchEndpointMusicSupportedConfigs? = null,
) : Endpoint() {
val type: String?
get() = watchEndpointMusicSupportedConfigs
?.watchEndpointMusicConfig
?.musicVideoType
@Serializable
data class WatchEndpointMusicSupportedConfigs(
@@ -82,7 +84,6 @@ data class NavigationEndpoint(
}
}
@Serializable
data class WatchPlaylist(
val params: String?,
@@ -96,6 +97,10 @@ data class NavigationEndpoint(
val browseId: String,
val browseEndpointContextSupportedConfigs: BrowseEndpointContextSupportedConfigs?,
) : Endpoint() {
val type: String?
get() = browseEndpointContextSupportedConfigs
?.browseEndpointContextMusicConfig
?.pageType
@Serializable
data class BrowseEndpointContextSupportedConfigs(

View File

@@ -16,7 +16,11 @@ data class Runs(
run.text == "" -> listOf(index - 1, index + 1)
else -> emptyList()
}
}.windowed(size = 2, step = 2) { (from, to) -> runs.slice(from..to) }
}.windowed(size = 2, step = 2) { (from, to) -> runs.slice(from..to) }.let {
it.ifEmpty {
listOf(runs)
}
}
}
@Serializable

View File

@@ -45,3 +45,4 @@ data class ThumbnailRenderer(
}
}
}