Skip to content

Commit

Permalink
fix(api): api changes from youtube impacting albums and playlists
Browse files Browse the repository at this point in the history
  • Loading branch information
Malopieds committed Jun 22, 2024
1 parent 5185a86 commit 4a609db
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 26 deletions.
45 changes: 21 additions & 24 deletions innertube/src/main/java/com/zionhuang/innertube/YouTube.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import com.zionhuang.innertube.models.YouTubeClient.Companion.WEB
import com.zionhuang.innertube.models.YouTubeClient.Companion.WEB_REMIX
import com.zionhuang.innertube.models.YouTubeLocale
import com.zionhuang.innertube.models.getContinuation
import com.zionhuang.innertube.models.oddElements
import com.zionhuang.innertube.models.response.AccountMenuResponse
import com.zionhuang.innertube.models.response.BrowseResponse
import com.zionhuang.innertube.models.response.GetQueueResponse
Expand All @@ -29,7 +28,6 @@ import com.zionhuang.innertube.models.response.NextResponse
import com.zionhuang.innertube.models.response.PipedResponse
import com.zionhuang.innertube.models.response.PlayerResponse
import com.zionhuang.innertube.models.response.SearchResponse
import com.zionhuang.innertube.models.splitBySeparator
import com.zionhuang.innertube.pages.AlbumPage
import com.zionhuang.innertube.pages.AlbumUtils
import com.zionhuang.innertube.pages.ArtistItemsContinuationPage
Expand Down Expand Up @@ -165,24 +163,23 @@ object YouTube {
album = AlbumItem(
browseId = browseId,
playlistId = playlistId,
title = response.header?.musicDetailHeaderRenderer?.title?.runs?.firstOrNull()?.text!!,
artists = response.header.musicDetailHeaderRenderer.subtitle.runs?.splitBySeparator()?.getOrNull(1)?.oddElements()?.map {
title = response.contents?.twoColumnBrowseResultsRenderer?.tabs?.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()?.musicResponsiveHeaderRenderer?.title?.runs?.firstOrNull()?.text!!,
artists = response.contents.twoColumnBrowseResultsRenderer.tabs.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()?.musicResponsiveHeaderRenderer?.straplineTextOne?.runs?.map {
Artist(
name = it.text,
id = it.navigationEndpoint?.browseEndpoint?.browseId
)
}!!,
year = response.header.musicDetailHeaderRenderer.subtitle.runs.lastOrNull()?.text?.toIntOrNull(),
thumbnail = response.header.musicDetailHeaderRenderer.thumbnail.croppedSquareThumbnailRenderer?.getThumbnailUrl()!!
year = response.contents.twoColumnBrowseResultsRenderer.tabs.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()?.musicResponsiveHeaderRenderer?.subtitle?.runs?.lastOrNull()?.text?.toIntOrNull(),
thumbnail = response.contents.twoColumnBrowseResultsRenderer.tabs.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()?.musicResponsiveHeaderRenderer?.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.lastOrNull()?.url!!,
),
songs = if (withSongs) albumSongs(playlistId).getOrThrow() else emptyList()
)
}

suspend fun albumSongs(playlistId: String): Result<List<SongItem>> = runCatching {
val response = innerTube.browse(WEB_REMIX, "VL$playlistId").body<BrowseResponse>()
response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull()
?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()
response.contents?.twoColumnBrowseResultsRenderer?.secondaryContents?.sectionListRenderer?.contents?.firstOrNull()
?.musicPlaylistShelfRenderer?.contents
?.mapNotNull {
AlbumPage.fromMusicResponsiveListItemRenderer(it.musicResponsiveListItemRenderer)
Expand Down Expand Up @@ -254,35 +251,35 @@ object YouTube {
browseId = "VL$playlistId",
setLogin = true
).body<BrowseResponse>()
val header = response.header?.musicDetailHeaderRenderer ?: response.header?.musicEditablePlaylistDetailHeaderRenderer?.header?.musicDetailHeaderRenderer!!
val base = response.contents?.twoColumnBrowseResultsRenderer?.tabs?.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()?.musicResponsiveHeaderRenderer
println(base?.buttons?.lastOrNull())
PlaylistPage(
playlist = PlaylistItem(
id = playlistId,
title = header.title.runs?.firstOrNull()?.text!!,
author = header.subtitle.runs?.getOrNull(2)?.let {
title = base?.title?.runs?.firstOrNull()?.text!!,
author = base.straplineTextOne?.runs?.firstOrNull()?.let {
Artist(
name = it.text,
id = it.navigationEndpoint?.browseEndpoint?.browseId
)
},
songCountText = header.secondSubtitle.runs?.firstOrNull()?.text,
thumbnail = header.thumbnail.croppedSquareThumbnailRenderer?.getThumbnailUrl()!!,
songCountText = base.secondSubtitle?.runs?.firstOrNull()?.text,
thumbnail = base.thumbnail?.musicThumbnailRenderer?.thumbnail?.thumbnails?.lastOrNull()?.url!!,
playEndpoint = null,
shuffleEndpoint = header.menu.menuRenderer.topLevelButtons?.firstOrNull()?.buttonRenderer?.navigationEndpoint?.watchPlaylistEndpoint!!,
radioEndpoint = header.menu.menuRenderer.items.find {
shuffleEndpoint = base.buttons?.lastOrNull()?.menuRenderer?.items?.firstOrNull()?.menuNavigationItemRenderer?.navigationEndpoint?.watchPlaylistEndpoint!!,
radioEndpoint = base.buttons.lastOrNull()?.menuRenderer?.items!!.find {
it.menuNavigationItemRenderer?.icon?.iconType == "MIX"
}?.menuNavigationItemRenderer?.navigationEndpoint?.watchPlaylistEndpoint!!
),
songs = response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull()
?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()
?.musicPlaylistShelfRenderer?.contents?.mapNotNull {
songs = response.contents.twoColumnBrowseResultsRenderer.secondaryContents?.sectionListRenderer?.contents
?.firstOrNull()?.musicPlaylistShelfRenderer?.contents?.mapNotNull {
PlaylistPage.fromMusicResponsiveListItemRenderer(it.musicResponsiveListItemRenderer)
}!!,
songsContinuation = response.contents.singleColumnBrowseResultsRenderer.tabs.firstOrNull()
?.tabRenderer?.content?.sectionListRenderer?.contents?.firstOrNull()
songsContinuation = response.contents.twoColumnBrowseResultsRenderer.secondaryContents.sectionListRenderer
.contents.firstOrNull()
?.musicPlaylistShelfRenderer?.continuations?.getContinuation(),
continuation = response.contents.singleColumnBrowseResultsRenderer.tabs.firstOrNull()
?.tabRenderer?.content?.sectionListRenderer?.continuations?.getContinuation()
continuation = response.contents.twoColumnBrowseResultsRenderer.secondaryContents.sectionListRenderer
.continuations?.getContinuation()
)
}

Expand Down Expand Up @@ -352,7 +349,7 @@ object YouTube {
val continuation = response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.continuations?.firstOrNull()?.nextContinuationData?.continuation
response.contents?.singleColumnBrowseResultsRenderer?.tabs?.firstOrNull()?.tabRenderer?.content?.sectionListRenderer?.contents!!
.mapNotNull { it.musicCarouselShelfRenderer }
.mapNotNull {
.map {
HomePlayList.fromMusicCarouselShelfRenderer(it, continuation)
}
}
Expand Down Expand Up @@ -400,7 +397,7 @@ object YouTube {
val newContinuation = response.continuationContents?.sectionListContinuation?.continuations?.firstOrNull()?.nextContinuationData?.continuation
response.continuationContents?.sectionListContinuation?.contents!!
.mapNotNull { it.musicCarouselShelfRenderer }
.mapNotNull {
.map {
HomePlayList.fromMusicCarouselShelfRenderer(it, newContinuation)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ data class Menu(
) {
@Serializable
data class MenuRenderer(
val items: List<Item>,
val items: List<Item>?,
val topLevelButtons: List<TopLevelButton>?,
) {
@Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.zionhuang.innertube.models

import com.zionhuang.innertube.models.response.BrowseResponse
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNames
Expand Down Expand Up @@ -44,5 +45,6 @@ data class SectionListRenderer(
val musicPlaylistShelfRenderer: MusicPlaylistShelfRenderer?,
val musicDescriptionShelfRenderer: MusicDescriptionShelfRenderer?,
val gridRenderer: GridRenderer?,
val musicResponsiveHeaderRenderer: BrowseResponse.Header.MusicHeaderRenderer?,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.zionhuang.innertube.models.Runs
import com.zionhuang.innertube.models.SectionListRenderer
import com.zionhuang.innertube.models.Tabs
import com.zionhuang.innertube.models.ThumbnailRenderer
import com.zionhuang.innertube.models.Thumbnails
import kotlinx.serialization.Serializable

@Serializable
Expand All @@ -18,13 +19,32 @@ data class BrowseResponse(
val header: Header?,
val microformat: Microformat?,
val responseContext: ResponseContext,
val background: MusicThumbnailRenderer?
) {
@Serializable
data class Contents(
val singleColumnBrowseResultsRenderer: Tabs?,
val twoColumnBrowseResultsRenderer: TwoColumnBrowseResultsRenderer?,
val sectionListRenderer: SectionListRenderer?,
)

@Serializable
data class TwoColumnBrowseResultsRenderer(
val tabs: List<Tabs.Tab?>?,
val secondaryContents: SecondaryContents?,
)

@Serializable
data class SecondaryContents(
val sectionListRenderer: SectionListRenderer?
)

@Serializable
data class MusicThumbnailRenderer(
val thumbnail: Thumbnails?,
val thumbnailCrop: String?,
)

@Serializable
data class ContinuationContents(
val sectionListContinuation: SectionListContinuation?,
Expand Down Expand Up @@ -87,10 +107,31 @@ data class BrowseResponse(
val foregroundThumbnail: ThumbnailRenderer,
val thumbnail: ThumbnailRenderer?,
)
@Serializable
data class Buttons(
val menuRenderer: Menu.MenuRenderer?,
)

@Serializable
data class MusicHeaderRenderer(
val title: Runs,
val buttons: List<Buttons>?,
val title: Runs?,
val thumbnail: MusicThumbnailRenderer?,
val subtitle: Runs?,
val secondSubtitle: Runs?,
val straplineTextOne: Runs?,
val straplineThumbnail: MusicThumbnailRenderer?
)

@Serializable
data class MusicThumbnail(
val url: String?
)

@Serializable
data class MusicThumbnailRenderer(
val musicThumbnailRenderer: BrowseResponse.MusicThumbnailRenderer,
val thumbnails: List<MusicThumbnail>?
)
}

Expand Down

0 comments on commit 4a609db

Please sign in to comment.