From eae8502e2e578e1578e06be96e3cb19a3693c88d Mon Sep 17 00:00:00 2001 From: absidue <48293849+absidue@users.noreply.github.com> Date: Mon, 10 Jun 2024 23:42:15 +0200 Subject: [PATCH] Local API: Extract playlists on the auto-generated "Music" channel --- src/renderer/helpers/api/local.js | 18 ++++++++++++++++++ src/renderer/views/Channel/Channel.js | 23 ++++++++++++++++++++--- src/renderer/views/Playlist/Playlist.js | 2 +- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/renderer/helpers/api/local.js b/src/renderer/helpers/api/local.js index 0b16dfd00edd7..cc3960923e847 100644 --- a/src/renderer/helpers/api/local.js +++ b/src/renderer/helpers/api/local.js @@ -674,6 +674,24 @@ export function parseLocalListPlaylist(playlist, channelId = undefined, channelN } } +/** + * @param {import('youtubei.js').YTNodes.CompactStation} compactStation + * @param {string} channelId + * @param {string} channelName + */ +export function parseLocalCompactStation(compactStation, channelId, channelName) { + return { + type: 'playlist', + dataSource: 'local', + title: compactStation.title.text, + thumbnail: compactStation.thumbnail[1].url, + channelName, + channelId, + playlistId: compactStation.endpoint.payload.playlistId, + videoCount: extractNumberFromString(compactStation.video_count.text) + } +} + /** * @param {YT.Search} response */ diff --git a/src/renderer/views/Channel/Channel.js b/src/renderer/views/Channel/Channel.js index 98a34a3b992a5..91bd4ea0a8e9e 100644 --- a/src/renderer/views/Channel/Channel.js +++ b/src/renderer/views/Channel/Channel.js @@ -38,6 +38,7 @@ import { parseLocalChannelShorts, parseLocalChannelVideos, parseLocalCommunityPosts, + parseLocalCompactStation, parseLocalListPlaylist, parseLocalListVideo, parseLocalSubscriberCount @@ -666,9 +667,25 @@ export default defineComponent({ this.getChannelReleasesLocal() } - if (!this.hideChannelPlaylists && channel.has_playlists) { - tabs.push('playlists') - this.getChannelPlaylistsLocal() + if (!this.hideChannelPlaylists) { + if (channel.has_playlists) { + tabs.push('playlists') + this.getChannelPlaylistsLocal() + } else if (channelId === 'UC-9-kyTW8ZkZNDHQJ6FgpwQ') { + // Special handling for "The Music Channel" (https://youtube.com/music) + tabs.push('playlists') + const playlists = channel.playlists.map(playlist => parseLocalListPlaylist(playlist)) + + const compactStations = channel.memo.get('CompactStation') + if (compactStations) { + for (const compactStation of compactStations) { + playlists.push(parseLocalCompactStation(compactStation, channelId, channelName)) + } + } + + this.showPlaylistSortBy = false + this.latestPlaylists = playlists + } } if (!this.hideChannelCommunity && channel.has_community) { diff --git a/src/renderer/views/Playlist/Playlist.js b/src/renderer/views/Playlist/Playlist.js index 9e10adfe5e8e0..1d5430dde8f30 100644 --- a/src/renderer/views/Playlist/Playlist.js +++ b/src/renderer/views/Playlist/Playlist.js @@ -340,7 +340,7 @@ export default defineComponent({ this.playlistDescription = result.info.description ?? '' this.firstVideoId = result.items[0].id this.playlistThumbnail = result.info.thumbnails[0].url - this.viewCount = extractNumberFromString(result.info.views) + this.viewCount = result.info.views.toLowerCase() === 'no views' ? 0 : extractNumberFromString(result.info.views) this.videoCount = extractNumberFromString(result.info.total_items) this.lastUpdated = result.info.last_updated ?? '' this.channelName = channelName ?? ''