fix: support MusicCardShelfRenderer (music search results)

This commit is contained in:
ThetaDev 2023-04-09 11:51:19 +02:00
parent 0164fac2e0
commit b7ecd1e4a3
7 changed files with 9516 additions and 3 deletions

View file

@ -255,6 +255,13 @@ impl MapResponse<MusicSearchResult> for response::MusicSearch {
}
}
}
response::music_search::ItemSection::MusicCardShelfRenderer(card) => {
if let Some(etype) = mapper.map_card(card) {
if !order.contains(&etype) {
order.push(etype);
}
}
}
response::music_search::ItemSection::ItemSectionRenderer { mut contents } => {
if let Some(corrected) = contents.try_swap_remove(0) {
corrected_query = Some(corrected.showing_results_for_renderer.corrected_query)
@ -308,6 +315,9 @@ impl<T: FromYtItem> MapResponse<MusicSearchFiltered<T>> for response::MusicSearc
ctoken = Some(cont.next_continuation_data.continuation);
}
}
response::music_search::ItemSection::MusicCardShelfRenderer(card) => {
mapper.map_card(card);
}
response::music_search::ItemSection::ItemSectionRenderer { mut contents } => {
if let Some(corrected) = contents.try_swap_remove(0) {
corrected_query = Some(corrected.showing_results_for_renderer.corrected_query)
@ -394,6 +404,7 @@ mod tests {
#[case::default("default")]
#[case::typo("typo")]
#[case::radio("radio")]
#[case::radio("artist")]
fn map_music_search_main(#[case] name: &str) {
let json_path = path!(*TESTFILES / "music_search" / format!("main_{name}.json"));
let json_file = File::open(json_path).unwrap();

View file

@ -31,6 +31,8 @@ pub(crate) enum ItemSection {
None,
}
/// MusicShelf represents the standard, vertical list of music items
/// (used in search results, playlist, album).
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -49,6 +51,8 @@ pub(crate) struct MusicShelf {
pub bottom_endpoint: Option<BrowseEndpointWrap>,
}
/// MusicCarouselShelf represents a horizontal list of music items displayed with
/// large covers.
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -58,6 +62,24 @@ pub(crate) struct MusicCarouselShelf {
pub contents: MapResult<Vec<MusicResponseItem>>,
}
/// MusicCardShelf is used to display the top search result. It contains
/// one main item and optionally a list of sub-items (like an artist + top tracks).
#[serde_as]
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct MusicCardShelf {
#[serde_as(as = "Text")]
pub title: String,
pub on_tap: NavigationEndpoint,
#[serde(default)]
pub subtitle: TextComponents,
#[serde(default)]
pub thumbnail: MusicThumbnailRenderer,
#[serde(default)]
#[serde_as(as = "VecLogError<_>")]
pub contents: MapResult<Vec<MusicResponseItem>>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) enum MusicResponseItem {
@ -888,6 +910,120 @@ impl MusicListMapper {
etype
}
pub fn map_card(&mut self, card: MusicCardShelf) -> Option<MusicItemType> {
/*
"Artist" "" "<subscriber count>"
"Album" "" "<artist>"
"Song" "" "<artist>" "" "<album>" "" "<duration>"
"Video" "" "<artist>" "" "<view count>" "" "<duration>"
"Playlist" "" "<author>" "" "<track count>" (guessed)
*/
let mut subtitle_parts = card.subtitle.split(util::DOT_SEPARATOR).into_iter();
let subtitle_p1 = subtitle_parts.next();
let subtitle_p2 = subtitle_parts.next();
let subtitle_p3 = subtitle_parts.next();
let subtitle_p4 = subtitle_parts.next();
let item_type = match card.on_tap.music_page() {
Some((page_type, id)) => match page_type {
MusicPageType::Artist => {
let subscriber_count = subtitle_p2
.and_then(|p| util::parse_large_numstr(p.first_str(), self.lang));
self.items.push(MusicItem::Artist(ArtistItem {
id,
name: card.title,
avatar: card.thumbnail.into(),
subscriber_count,
}));
Some(MusicItemType::Artist)
}
MusicPageType::Album => {
let (artists, by_va) = map_artists(subtitle_p2);
let album_type = subtitle_p1
.map(|p| map_album_type(p.first_str(), self.lang))
.unwrap_or_default();
self.items.push(MusicItem::Album(AlbumItem {
id,
name: card.title,
cover: card.thumbnail.into(),
artist_id: artists.first().and_then(|a| a.id.to_owned()),
artists,
album_type,
year: subtitle_p3.and_then(|y| util::parse_numeric(y.first_str()).ok()),
by_va,
}));
Some(MusicItemType::Album)
}
MusicPageType::Track { is_video } => {
let (artists, by_va) = map_artists(subtitle_p2);
let duration =
subtitle_p4.and_then(|p| util::parse_video_length(p.first_str()));
let (album, view_count) = if is_video {
(
None,
subtitle_p3
.and_then(|p| util::parse_large_numstr(p.first_str(), self.lang)),
)
} else {
(
subtitle_p3.and_then(|p| {
p.0.into_iter().find_map(|c| AlbumId::try_from(c).ok())
}),
None,
)
};
self.items.push(MusicItem::Track(TrackItem {
id,
name: card.title,
duration,
cover: card.thumbnail.into(),
artist_id: artists.first().and_then(|a| a.id.to_owned()),
artists,
album,
view_count,
is_video,
track_nr: None,
by_va,
}));
Some(MusicItemType::Track)
}
MusicPageType::Playlist => {
let from_ytm = subtitle_p2
.as_ref()
.map(|p| p.first_str() == util::YT_MUSIC_NAME)
.unwrap_or(true);
let channel = subtitle_p2
.and_then(|p| p.0.into_iter().find_map(|c| ChannelId::try_from(c).ok()));
let track_count =
subtitle_p3.and_then(|p| util::parse_numeric(p.first_str()).ok());
self.items.push(MusicItem::Playlist(MusicPlaylistItem {
id,
name: card.title,
thumbnail: card.thumbnail.into(),
channel,
track_count,
from_ytm,
}));
Some(MusicItemType::Playlist)
}
MusicPageType::None => None,
},
None => {
self.warnings
.push("could not determine item type".to_owned());
None
}
};
self.map_response(card.contents);
item_type
}
pub fn add_item(&mut self, item: MusicItem) {
self.items.push(item);
}

View file

@ -4,7 +4,7 @@ use serde_with::{rust::deserialize_ignore_any, serde_as, VecSkipError};
use crate::serializer::text::Text;
use super::{
music_item::{ListMusicItem, MusicShelf},
music_item::{ListMusicItem, MusicCardShelf, MusicShelf},
ContentsRenderer, SectionList, Tab,
};
@ -37,6 +37,7 @@ pub(crate) struct Contents {
#[serde(rename_all = "camelCase")]
pub(crate) enum ItemSection {
MusicShelfRenderer(MusicShelf),
MusicCardShelfRenderer(MusicCardShelf),
ItemSectionRenderer {
#[serde_as(as = "VecSkipError<_>")]
contents: Vec<ShowingResultsFor>,

View file

@ -0,0 +1,575 @@
---
source: src/client/music_search.rs
expression: map_res.c
---
MusicSearchResult(
tracks: [
TrackItem(
id: "3YgtjHZyCIQ",
name: "Anti-Hero",
duration: Some(201),
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/YT8q7RwmbNVf7EcjSii-T5vm7FZI7_mSb_KYvhfKqvKRWdCTB-mzr2jLZCPwYqER3wHFXhuEQKTKmUCJ=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/YT8q7RwmbNVf7EcjSii-T5vm7FZI7_mSb_KYvhfKqvKRWdCTB-mzr2jLZCPwYqER3wHFXhuEQKTKmUCJ=w120-h120-l90-rj",
width: 120,
height: 120,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: Some(AlbumId(
id: "MPREb_MOJF3UvLsif",
name: "Midnights (3am Edition)",
)),
view_count: None,
is_video: false,
track_nr: None,
by_va: false,
),
TrackItem(
id: "aZ1hziFhj1o",
name: "Love Story",
duration: Some(235),
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/YEcmx-25aRBMaKNTvCx17QboP0KCJq2jqKdjpjLImqA60wWE2AZV_ZdQa417ZEmAkK7ipsEt1m0DEI-Z9A=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/YEcmx-25aRBMaKNTvCx17QboP0KCJq2jqKdjpjLImqA60wWE2AZV_ZdQa417ZEmAkK7ipsEt1m0DEI-Z9A=w120-h120-l90-rj",
width: 120,
height: 120,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: Some(AlbumId(
id: "MPREb_u721jSRXVRq",
name: "Fearless (Platinum Edition)",
)),
view_count: None,
is_video: false,
track_nr: None,
by_va: false,
),
TrackItem(
id: "VmBoTeLsKfs",
name: "I Knew You Were Trouble.",
duration: Some(220),
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/_HJASc9B_QXn2yoUBn4ZLkn6ka8o_CYX4hNT3HQSeIRcqStiJU15VVtOwlaoFV4KqhJK3d-0W0sw3yQ=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/_HJASc9B_QXn2yoUBn4ZLkn6ka8o_CYX4hNT3HQSeIRcqStiJU15VVtOwlaoFV4KqhJK3d-0W0sw3yQ=w120-h120-l90-rj",
width: 120,
height: 120,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: Some(AlbumId(
id: "MPREb_6FbAboRIFSX",
name: "Red",
)),
view_count: None,
is_video: false,
track_nr: None,
by_va: false,
),
TrackItem(
id: "65Q7EdWnjqM",
name: "We Are Never Ever Getting Back Together",
duration: Some(194),
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/_HJASc9B_QXn2yoUBn4ZLkn6ka8o_CYX4hNT3HQSeIRcqStiJU15VVtOwlaoFV4KqhJK3d-0W0sw3yQ=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/_HJASc9B_QXn2yoUBn4ZLkn6ka8o_CYX4hNT3HQSeIRcqStiJU15VVtOwlaoFV4KqhJK3d-0W0sw3yQ=w120-h120-l90-rj",
width: 120,
height: 120,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: Some(AlbumId(
id: "MPREb_6FbAboRIFSX",
name: "Red",
)),
view_count: None,
is_video: false,
track_nr: None,
by_va: false,
),
TrackItem(
id: "EL72UcDZLSk",
name: "Midnight Rain",
duration: Some(175),
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/omCs21jqwK4Ss_VZxPFKwQP5z0UY0vi_8gXu4XNxHKDgE-GHYHWkIw80XR1uzFgdyhM3PvVUZeZ8iAfF=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/omCs21jqwK4Ss_VZxPFKwQP5z0UY0vi_8gXu4XNxHKDgE-GHYHWkIw80XR1uzFgdyhM3PvVUZeZ8iAfF=w120-h120-l90-rj",
width: 120,
height: 120,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: Some(AlbumId(
id: "MPREb_z0ABWl3jaT0",
name: "Midnights",
)),
view_count: None,
is_video: false,
track_nr: None,
by_va: false,
),
TrackItem(
id: "b1kbLwvqugk",
name: "Anti-Hero",
duration: Some(310),
cover: [
Thumbnail(
url: "https://i.ytimg.com/vi/b1kbLwvqugk/sddefault.jpg?sqp=-oaymwEWCJADEOEBIAQqCghqEJQEGHgg6AJIWg&rs=AMzJL3mTWxIS76F_mpp6z63jfh_wtth9RA",
width: 400,
height: 225,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: None,
view_count: Some(123000000),
is_video: true,
track_nr: None,
by_va: false,
),
TrackItem(
id: "3tmd-ClpJxA",
name: "Look What You Made Me Do",
duration: Some(256),
cover: [
Thumbnail(
url: "https://i.ytimg.com/vi/3tmd-ClpJxA/sddefault.jpg?sqp=-oaymwEWCJADEOEBIAQqCghqEJQEGHgg6AJIWg&rs=AMzJL3nNkqC6yuXrIsm7St2zBSUzvuji-Q",
width: 400,
height: 225,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: None,
view_count: Some(1300000000),
is_video: true,
track_nr: None,
by_va: false,
),
TrackItem(
id: "FuXNumBwDOM",
name: "ME! (feat. Brendon Urie)",
duration: Some(249),
cover: [
Thumbnail(
url: "https://i.ytimg.com/vi/FuXNumBwDOM/sddefault.jpg?sqp=-oaymwEWCJADEOEBIAQqCghqEJQEGHgg6AJIWg&rs=AMzJL3lT7i_HDpIpUM2j9RoGdVL7NBDh4A",
width: 400,
height: 225,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album: None,
view_count: Some(402000000),
is_video: true,
track_nr: None,
by_va: false,
),
],
albums: [
AlbumItem(
id: "MPREb_l2IU1O3l6QK",
name: "Lavender Haze (Acoustic Version)",
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/YmOLcfKGBXqhvqc-JLhpN03MuLDEYReKP_hrTHPp1mE8uA5s1r7vVqrwwt7hoWNI3_PixnuFPzSTwRM=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/YmOLcfKGBXqhvqc-JLhpN03MuLDEYReKP_hrTHPp1mE8uA5s1r7vVqrwwt7hoWNI3_PixnuFPzSTwRM=w120-h120-l90-rj",
width: 120,
height: 120,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/YmOLcfKGBXqhvqc-JLhpN03MuLDEYReKP_hrTHPp1mE8uA5s1r7vVqrwwt7hoWNI3_PixnuFPzSTwRM=w226-h226-l90-rj",
width: 226,
height: 226,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/YmOLcfKGBXqhvqc-JLhpN03MuLDEYReKP_hrTHPp1mE8uA5s1r7vVqrwwt7hoWNI3_PixnuFPzSTwRM=w544-h544-l90-rj",
width: 544,
height: 544,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album_type: Single,
year: Some(2023),
by_va: false,
),
AlbumItem(
id: "MPREb_BiCQyyofUtj",
name: "Eyes Open (Taylor\'s Version)",
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/d_T3L3Ed5ynZLMVs0Ely4aqTfBZ-y9P9azzlLuKvT2re1QQuxqTxRPoSv082zBOBWmXZZRZKqIFbR7YI=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/d_T3L3Ed5ynZLMVs0Ely4aqTfBZ-y9P9azzlLuKvT2re1QQuxqTxRPoSv082zBOBWmXZZRZKqIFbR7YI=w120-h120-l90-rj",
width: 120,
height: 120,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/d_T3L3Ed5ynZLMVs0Ely4aqTfBZ-y9P9azzlLuKvT2re1QQuxqTxRPoSv082zBOBWmXZZRZKqIFbR7YI=w226-h226-l90-rj",
width: 226,
height: 226,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/d_T3L3Ed5ynZLMVs0Ely4aqTfBZ-y9P9azzlLuKvT2re1QQuxqTxRPoSv082zBOBWmXZZRZKqIFbR7YI=w544-h544-l90-rj",
width: 544,
height: 544,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album_type: Single,
year: Some(2021),
by_va: false,
),
AlbumItem(
id: "MPREb_aTnRAnnwbvO",
name: "The More Lover Chapter",
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/wdHdhi2eTDZpnLaBV0y-sVDpOdxcpyzKCC_ivCcKpprhMoeJ4alAW3__PzTttGfR5yhX8vGsHs8u8upz=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/wdHdhi2eTDZpnLaBV0y-sVDpOdxcpyzKCC_ivCcKpprhMoeJ4alAW3__PzTttGfR5yhX8vGsHs8u8upz=w120-h120-l90-rj",
width: 120,
height: 120,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/wdHdhi2eTDZpnLaBV0y-sVDpOdxcpyzKCC_ivCcKpprhMoeJ4alAW3__PzTttGfR5yhX8vGsHs8u8upz=w226-h226-l90-rj",
width: 226,
height: 226,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/wdHdhi2eTDZpnLaBV0y-sVDpOdxcpyzKCC_ivCcKpprhMoeJ4alAW3__PzTttGfR5yhX8vGsHs8u8upz=w544-h544-l90-rj",
width: 544,
height: 544,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album_type: Ep,
year: Some(2019),
by_va: false,
),
AlbumItem(
id: "MPREb_UGeXP8tVTb5",
name: "All Of The Girls You Loved Before",
cover: [
Thumbnail(
url: "https://lh3.googleusercontent.com/Dbm6JTTRFJbiMNjrqRTIDircS8Jaj8MrJhOHb_d2a-rH6YuuOUwlxXh6vzQ4aKe0mHHZCAXVML-PcBLo=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/Dbm6JTTRFJbiMNjrqRTIDircS8Jaj8MrJhOHb_d2a-rH6YuuOUwlxXh6vzQ4aKe0mHHZCAXVML-PcBLo=w120-h120-l90-rj",
width: 120,
height: 120,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/Dbm6JTTRFJbiMNjrqRTIDircS8Jaj8MrJhOHb_d2a-rH6YuuOUwlxXh6vzQ4aKe0mHHZCAXVML-PcBLo=w226-h226-l90-rj",
width: 226,
height: 226,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/Dbm6JTTRFJbiMNjrqRTIDircS8Jaj8MrJhOHb_d2a-rH6YuuOUwlxXh6vzQ4aKe0mHHZCAXVML-PcBLo=w544-h544-l90-rj",
width: 544,
height: 544,
),
],
artists: [
ArtistId(
id: Some("UCPC0L1d253x-KuMNwa05TpA"),
name: "Taylor Swift",
),
],
artist_id: Some("UCPC0L1d253x-KuMNwa05TpA"),
album_type: Single,
year: Some(2019),
by_va: false,
),
],
artists: [
ArtistItem(
id: "UCPC0L1d253x-KuMNwa05TpA",
name: "Taylor Swift",
avatar: [
Thumbnail(
url: "https://lh3.googleusercontent.com/U1cI80giSCUuNYx3zkRPt_AWytN1qFMlQoL5F7kTZeFzfIMmfHJYLJchX3BxeDLglE9MeVYp4OlN5Xc=w60-h60-p-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/U1cI80giSCUuNYx3zkRPt_AWytN1qFMlQoL5F7kTZeFzfIMmfHJYLJchX3BxeDLglE9MeVYp4OlN5Xc=w120-h120-p-l90-rj",
width: 120,
height: 120,
),
],
subscriber_count: Some(51400000),
),
ArtistItem(
id: "UCprAFmT0C6O4X0ToEXpeFTQ",
name: "Kendrick Lamar",
avatar: [
Thumbnail(
url: "https://lh3.googleusercontent.com/hMjzHmIuTV0XPlvRSjl3wMR6NP-uF-fqF6kkandkFX-hEVp6d3tw-FQG9_smAq0tFwNBT6QLQR-Hkwge=w60-h60-p-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/hMjzHmIuTV0XPlvRSjl3wMR6NP-uF-fqF6kkandkFX-hEVp6d3tw-FQG9_smAq0tFwNBT6QLQR-Hkwge=w120-h120-p-l90-rj",
width: 120,
height: 120,
),
],
subscriber_count: Some(11900000),
),
ArtistItem(
id: "UCYR9erHSNBPjjNswR4FrMaw",
name: "ZAYN",
avatar: [
Thumbnail(
url: "https://lh3.googleusercontent.com/x_OLwEjNh74QScfVbc3ejrbxjjG3WFe5CfVrO9KlIT_W2VvHpVC-orFzg-LF2kVYsBGK2YOA5JvUsVE=w60-h60-p-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/x_OLwEjNh74QScfVbc3ejrbxjjG3WFe5CfVrO9KlIT_W2VvHpVC-orFzg-LF2kVYsBGK2YOA5JvUsVE=w120-h120-p-l90-rj",
width: 120,
height: 120,
),
],
subscriber_count: Some(15300000),
),
ArtistItem(
id: "UCH9AZnGOJebPl3RiVGgpkKA",
name: "I Prevail",
avatar: [
Thumbnail(
url: "https://lh3.googleusercontent.com/BsYJ-FyJ4DuXe3yLZ_C3gZREpGAOJ4g1s779ZOF5XqccwJ0ahXfiFujd8dIBkaPjsC6RhW1A6iNgVw=w60-h60-p-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/BsYJ-FyJ4DuXe3yLZ_C3gZREpGAOJ4g1s779ZOF5XqccwJ0ahXfiFujd8dIBkaPjsC6RhW1A6iNgVw=w120-h120-p-l90-rj",
width: 120,
height: 120,
),
],
subscriber_count: Some(847000),
),
],
playlists: [
MusicPlaylistItem(
id: "RDCLAK5uy_k1272v-yXtLJm7gmMiAxjOl-vh5aEC11A",
name: "Presenting Taylor Swift",
thumbnail: [
Thumbnail(
url: "https://lh3.googleusercontent.com/1Z1x27acd-hAcqXUfF8pTtYrlK6bzuW5LERhwJOGKZ-i3IsnR9UGBiIetLRagRE-PtTw9MlCNQ7kkM0=w60-h60-l90-rj",
width: 60,
height: 60,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/1Z1x27acd-hAcqXUfF8pTtYrlK6bzuW5LERhwJOGKZ-i3IsnR9UGBiIetLRagRE-PtTw9MlCNQ7kkM0=w120-h120-l90-rj",
width: 120,
height: 120,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/1Z1x27acd-hAcqXUfF8pTtYrlK6bzuW5LERhwJOGKZ-i3IsnR9UGBiIetLRagRE-PtTw9MlCNQ7kkM0=w226-h226-l90-rj",
width: 226,
height: 226,
),
Thumbnail(
url: "https://lh3.googleusercontent.com/1Z1x27acd-hAcqXUfF8pTtYrlK6bzuW5LERhwJOGKZ-i3IsnR9UGBiIetLRagRE-PtTw9MlCNQ7kkM0=w544-h544-l90-rj",
width: 544,
height: 544,
),
],
channel: None,
track_count: Some(72),
from_ytm: true,
),
MusicPlaylistItem(
id: "PLMtpqbF01MkVhY0_Z4Afg1m3xCKa2kNBf",
name: "All Taylor Swift Songs",
thumbnail: [
Thumbnail(
url: "https://yt3.ggpht.com/mANLpVYRbRYvB5AxT5PjOBkK7jDSuGs8slNDTidtTII6xoXgZAXloGaN6JOIDfN5lTc3TZ5yyxw=s192",
width: 192,
height: 192,
),
Thumbnail(
url: "https://yt3.ggpht.com/mANLpVYRbRYvB5AxT5PjOBkK7jDSuGs8slNDTidtTII6xoXgZAXloGaN6JOIDfN5lTc3TZ5yyxw=s576",
width: 576,
height: 576,
),
Thumbnail(
url: "https://yt3.ggpht.com/mANLpVYRbRYvB5AxT5PjOBkK7jDSuGs8slNDTidtTII6xoXgZAXloGaN6JOIDfN5lTc3TZ5yyxw=s1200",
width: 1200,
height: 1200,
),
],
channel: Some(ChannelId(
id: "UC0tDRlJxvcgAhXiHwZm4wcQ",
name: "Elyssa Hamilton",
)),
track_count: Some(155),
from_ytm: false,
),
MusicPlaylistItem(
id: "PLsK_PMdOWOamZphWwqin4A1vw9IJQ0bxC",
name: "Taylor Swift The Eras Tour Setlist (Lyrics and Music Videos)",
thumbnail: [
Thumbnail(
url: "https://yt3.googleusercontent.com/1ayovXXUII1Meb91J5iTGgsinZz7AXKXj_cLSRSzUvsaBC5gBesgJio8M1cxyo4QZX8hZyQzknA=s192",
width: 192,
height: 192,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/1ayovXXUII1Meb91J5iTGgsinZz7AXKXj_cLSRSzUvsaBC5gBesgJio8M1cxyo4QZX8hZyQzknA=s576",
width: 576,
height: 576,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/1ayovXXUII1Meb91J5iTGgsinZz7AXKXj_cLSRSzUvsaBC5gBesgJio8M1cxyo4QZX8hZyQzknA=s1200",
width: 1200,
height: 1200,
),
],
channel: Some(ChannelId(
id: "UCNpa7-_q_H17TGFfUccs6mw",
name: "Spencer Ramirez Salas",
)),
track_count: Some(43),
from_ytm: false,
),
MusicPlaylistItem(
id: "PL_MyZJz846m0QstXAZMmDUJAEHw6je6-_",
name: "Taylor Swift - Top Tracks 2022 Playlist",
thumbnail: [
Thumbnail(
url: "https://yt3.googleusercontent.com/N1g1refv6sTYiWO2Zbgjoo1eKD8rdEwntTY1L7cFfJV1coqaISjNVajG-a4ybUcjQhGGioJbUf0=s192",
width: 192,
height: 192,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/N1g1refv6sTYiWO2Zbgjoo1eKD8rdEwntTY1L7cFfJV1coqaISjNVajG-a4ybUcjQhGGioJbUf0=s576",
width: 576,
height: 576,
),
Thumbnail(
url: "https://yt3.googleusercontent.com/N1g1refv6sTYiWO2Zbgjoo1eKD8rdEwntTY1L7cFfJV1coqaISjNVajG-a4ybUcjQhGGioJbUf0=s1200",
width: 1200,
height: 1200,
),
],
channel: Some(ChannelId(
id: "UCrESzB-SUekVTY3QI3Jfqlg",
name: "N.J. Music",
)),
track_count: Some(96),
from_ytm: false,
),
],
corrected_query: None,
order: [
Artist,
Track,
Album,
Playlist,
],
)