From 92141f4f498df9f757ea5e1bde420ee7173cea8b Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Thu, 13 Oct 2022 19:48:27 +0200 Subject: [PATCH] Fix #423 --- .../vfsfitvnm/vimusic/savers/ArtistSaver.kt | 2 +- .../it/vfsfitvnm/vimusic/utils/Utils.kt | 2 +- .../youtubemusic/models/BrowseResponse.kt | 6 +- .../youtubemusic/requests/ArtistPage.kt | 177 +++++++++--------- 4 files changed, 99 insertions(+), 88 deletions(-) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/savers/ArtistSaver.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/savers/ArtistSaver.kt index 4112741..a24c13f 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/savers/ArtistSaver.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/savers/ArtistSaver.kt @@ -16,7 +16,7 @@ object ArtistSaver : Saver> { override fun restore(value: List): Artist = Artist( id = value[0] as String, - name = value[1] as String, + name = value[1] as String?, thumbnailUrl = value[2] as String?, info = value[3] as String?, timestamp = value[4] as Long?, diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt index a6c1e64..3c32c64 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Utils.kt @@ -83,7 +83,7 @@ val DetailedSong.asMediaItem: MediaItem 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" + this?.startsWith("https://yt3.ggpht.com") == true -> "$this-w$size-h$size-s$size" else -> this } } diff --git a/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/models/BrowseResponse.kt b/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/models/BrowseResponse.kt index 3c4ada8..4d66b65 100644 --- a/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/models/BrowseResponse.kt +++ b/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/models/BrowseResponse.kt @@ -1,6 +1,8 @@ package it.vfsfitvnm.youtubemusic.models +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonNames @Serializable data class BrowseResponse( @@ -15,7 +17,8 @@ data class BrowseResponse( ) @Serializable - data class Header( + data class Header @OptIn(ExperimentalSerializationApi::class) constructor( + @JsonNames("musicVisualHeaderRenderer") val musicImmersiveHeaderRenderer: MusicImmersiveHeaderRenderer?, val musicDetailHeaderRenderer: MusicDetailHeaderRenderer?, ) { @@ -33,6 +36,7 @@ data class BrowseResponse( val playButton: PlayButton?, val startRadioButton: StartRadioButton?, val thumbnail: ThumbnailRenderer?, + val foregroundThumbnail: ThumbnailRenderer?, val title: Runs? ) { @Serializable diff --git a/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/requests/ArtistPage.kt b/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/requests/ArtistPage.kt index c0f1ccb..afaa49f 100644 --- a/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/requests/ArtistPage.kt +++ b/innertube/src/main/kotlin/it/vfsfitvnm/youtubemusic/requests/ArtistPage.kt @@ -13,90 +13,97 @@ import it.vfsfitvnm.youtubemusic.utils.findSectionByTitle import it.vfsfitvnm.youtubemusic.utils.from import it.vfsfitvnm.youtubemusic.utils.runCatchingNonCancellable -suspend fun Innertube.artistPage(body: BrowseBody): Result? = runCatchingNonCancellable { - val response = client.post(browse) { - setBody(body) - mask("contents,header") - }.body() +suspend fun Innertube.artistPage(body: BrowseBody): Result? = + runCatchingNonCancellable { + val response = client.post(browse) { + setBody(body) + mask("contents,header") + }.body() - fun findSectionByTitle(text: String): SectionListRenderer.Content? { - return response - .contents - ?.singleColumnBrowseResultsRenderer - ?.tabs - ?.get(0) - ?.tabRenderer - ?.content - ?.sectionListRenderer - ?.findSectionByTitle(text) + println(response) + + fun findSectionByTitle(text: String): SectionListRenderer.Content? { + return response + .contents + ?.singleColumnBrowseResultsRenderer + ?.tabs + ?.get(0) + ?.tabRenderer + ?.content + ?.sectionListRenderer + ?.findSectionByTitle(text) + } + + val songsSection = findSectionByTitle("Songs")?.musicShelfRenderer + val albumsSection = findSectionByTitle("Albums")?.musicCarouselShelfRenderer + val singlesSection = findSectionByTitle("Singles")?.musicCarouselShelfRenderer + + Innertube.ArtistPage( + name = response + .header + ?.musicImmersiveHeaderRenderer + ?.title + ?.text, + description = response + .header + ?.musicImmersiveHeaderRenderer + ?.description + ?.text + ?.substringBeforeLast("\n\nFrom Wikipedia"), + thumbnail = (response + .header + ?.musicImmersiveHeaderRenderer + ?.foregroundThumbnail + ?: response + .header + ?.musicImmersiveHeaderRenderer + ?.thumbnail) + ?.musicThumbnailRenderer + ?.thumbnail + ?.thumbnails + ?.getOrNull(0), + shuffleEndpoint = response + .header + ?.musicImmersiveHeaderRenderer + ?.playButton + ?.buttonRenderer + ?.navigationEndpoint + ?.watchEndpoint, + radioEndpoint = response + .header + ?.musicImmersiveHeaderRenderer + ?.startRadioButton + ?.buttonRenderer + ?.navigationEndpoint + ?.watchEndpoint, + songs = songsSection + ?.contents + ?.mapNotNull(MusicShelfRenderer.Content::musicResponsiveListItemRenderer) + ?.mapNotNull(Innertube.SongItem::from), + songsEndpoint = songsSection + ?.bottomEndpoint + ?.browseEndpoint, + albums = albumsSection + ?.contents + ?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer) + ?.mapNotNull(Innertube.AlbumItem::from), + albumsEndpoint = albumsSection + ?.header + ?.musicCarouselShelfBasicHeaderRenderer + ?.moreContentButton + ?.buttonRenderer + ?.navigationEndpoint + ?.browseEndpoint, + singles = singlesSection + ?.contents + ?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer) + ?.mapNotNull(Innertube.AlbumItem::from), + singlesEndpoint = singlesSection + ?.header + ?.musicCarouselShelfBasicHeaderRenderer + ?.moreContentButton + ?.buttonRenderer + ?.navigationEndpoint + ?.browseEndpoint, + ) } - - val songsSection = findSectionByTitle("Songs")?.musicShelfRenderer - val albumsSection = findSectionByTitle("Albums")?.musicCarouselShelfRenderer - val singlesSection = findSectionByTitle("Singles")?.musicCarouselShelfRenderer - - Innertube.ArtistPage( - name = response - .header - ?.musicImmersiveHeaderRenderer - ?.title - ?.text, - description = response - .header - ?.musicImmersiveHeaderRenderer - ?.description - ?.text - ?.substringBeforeLast("\n\nFrom Wikipedia"), - thumbnail = response - .header - ?.musicImmersiveHeaderRenderer - ?.thumbnail - ?.musicThumbnailRenderer - ?.thumbnail - ?.thumbnails - ?.getOrNull(0), - shuffleEndpoint = response - .header - ?.musicImmersiveHeaderRenderer - ?.playButton - ?.buttonRenderer - ?.navigationEndpoint - ?.watchEndpoint, - radioEndpoint = response - .header - ?.musicImmersiveHeaderRenderer - ?.startRadioButton - ?.buttonRenderer - ?.navigationEndpoint - ?.watchEndpoint, - songs = songsSection - ?.contents - ?.mapNotNull(MusicShelfRenderer.Content::musicResponsiveListItemRenderer) - ?.mapNotNull(Innertube.SongItem::from), - songsEndpoint = songsSection - ?.bottomEndpoint - ?.browseEndpoint, - albums = albumsSection - ?.contents - ?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer) - ?.mapNotNull(Innertube.AlbumItem::from), - albumsEndpoint = albumsSection - ?.header - ?.musicCarouselShelfBasicHeaderRenderer - ?.moreContentButton - ?.buttonRenderer - ?.navigationEndpoint - ?.browseEndpoint, - singles = singlesSection - ?.contents - ?.mapNotNull(MusicCarouselShelfRenderer.Content::musicTwoRowItemRenderer) - ?.mapNotNull(Innertube.AlbumItem::from), - singlesEndpoint = singlesSection - ?.header - ?.musicCarouselShelfBasicHeaderRenderer - ?.moreContentButton - ?.buttonRenderer - ?.navigationEndpoint - ?.browseEndpoint, - ) -}