diff --git a/codegen/src/abtest.rs b/codegen/src/abtest.rs index 8852cb9..eeb95d8 100644 --- a/codegen/src/abtest.rs +++ b/codegen/src/abtest.rs @@ -35,6 +35,7 @@ pub enum ABTest { MusicPlaylistTwoColumn = 13, CommentsFrameworkUpdate = 14, ChannelShortsLockup = 15, + PlaylistPageHeader = 16, } /// List of active A/B tests that are run when none is manually specified @@ -112,6 +113,7 @@ pub async fn run_test( ABTest::MusicPlaylistTwoColumn => music_playlist_two_column(&query).await, ABTest::CommentsFrameworkUpdate => comments_framework_update(&query).await, ABTest::ChannelShortsLockup => channel_shorts_lockup(&query).await, + ABTest::PlaylistPageHeader => playlist_page_header_renderer(&query).await, } .unwrap(); pb.inc(1); @@ -382,3 +384,20 @@ pub async fn channel_shorts_lockup(rp: &RustyPipeQuery) -> Result { .unwrap(); Ok(res.contains("\"shortsLockupViewModel\"")) } + +pub async fn playlist_page_header_renderer(rp: &RustyPipeQuery) -> Result { + let id = "VLPLZN_exA7d4RVmCQrG5VlWIjMOkMFZVVOc"; + let res = rp + .raw( + ClientType::Desktop, + "browse", + &QBrowse { + context: rp.get_context(ClientType::Desktop, true, None).await, + browse_id: id, + params: None, + }, + ) + .await + .unwrap(); + Ok(res.contains("\"pageHeaderRenderer\"")) +} diff --git a/codegen/src/collect_chan_prefixes.rs b/codegen/src/collect_chan_prefixes.rs new file mode 100644 index 0000000..0d15bba --- /dev/null +++ b/codegen/src/collect_chan_prefixes.rs @@ -0,0 +1,75 @@ +use std::{collections::BTreeMap, fs::File, io::BufReader}; + +use path_macro::path; +use rustypipe::{ + client::RustyPipe, + param::{Language, LANGUAGES}, +}; +use serde::{Deserialize, Serialize}; + +use crate::util::{self, DICT_DIR}; + +#[derive(Debug, Serialize, Deserialize)] +struct Entry { + prefix: String, + suffix: String, +} + +pub async fn collect_chan_prefixes() { + let cname = "kiernanchrisman"; + let json_path = path!(*DICT_DIR / "chan_prefixes.json"); + let mut res = BTreeMap::new(); + + let rp = RustyPipe::new(); + + for lang in LANGUAGES { + let playlist = rp + .query() + .lang(lang) + .playlist("PLZN_exA7d4RVmCQrG5VlWIjMOkMFZVVOc") + .await + .unwrap(); + let n = playlist.channel.unwrap().name; + let offset = n.find(cname).unwrap(); + let prefix = &n[..offset]; + let suffix = &n[(offset + cname.len())..]; + + res.insert( + lang, + Entry { + prefix: prefix.to_owned(), + suffix: suffix.to_owned(), + }, + ); + } + + let file = File::create(json_path).unwrap(); + serde_json::to_writer_pretty(file, &res).unwrap(); +} + +pub fn write_samples_to_dict() { + let json_path = path!(*DICT_DIR / "chan_prefixes.json"); + + let json_file = File::open(json_path).unwrap(); + let collected: BTreeMap = + serde_json::from_reader(BufReader::new(json_file)).unwrap(); + let mut dict = util::read_dict(); + let langs = dict.keys().copied().collect::>(); + + for lang in langs { + let dict_entry = dict.entry(lang).or_default(); + + let e = collected.get(&lang).unwrap(); + dict_entry.chan_prefix = e.prefix.trim().to_owned(); + dict_entry.chan_suffix = e.suffix.trim().to_owned(); + + for lang in &dict_entry.equivalent { + let ee = collected.get(lang).unwrap(); + if ee.prefix != e.prefix || ee.suffix != e.suffix { + panic!("equivalent lang conflict, lang: {lang}"); + } + } + } + + util::write_dict(dict); +} diff --git a/codegen/src/gen_dictionary.rs b/codegen/src/gen_dictionary.rs index 452a47b..140f519 100644 --- a/codegen/src/gen_dictionary.rs +++ b/codegen/src/gen_dictionary.rs @@ -85,6 +85,10 @@ pub(crate) struct Entry { /// /// Format: Parsed text -> Album type pub album_types: phf::Map<&'static str, AlbumType>, + /// Channel name prefix on playlist pages (e.g. `by`) + pub chan_prefix: &'static str, + /// Channel name suffix on playlist pages + pub chan_suffix: &'static str, } "#; @@ -180,8 +184,8 @@ pub(crate) fn entry(lang: Language) -> Entry { .to_string() .replace('\n', "\n "); - write!(code_timeago_tokens, "{} => Entry {{\n timeago_tokens: {},\n date_order: {},\n months: {},\n timeago_nd_tokens: {},\n comma_decimal: {:?},\n number_tokens: {},\n number_nd_tokens: {},\n album_types: {},\n }},\n ", - selector, code_ta_tokens, date_order, code_months, code_ta_nd_tokens, entry.comma_decimal, code_number_tokens, code_number_nd_tokens, code_album_types).unwrap(); + write!(code_timeago_tokens, "{} => Entry {{\n timeago_tokens: {},\n date_order: {},\n months: {},\n timeago_nd_tokens: {},\n comma_decimal: {:?},\n number_tokens: {},\n number_nd_tokens: {},\n album_types: {},\n chan_prefix: {:?},\n chan_suffix: {:?},\n }},\n ", + selector, code_ta_tokens, date_order, code_months, code_ta_nd_tokens, entry.comma_decimal, code_number_tokens, code_number_nd_tokens, code_album_types, entry.chan_prefix, entry.chan_suffix).unwrap(); } code_timeago_tokens = code_timeago_tokens.trim_end().to_owned() + "\n }\n}\n"; diff --git a/codegen/src/main.rs b/codegen/src/main.rs index 7c8a5f2..b2dee3e 100644 --- a/codegen/src/main.rs +++ b/codegen/src/main.rs @@ -2,6 +2,7 @@ mod abtest; mod collect_album_types; +mod collect_chan_prefixes; mod collect_large_numbers; mod collect_playlist_dates; mod collect_video_dates; @@ -29,10 +30,12 @@ enum Commands { CollectAlbumTypes, CollectVideoDurations, CollectVideoDates, + CollectChanPrefixes, ParsePlaylistDates, ParseLargeNumbers, ParseAlbumTypes, ParseVideoDurations, + ParseChanPrefixes, GenLocales, GenDict, DownloadTestfiles, @@ -65,10 +68,14 @@ async fn main() { Commands::CollectVideoDates => { collect_video_dates::collect_video_dates(cli.concurrency).await; } + Commands::CollectChanPrefixes => { + collect_chan_prefixes::collect_chan_prefixes().await; + } Commands::ParsePlaylistDates => collect_playlist_dates::write_samples_to_dict(), Commands::ParseLargeNumbers => collect_large_numbers::write_samples_to_dict(), Commands::ParseAlbumTypes => collect_album_types::write_samples_to_dict(), Commands::ParseVideoDurations => collect_video_durations::parse_video_durations(), + Commands::ParseChanPrefixes => collect_chan_prefixes::write_samples_to_dict(), Commands::GenLocales => { gen_locales::generate_locales().await; } diff --git a/codegen/src/model.rs b/codegen/src/model.rs index 0f445a6..c487d94 100644 --- a/codegen/src/model.rs +++ b/codegen/src/model.rs @@ -50,10 +50,10 @@ pub struct DictEntry { /// /// Format: Parsed text -> Album type pub album_types: BTreeMap, - /// Names of item types (Song, Video, Artist, Playlist) - /// - /// Format: Parsed text -> Item type - pub item_types: BTreeMap, + /// Channel name prefix on playlist pages (e.g. `by`) + pub chan_prefix: String, + /// Channel name suffix on playlist pages + pub chan_suffix: String, } /// Parsed TimeAgo string, contains amount and time unit. diff --git a/notes/AB_Tests.md b/notes/AB_Tests.md index 3330a6b..800048f 100644 --- a/notes/AB_Tests.md +++ b/notes/AB_Tests.md @@ -312,7 +312,7 @@ The data model for the video shelves did not change. - **Encountered on:** 1.05.2023 - **Impact:** 🟢 Low - **Endpoint:** browse (trending videos) -- **Status:** Frequent (99%) +- **Status:** Stabilized YouTube changed the header renderer type on the trending page to a `pageHeaderRenderer`. @@ -489,7 +489,7 @@ looks needlessly complex but contains the same parsing-relevant data as the old - **Encountered on:** 29.01.2024 - **Impact:** 🟢 Low - **Endpoint:** browse -- **Status:** Frequent (55%) +- **Status:** Stabilized YouTube introduced a new data model for channel headers, based on a `"pageHeaderRenderer"`. The new model comes with more needless complexity that needs to @@ -598,7 +598,7 @@ be accomodated. There are also no mobile/TV header images available any more. - **Encountered on:** 29.02.2024 - **Impact:** 🟢 Low - **Endpoint:** browse -- **Status:** Discontinued (0%) +- **Status:** Stabilized ![A/B test 13 screenshot](./_img/ab_13.png) @@ -610,7 +610,7 @@ cover on the left side of the playlist content. - **Encountered on:** 31.01.2024 - **Impact:** 🟢 Low - **Endpoint:** next -- **Status:** Frequent (98%) +- **Status:** Stabilized YouTube changed the data model for YouTube comments, now putting the content into a seperate framework update object @@ -754,7 +754,7 @@ seperate framework update object - **Encountered on:** 10.09.2024 - **Impact:** 🟢 Low - **Endpoint:** browse -- **Status:** Common +- **Status:** Stabilized YouTube changed the data model for the channel shorts tab @@ -787,3 +787,115 @@ YouTube changed the data model for the channel shorts tab } } ``` + +## [16] New playlist header renderer + +- **Encountered on:** 11.10.2024 +- **Impact:** 🟢 Low +- **Endpoint:** browse +- **Status:** Common (99%) + +```json +{ + "pageHeaderRenderer": { + "pageTitle": "LilyPichu", + "content": { + "pageHeaderViewModel": { + "title": { + "dynamicTextViewModel": { + "text": { + "content": "LilyPichu" + } + } + }, + "metadata": { + "contentMetadataViewModel": { + "metadataRows": [ + { + "metadataParts": [ + { + "avatarStack": { + "avatarStackViewModel": { + "avatars": [ + { + "avatarViewModel": { + "image": { + "sources": [ + { + "url": "https://yt3.ggpht.com/ytc/AIdro_kcjhSY2e8WlYjQABOB65Za8n3QYycNHP9zXwxjKpBfOg=s48-c-k-c0x00ffffff-no-rj", + "width": 48, + "height": 48 + } + ] + } + } + } + ], + "text": { + "content": "by Kevin Ramirez", + "commandRuns": [ + { + "startIndex": 0, + "length": 16, + "onTap": { + "innertubeCommand": { + "browseEndpoint": { + "browseId": "UCai7BcI5lrXC2vdc3ySku8A", + "canonicalBaseUrl": "/@XxthekevinramirezxX" + } + } + } + } + ] + } + } + } + } + ] + }, + { + "metadataParts": [ + { + "text": { + "content": "Playlist" + } + }, + { + "text": { + "content": "10 videos" + } + }, + { + "text": { + "content": "856 views" + } + } + ] + } + ] + } + }, + "actions": {}, + "description": { + "descriptionPreviewViewModel": { + "description": { "content": "Hello World" } + } + }, + "heroImage": { + "contentPreviewImageViewModel": { + "image": { + "sources": [ + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLAHp6V96b70x4SWm9Pe6WEHnQhP6A", + "width": 168, + "height": 94 + } + ] + } + } + } + } + } + } +} +``` diff --git a/src/client/channel.rs b/src/client/channel.rs index 41930a7..cd29b87 100644 --- a/src/client/channel.rs +++ b/src/client/channel.rs @@ -470,10 +470,10 @@ fn map_channel( ) }; let subscriber_count = sub_part.and_then(|t| { - util::parse_large_numstr_or_warn::(&t.text, ctx.lang, &mut warnings) + util::parse_large_numstr_or_warn::(t.as_str(), ctx.lang, &mut warnings) }); let video_count = - vc_part.and_then(|t| util::parse_numeric_or_warn(&t.text, &mut warnings)); + vc_part.and_then(|t| util::parse_numeric_or_warn(t.as_str(), &mut warnings)); Channel { id: metadata.external_id, @@ -482,7 +482,7 @@ fn map_channel( md_rows .first() .and_then(|md| md.metadata_parts.get(1)) - .map(|txt| txt.text.to_owned()) + .map(|txt| txt.as_str().to_owned()) .filter(|txt| util::CHANNEL_HANDLE_REGEX.is_match(txt)) }), subscriber_count, @@ -710,7 +710,7 @@ mod tests { #[case::livestreams("livestreams", "UC2DjFE7Xf11URZqWBigcVOQ")] #[case::pageheader("shorts_20240129_pageheader", "UCh8gHdtzO2tXd593_bjErWg")] #[case::pageheader2("videos_20240324_pageheader2", "UC2DjFE7Xf11URZqWBigcVOQ")] - #[case::shorts2("shorts_20240910_lockup", "UCh8gHdtzO2tXd593_bjErWg")] + #[case::lockup("shorts_20240910_lockup", "UCh8gHdtzO2tXd593_bjErWg")] fn map_channel_videos(#[case] name: &str, #[case] id: &str) { let json_path = path!(*TESTFILES / "channel" / format!("channel_{name}.json")); let json_file = File::open(json_path).unwrap(); diff --git a/src/client/playlist.rs b/src/client/playlist.rs index 1ca0ab3..0a7f556 100644 --- a/src/client/playlist.rs +++ b/src/client/playlist.rs @@ -10,7 +10,7 @@ use crate::{ ChannelId, Playlist, VideoItem, }, serializer::text::{TextComponent, TextComponents}, - util::{self, timeago, TryRemove}, + util::{self, dictionary, timeago, TryRemove}, }; use super::{response, ClientType, MapRespCtx, MapResponse, MapResult, QBrowse, RustyPipeQuery}; @@ -98,46 +98,105 @@ impl MapResponse for response::Playlist { .playlist_sidebar_primary_info_renderer .description .filter(|d| !d.0.is_empty()), - primary - .playlist_sidebar_primary_info_renderer - .thumbnail_renderer - .playlist_video_thumbnail_renderer - .thumbnail, + Some( + primary + .playlist_sidebar_primary_info_renderer + .thumbnail_renderer + .playlist_video_thumbnail_renderer + .thumbnail, + ), primary .playlist_sidebar_primary_info_renderer .stats .try_swap_remove(2), ) } - None => { - let header_banner = header - .playlist_header_renderer - .playlist_header_banner - .ok_or(ExtractionError::InvalidData(Cow::Borrowed( - "no thumbnail found", - )))?; - - let mut byline = header.playlist_header_renderer.byline; - let last_update_txt = byline - .try_swap_remove(1) - .map(|b| b.playlist_byline_renderer.text); - - ( - None, - header_banner.hero_playlist_thumbnail_renderer.thumbnail, - last_update_txt, - ) - } + None => (None, None, None), }; + let (name, playlist_id, channel, n_videos_txt, description2, thumbnails2, last_update_txt2) = + match header { + response::playlist::Header::PlaylistHeaderRenderer(header_renderer) => { + let mut byline = header_renderer.byline; + let last_update_txt = byline + .try_swap_remove(1) + .map(|b| b.playlist_byline_renderer.text); + + ( + header_renderer.title, + header_renderer.playlist_id, + header_renderer + .owner_text + .and_then(|link| ChannelId::try_from(link).ok()), + header_renderer.num_videos_text, + header_renderer + .description_text + .map(|text| TextComponents(vec![TextComponent::new(text)])), + header_renderer + .playlist_header_banner + .map(|b| b.hero_playlist_thumbnail_renderer.thumbnail), + last_update_txt, + ) + } + response::playlist::Header::PageHeaderRenderer(content_renderer) => { + let h = content_renderer.content.page_header_view_model; + let rows = h.metadata.content_metadata_view_model.metadata_rows; + let n_videos_txt = rows + .get(1) + .and_then(|r| r.metadata_parts.get(1)) + .map(|p| p.as_str().to_owned()) + .ok_or(ExtractionError::InvalidData("no video count".into()))?; + let mut channel = rows + .into_iter() + .next() + .and_then(|r| r.metadata_parts.into_iter().next()) + .and_then(|p| match p { + response::MetadataPart::Text(_) => None, + response::MetadataPart::AvatarStack { + avatar_stack_view_model, + } => ChannelId::try_from(avatar_stack_view_model.text).ok(), + }); + // remove "by" prefix + if let Some(c) = channel.as_mut() { + let entry = dictionary::entry(ctx.lang); + let n = c.name.strip_prefix(entry.chan_prefix).unwrap_or(&c.name); + let n = n.strip_suffix(entry.chan_suffix).unwrap_or(n); + c.name = n.trim().to_owned(); + } + + let playlist_id = h + .actions + .flexible_actions_view_model + .actions_rows + .into_iter() + .next() + .and_then(|r| r.actions.into_iter().next()) + .and_then(|a| { + a.button_view_model + .on_tap + .innertube_command + .into_playlist_id() + }) + .ok_or(ExtractionError::InvalidData("no playlist id".into()))?; + ( + h.title.dynamic_text_view_model.text, + playlist_id, + channel, + n_videos_txt, + h.description.description_preview_view_model.description, + h.hero_image.content_preview_image_view_model.image.into(), + None, + ) + } + }; + let n_videos = if mapper.ctoken.is_some() { - util::parse_numeric(&header.playlist_header_renderer.num_videos_text) - .map_err(|_| ExtractionError::InvalidData(Cow::Borrowed("no video count")))? + util::parse_numeric(&n_videos_txt) + .map_err(|_| ExtractionError::InvalidData("no video count".into()))? } else { mapper.items.len() as u64 }; - let playlist_id = header.playlist_header_renderer.playlist_id; if playlist_id != ctx.id { return Err(ExtractionError::WrongResult(format!( "got wrong playlist id {}, expected {}", @@ -145,24 +204,19 @@ impl MapResponse for response::Playlist { ))); } - let name = header.playlist_header_renderer.title; - let description = description - .or_else(|| { - header - .playlist_header_renderer - .description_text - .map(|text| TextComponents(vec![TextComponent::new(text)])) - }) - .map(RichText::from); - let channel = header - .playlist_header_renderer - .owner_text - .and_then(|link| ChannelId::try_from(link).ok()); - - let last_update = last_update_txt.as_ref().and_then(|txt| { - timeago::parse_textual_date_or_warn(ctx.lang, txt, &mut mapper.warnings) - .map(OffsetDateTime::date) - }); + let description = description.or(description2).map(RichText::from); + let thumbnails = thumbnails + .or(thumbnails2) + .ok_or(ExtractionError::InvalidData(Cow::Borrowed( + "no thumbnail found", + )))?; + let last_update = last_update_txt + .as_deref() + .or(last_update_txt2.as_deref()) + .and_then(|txt| { + timeago::parse_textual_date_or_warn(ctx.lang, txt, &mut mapper.warnings) + .map(OffsetDateTime::date) + }); Ok(MapResult { c: Playlist { @@ -207,6 +261,7 @@ mod tests { #[case::long("long", "PL5dDx681T4bR7ZF1IuWzOv1omlRbE7PiJ")] #[case::nomusic("nomusic", "PL1J-6JOckZtE_P9Xx8D3b2O6w0idhuKBe")] #[case::live("live", "UULVvqRdlKsE5Q8mf8YXbdIJLw")] + #[case::pageheader("20241011_pageheader", "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5")] fn map_playlist_data(#[case] name: &str, #[case] id: &str) { let json_path = path!(*TESTFILES / "playlist" / format!("playlist_{name}.json")); let json_file = File::open(json_path).unwrap(); diff --git a/src/client/response/channel.rs b/src/client/response/channel.rs index c9b0440..a379d06 100644 --- a/src/client/response/channel.rs +++ b/src/client/response/channel.rs @@ -3,7 +3,8 @@ use serde_with::{rust::deserialize_ignore_any, serde_as, DefaultOnError, VecSkip use super::{ video_item::YouTubeListRenderer, Alert, ChannelBadge, ContentRenderer, ContentsRenderer, - ContinuationActionWrap, ImageView, ResponseContext, Thumbnails, TwoColumnBrowseResults, + ContinuationActionWrap, ImageView, PageHeaderRendererContent, PhMetadataView, ResponseContext, + Thumbnails, TwoColumnBrowseResults, }; use crate::serializer::text::{AttributedText, Text, TextComponent}; @@ -76,7 +77,7 @@ pub(crate) enum Header { C4TabbedHeaderRenderer(HeaderRenderer), /// Used for special channels like YouTube Music CarouselHeaderRenderer(ContentsRenderer), - PageHeaderRenderer(ContentRenderer), + PageHeaderRenderer(ContentRenderer>), } #[serde_as] @@ -114,12 +115,6 @@ pub(crate) enum CarouselHeaderRendererItem { None, } -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct PageHeaderRenderer { - pub page_header_view_model: PageHeaderRendererInner, -} - #[serde_as] #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] @@ -225,38 +220,12 @@ pub(crate) struct PhAvatarView3 { pub avatar_view_model: ImageView, } -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct PhMetadataView { - pub content_metadata_view_model: PhMetadataView2, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct PhMetadataView2 { - pub metadata_rows: Vec, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct PhMetadataRow { - pub metadata_parts: Vec, -} - #[derive(Default, Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct PhBannerView { pub image_banner_view_model: ImageView, } -#[serde_as] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct TextWrap { - #[serde_as(deserialize_as = "Text")] - pub text: String, -} - #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct Metadata { diff --git a/src/client/response/mod.rs b/src/client/response/mod.rs index e8b7b52..cf946e6 100644 --- a/src/client/response/mod.rs +++ b/src/client/response/mod.rs @@ -57,7 +57,8 @@ use serde::{ use serde_with::{serde_as, DisplayFromStr, VecSkipError}; use crate::error::ExtractionError; -use crate::serializer::{text::Text, MapResult, VecSkipErrorWrap}; +use crate::serializer::text::{AttributedText, Text, TextComponent}; +use crate::serializer::{MapResult, VecSkipErrorWrap}; use self::video_item::YouTubeListRenderer; @@ -464,3 +465,61 @@ where deserializer.deserialize_seq(SeqVisitor(PhantomData::)) } } + +// PAGE HEADER + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PageHeaderRendererContent { + pub page_header_view_model: T, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhMetadataView { + pub content_metadata_view_model: PhMetadataView2, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhMetadataView2 { + pub metadata_rows: Vec, +} + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhMetadataRow { + #[serde_as(as = "VecSkipError<_>")] + pub metadata_parts: Vec, +} + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) enum MetadataPart { + Text(#[serde_as(deserialize_as = "AttributedText")] String), + #[serde(rename_all = "camelCase")] + AvatarStack { + avatar_stack_view_model: AvatarStackViewModel, + }, +} + +impl MetadataPart { + pub fn as_str(&self) -> &str { + match self { + MetadataPart::Text(s) => s, + MetadataPart::AvatarStack { + avatar_stack_view_model, + } => avatar_stack_view_model.text.as_str(), + } + } +} + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct AvatarStackViewModel { + #[serde_as(deserialize_as = "AttributedText")] + pub text: TextComponent, +} diff --git a/src/client/response/playlist.rs b/src/client/response/playlist.rs index 7d29635..619932e 100644 --- a/src/client/response/playlist.rs +++ b/src/client/response/playlist.rs @@ -1,11 +1,12 @@ use serde::Deserialize; -use serde_with::{serde_as, DefaultOnError}; +use serde_with::{serde_as, DefaultOnError, VecSkipError}; -use crate::serializer::text::{Text, TextComponent, TextComponents}; +use crate::serializer::text::{AttributedText, Text, TextComponent, TextComponents}; use super::{ - video_item::YouTubeListRenderer, Alert, ContentsRenderer, ResponseContext, SectionList, Tab, - ThumbnailsWrap, TwoColumnBrowseResults, + url_endpoint::NavigationEndpoint, video_item::YouTubeListRenderer, Alert, ContentRenderer, + ContentsRenderer, ImageView, PageHeaderRendererContent, PhMetadataView, ResponseContext, + SectionList, Tab, ThumbnailsWrap, TwoColumnBrowseResults, }; #[serde_as] @@ -35,8 +36,9 @@ pub(crate) struct PlaylistVideoListRenderer { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -pub(crate) struct Header { - pub playlist_header_renderer: HeaderRenderer, +pub(crate) enum Header { + PlaylistHeaderRenderer(HeaderRenderer), + PageHeaderRenderer(ContentRenderer>), } #[serde_as] @@ -111,3 +113,85 @@ pub(crate) struct PlaylistThumbnailRenderer { #[serde(alias = "playlistCustomThumbnailRenderer")] pub playlist_video_thumbnail_renderer: ThumbnailsWrap, } + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PageHeaderRendererInner { + pub title: PhTitleView, + pub metadata: PhMetadataView, + pub actions: PhActions, + pub description: PhDescription, + pub hero_image: PhHeroImage, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhDescription { + pub description_preview_view_model: PhDescription2, +} + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhDescription2 { + #[serde_as(as = "Option")] + pub description: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhHeroImage { + pub content_preview_image_view_model: ImageView, +} + +#[derive(Default, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhTitleView { + pub dynamic_text_view_model: PhTitleInner, +} + +#[serde_as] +#[derive(Default, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhTitleInner { + #[serde_as(as = "AttributedText")] + pub text: String, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhActions { + pub flexible_actions_view_model: PhActions2, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct PhActions2 { + pub actions_rows: Vec, +} + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ActionsRow { + #[serde_as(as = "VecSkipError<_>")] + pub actions: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ButtonAction { + pub button_view_model: ButtonViewModel, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ButtonViewModel { + pub on_tap: ActionOnTap, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ActionOnTap { + pub innertube_command: NavigationEndpoint, +} diff --git a/src/client/response/url_endpoint.rs b/src/client/response/url_endpoint.rs index e94e06c..1eb5786 100644 --- a/src/client/response/url_endpoint.rs +++ b/src/client/response/url_endpoint.rs @@ -157,7 +157,7 @@ pub(crate) struct WatchEndpointConfig { #[derive(Default, Debug, Clone, Copy, Deserialize, PartialEq, Eq)] pub(crate) enum MusicVideoType { #[default] - #[serde(rename = "MUSIC_VIDEO_TYPE_OMV")] + #[serde(rename = "MUSIC_VIDEO_TYPE_OMV", alias = "MUSIC_VIDEO_TYPE_UGC")] Video, #[serde(rename = "MUSIC_VIDEO_TYPE_ATV")] Track, @@ -333,4 +333,26 @@ impl NavigationEndpoint { None } } + + pub(crate) fn into_playlist_id(self) -> Option { + match self { + NavigationEndpoint::Watch { watch_endpoint } => watch_endpoint.playlist_id, + NavigationEndpoint::Browse { + browse_endpoint, + command_metadata, + } => Some(browse_endpoint.browse_id).filter(|_| { + browse_endpoint + .browse_endpoint_context_supported_configs + .map(|c| c.browse_endpoint_context_music_config.page_type == PageType::Playlist) + .unwrap_or_default() + || command_metadata + .map(|c| c.web_command_metadata.web_page_type == PageType::Playlist) + .unwrap_or_default() + }), + NavigationEndpoint::Url { .. } => None, + NavigationEndpoint::WatchPlaylist { + watch_playlist_endpoint, + } => Some(watch_playlist_endpoint.playlist_id), + } + } } diff --git a/src/client/snapshots/rustypipe__client__playlist__tests__map_playlist_data_20241011_pageheader.snap b/src/client/snapshots/rustypipe__client__playlist__tests__map_playlist_data_20241011_pageheader.snap new file mode 100644 index 0000000..99d94cf --- /dev/null +++ b/src/client/snapshots/rustypipe__client__playlist__tests__map_playlist_data_20241011_pageheader.snap @@ -0,0 +1,456 @@ +--- +source: src/client/playlist.rs +expression: map_res.c +--- +Playlist( + id: "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + name: "LilyPichu", + videos: Paginator( + count: Some(10), + items: [ + VideoItem( + id: "DXuNJ267Vss", + name: "dreamy night ♫", + duration: Some(246), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBQu39qIU8WKbC5KeXQ_a_Kmeq-Mw", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAFnmg4-mRI64nmz4R4GUGo720Jzw", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLClxuSTfYdqfosJClOxA2osI934sw", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCVR7qAVJNM3flwQ_ZYfPS3iujF1w", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(15000000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "eutMcjJCVqc", + name: "these days it\'s hard to find the words ♫", + duration: Some(168), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDc3Ycpb5YaNFeHu8Nf5smL25Z07A", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAScc3jmGa81fZ-rdds1pLhsyeHcA", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCukgu31Ut9lp2E4t5BWlzit6JruA", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBjeA0RixBcCP2w53Ke2H43HJ9j9w", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(1200000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "B5eM3Q3wj0M", + name: "a vision ♫", + duration: Some(169), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBK3FpJmFmAlA7ALGjJDXrWC-jtfw", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCwzmil8fgPbrAd-ef4T3vzIzmlKg", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBDU2ur1UisffVmAXAG8lXbT49x5Q", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBy46YLhKfVL6Wj71RWd1Ru9C3Z0w", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(843000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "MJedvm2TE8o", + name: "a stormy night ♫", + duration: Some(202), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBtulKIBStuPyBYbBqlE5B4-2xBaQ", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAEgWtwIZHLv5EKCZVIVibIkZLHlg", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSlJy1g4t2np6JK4hBst8b6PA2ew", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDkDGK867GRxs9b42P7hJkK6B2pRQ", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(1300000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "HHKmS7c5ai4", + name: "unknown waters ♫", + duration: Some(116), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLArqrLnSpTLA-1qj-yF6AmfrHOsTA", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCOh-S60OM2Hhswihr3Glb1cM1AAg", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBEyk0qxSToWD_g9L3bTrtrsJjhsw", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDG12RCxjnm4JHG9T8Ow_thj_ecxA", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(707000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "zF32eh6PWPk", + name: "wilting memories ♫", + duration: Some(108), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDr2_1EoZ50kzSgDKwJQaY6Pv3WJA", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC44h27mvgtl5QBA_ed1o4kXPieBA", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDm1iJNfB4KbVMoqPMKrWNHIBaBgg", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDCJEQasRwYLo-iK___zZ767PrCWQ", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(797000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "hbz-8K-pxpY", + name: "sunshine & butterflies ♫", + duration: Some(185), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDMheaVKp1qI6AOcwrLl2K_U7EnAA", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDSWaobRJuSVZFDf9aj1kHVx6WuXw", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDi33fhhNwD8Rtf56eIrPZV0Wh8ZQ", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBt77gqVq8oLIUs7njZkvP2EvmTAw", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(2500000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "A2zepLiuEJU", + name: "foreverland ♫", + duration: Some(146), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAUpy0PRzet_xrPsGPj2Mw_ik5o0A", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCgYyZQkAGdE25F-zZ6AAHY5GuNjQ", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBWFlbG5J4x8J3pxGC2k_P2O7lKmA", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD6N47yuLYe5m50AwYPX9Cos4RSVA", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(983000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "5yaY7aG1Lpo", + name: "dreamy nightmares ♫", + duration: Some(197), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB-5OLhj51LzsZswqPsGVPOKfkhFA", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDISujKyqhzBYW3SdgC5QTxv7i1KQ", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDBkkukABZ_d3rsEzewfiHimbM2PA", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCnqJbFB4UvqIKUQq5xvVH6RQBm7A", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(1100000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + VideoItem( + id: "WwXJrMhbi-s", + name: "comfy vibes ♫", + duration: Some(194), + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLByFfew80T9RbyU8-EiLyb6HRU4Ww", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCcjh19GL-pWHpkpRD1ioCcyoZcrA", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCa7u5cp-4vH6mDG8HUOKyNTETgtQ", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB-vP4BDBiu9PfU-F6DQ75iUsL4xQ", + width: 336, + height: 188, + ), + ], + channel: Some(ChannelTag( + id: "UCde_xnXu2lPBmRgAp_nq29A", + name: "comfi beats", + avatar: [], + verification: None, + subscriber_count: None, + )), + publish_date: "[date]", + publish_date_txt: Some("4 years ago"), + view_count: Some(1800000), + is_live: false, + is_short: false, + is_upcoming: false, + short_description: None, + ), + ], + ctoken: None, + endpoint: browse, + ), + video_count: 10, + thumbnail: [ + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLAHp6V96b70x4SWm9Pe6WEHnQhP6A", + width: 168, + height: 94, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCMQBEG5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLDPCehYWYW8HhToloH9MJWD_wKq1w", + width: 196, + height: 110, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCPYBEIoBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLA7aSRV3Ymv8oEFYT7TUpwSZLPbCA", + width: 246, + height: 138, + ), + Thumbnail( + url: "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAYMzfwTTZbTbHcDUK9kIa450u_7g", + width: 336, + height: 188, + ), + ], + description: None, + channel: Some(ChannelId( + id: "UCai7BcI5lrXC2vdc3ySku8A", + name: "Kevin Ramirez", + )), + last_update: "[date]", + last_update_txt: Some("Last updated on Oct 13, 2020"), + visitor_data: Some("CgtQNE9Wb3N1MU1HSSic8Ka4BjIKCgJERRIEEgAgMA%3D%3D"), +) diff --git a/src/util/dictionary.rs b/src/util/dictionary.rs index f2fbe2a..22fab6a 100644 --- a/src/util/dictionary.rs +++ b/src/util/dictionary.rs @@ -50,6 +50,10 @@ pub(crate) struct Entry { /// /// Format: Parsed text -> Album type pub album_types: phf::Map<&'static str, AlbumType>, + /// Channel name prefix on playlist pages (e.g. `by`) + pub chan_prefix: &'static str, + /// Channel name suffix on playlist pages + pub chan_suffix: &'static str, } #[rustfmt::skip] @@ -151,6 +155,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("enkelsnit", AlbumType::Single), ], }, + chan_prefix: "deur", + chan_suffix: "", }, Language::Am => Entry { timeago_tokens: ::phf::Map { @@ -252,6 +258,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("አልበም", AlbumType::Album), ], }, + chan_prefix: "በ", + chan_suffix: "", }, Language::Ar => Entry { timeago_tokens: ::phf::Map { @@ -355,6 +363,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("الكتب المسموعة", AlbumType::Audiobook), ], }, + chan_prefix: "بواسطة", + chan_suffix: "", }, Language::As => Entry { timeago_tokens: ::phf::Map { @@ -438,6 +448,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "", + chan_suffix: "ৰ দ\u{9cd}ব\u{9be}ৰ\u{9be}", }, Language::Az => Entry { timeago_tokens: ::phf::Map { @@ -524,6 +536,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "by", + chan_suffix: "", }, Language::Be => Entry { timeago_tokens: ::phf::Map { @@ -640,6 +654,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("міні-альбом", AlbumType::Ep), ], }, + chan_prefix: "ад", + chan_suffix: "", }, Language::Bg => Entry { timeago_tokens: ::phf::Map { @@ -725,6 +741,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("предаване", AlbumType::Show), ], }, + chan_prefix: "от", + chan_suffix: "", }, Language::Bn => Entry { timeago_tokens: ::phf::Map { @@ -816,6 +834,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("অ\u{9cd}য\u{9be}লব\u{9be}ম", AlbumType::Album), ], }, + chan_prefix: ",", + chan_suffix: "দ\u{9cd}ব\u{9be}র\u{9be}", }, Language::Bs => Entry { timeago_tokens: ::phf::Map { @@ -926,6 +946,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "od", + chan_suffix: "", }, Language::Ca => Entry { timeago_tokens: ::phf::Map { @@ -1023,6 +1045,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiollibre", AlbumType::Audiobook), ], }, + chan_prefix: "de:", + chan_suffix: "", }, Language::Cs => Entry { timeago_tokens: ::phf::Map { @@ -1122,6 +1146,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("album", AlbumType::Album), ], }, + chan_prefix: "autor:", + chan_suffix: "", }, Language::Da => Entry { timeago_tokens: ::phf::Map { @@ -1218,6 +1244,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "af", + chan_suffix: "", }, Language::De => Entry { timeago_tokens: ::phf::Map { @@ -1299,6 +1327,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("hörspiel", AlbumType::Show), ], }, + chan_prefix: "von", + chan_suffix: "", }, Language::El => Entry { timeago_tokens: ::phf::Map { @@ -1399,6 +1429,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("άλμπουμ", AlbumType::Album), ], }, + chan_prefix: "από το χρήστη", + chan_suffix: "", }, Language::En | Language::EnGb | Language::EnIn => Entry { timeago_tokens: ::phf::Map { @@ -1511,6 +1543,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiobook", AlbumType::Audiobook), ], }, + chan_prefix: "by", + chan_suffix: "", }, Language::Es => Entry { timeago_tokens: ::phf::Map { @@ -1608,6 +1642,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "de", + chan_suffix: "", }, Language::EsUs | Language::Es419 => Entry { timeago_tokens: ::phf::Map { @@ -1706,6 +1742,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("álbum", AlbumType::Album), ], }, + chan_prefix: "de", + chan_suffix: "", }, Language::Et => Entry { timeago_tokens: ::phf::Map { @@ -1806,6 +1844,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("album", AlbumType::Album), ], }, + chan_prefix: "kanalilt", + chan_suffix: "", }, Language::Eu => Entry { timeago_tokens: ::phf::Map { @@ -1892,6 +1932,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("albuma", AlbumType::Album), ], }, + chan_prefix: "egilea:", + chan_suffix: "", }, Language::Fa => Entry { timeago_tokens: ::phf::Map { @@ -1978,6 +2020,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("کتاب صوتی", AlbumType::Audiobook), ], }, + chan_prefix: "توسط", + chan_suffix: "", }, Language::Fi => Entry { timeago_tokens: ::phf::Map { @@ -2066,6 +2110,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "tekijä:", + chan_suffix: "", }, Language::Fil => Entry { timeago_tokens: ::phf::Map { @@ -2152,6 +2198,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "ni/ng", + chan_suffix: "", }, Language::Fr | Language::FrCa => Entry { timeago_tokens: ::phf::Map { @@ -2256,6 +2304,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("single", AlbumType::Single), ], }, + chan_prefix: "de", + chan_suffix: "", }, Language::Gl => Entry { timeago_tokens: ::phf::Map { @@ -2352,6 +2402,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiolibro", AlbumType::Audiobook), ], }, + chan_prefix: "de", + chan_suffix: "", }, Language::Gu => Entry { timeago_tokens: ::phf::Map { @@ -2437,6 +2489,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("સિ\u{a82}ગલ", AlbumType::Single), ], }, + chan_prefix: "", + chan_suffix: "દ\u{acd}વારા", }, Language::Hi => Entry { timeago_tokens: ::phf::Map { @@ -2526,6 +2580,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("एल\u{94d}\u{200d}बम", AlbumType::Album), ], }, + chan_prefix: "", + chan_suffix: "क\u{947} ज\u{93c}रिए", }, Language::Hr => Entry { timeago_tokens: ::phf::Map { @@ -2635,6 +2691,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("singl", AlbumType::Single), ], }, + chan_prefix: "omogućio kanal", + chan_suffix: "", }, Language::Hu => Entry { timeago_tokens: ::phf::Map { @@ -2734,6 +2792,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("műsor", AlbumType::Show), ], }, + chan_prefix: "", + chan_suffix: "csatornától", }, Language::Hy => Entry { timeago_tokens: ::phf::Map { @@ -2826,6 +2886,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ալբոմ", AlbumType::Album), ], }, + chan_prefix: "հեղինակ՝", + chan_suffix: "", }, Language::Id => Entry { timeago_tokens: ::phf::Map { @@ -2918,6 +2980,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("acara", AlbumType::Show), ], }, + chan_prefix: "oleh", + chan_suffix: "", }, Language::Is => Entry { timeago_tokens: ::phf::Map { @@ -3023,6 +3087,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "eftir", + chan_suffix: "", }, Language::It => Entry { timeago_tokens: ::phf::Map { @@ -3125,6 +3191,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("programma", AlbumType::Show), ], }, + chan_prefix: "di", + chan_suffix: "", }, Language::Iw => Entry { timeago_tokens: ::phf::Map { @@ -3233,6 +3301,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("סינגל", AlbumType::Single), ], }, + chan_prefix: "מאת", + chan_suffix: "", }, Language::Ja => Entry { timeago_tokens: ::phf::Map { @@ -3300,6 +3370,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("表示", AlbumType::Show), ], }, + chan_prefix: "作成者:", + chan_suffix: "", }, Language::Ka => Entry { timeago_tokens: ::phf::Map { @@ -3392,6 +3464,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("სინგლი", AlbumType::Single), ], }, + chan_prefix: "", + chan_suffix: "-ის მიერ", }, Language::Kk => Entry { timeago_tokens: ::phf::Map { @@ -3485,6 +3559,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("альбом", AlbumType::Album), ], }, + chan_prefix: "қосқан", + chan_suffix: "", }, Language::Km => Entry { timeago_tokens: ::phf::Map { @@ -3570,6 +3646,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ចម\u{17d2}រៀងទោល", AlbumType::Single), ], }, + chan_prefix: "ដោយ", + chan_suffix: "", }, Language::Kn => Entry { timeago_tokens: ::phf::Map { @@ -3671,6 +3749,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ಆಲ\u{ccd}ಬಮ\u{ccd}", AlbumType::Album), ], }, + chan_prefix: "", + chan_suffix: "ಚಾನಲ\u{ccd}\u{200c}ನ\u{cbf}ಂದ", }, Language::Ko => Entry { timeago_tokens: ::phf::Map { @@ -3741,6 +3821,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("싱글", AlbumType::Single), ], }, + chan_prefix: "게시자:", + chan_suffix: "", }, Language::Ky => Entry { timeago_tokens: ::phf::Map { @@ -3829,6 +3911,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("чакан альбом", AlbumType::Ep), ], }, + chan_prefix: "", + chan_suffix: "каналы аркылуу", }, Language::Lo => Entry { timeago_tokens: ::phf::Map { @@ -3923,6 +4007,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ສະແດງ", AlbumType::Show), ], }, + chan_prefix: "ໂດຍ", + chan_suffix: "", }, Language::Lt => Entry { timeago_tokens: ::phf::Map { @@ -4026,6 +4112,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("garsinė knyga", AlbumType::Audiobook), ], }, + chan_prefix: "pridėjo", + chan_suffix: "", }, Language::Lv => Entry { timeago_tokens: ::phf::Map { @@ -4132,6 +4220,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("pārraide", AlbumType::Show), ], }, + chan_prefix: "autors:", + chan_suffix: "", }, Language::Mk => Entry { timeago_tokens: ::phf::Map { @@ -4215,6 +4305,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("серија", AlbumType::Show), ], }, + chan_prefix: "од", + chan_suffix: "", }, Language::Ml => Entry { timeago_tokens: ::phf::Map { @@ -4302,6 +4394,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ആല\u{d4d}\u{200d}\u{200c}ബം", AlbumType::Album), ], }, + chan_prefix: "", + chan_suffix: "മ\u{d41}ഖേന", }, Language::Mn => Entry { timeago_tokens: ::phf::Map { @@ -4379,6 +4473,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("цомог", AlbumType::Album), ], }, + chan_prefix: "сувгийн нэр:", + chan_suffix: "", }, Language::Mr => Entry { timeago_tokens: ::phf::Map { @@ -4481,6 +4577,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("शो", AlbumType::Show), ], }, + chan_prefix: "", + chan_suffix: "द\u{94d}वार\u{947}", }, Language::Ms => Entry { timeago_tokens: ::phf::Map { @@ -4570,6 +4668,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "oleh", + chan_suffix: "", }, Language::My => Entry { timeago_tokens: ::phf::Map { @@ -4663,6 +4763,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("အော\u{103a}ဒ\u{102e}ယ\u{102d}\u{102f}စာအ\u{102f}ပ\u{103a}", AlbumType::Audiobook), ], }, + chan_prefix: "", + chan_suffix: "မ\u{103e}", }, Language::Ne => Entry { timeago_tokens: ::phf::Map { @@ -4750,6 +4852,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("अडियोब\u{941}क", AlbumType::Audiobook), ], }, + chan_prefix: "", + chan_suffix: "द\u{94d}वारा", }, Language::Nl => Entry { timeago_tokens: ::phf::Map { @@ -4843,6 +4947,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "door", + chan_suffix: "", }, Language::No => Entry { timeago_tokens: ::phf::Map { @@ -4946,6 +5052,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "av", + chan_suffix: "", }, Language::Or => Entry { timeago_tokens: ::phf::Map { @@ -5046,6 +5154,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "", + chan_suffix: "ଦ\u{b4d}ଵ\u{b3e}ର\u{b3e}", }, Language::Pa => Entry { timeago_tokens: ::phf::Map { @@ -5135,6 +5245,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ਸ\u{a3c}\u{a4b}ਅ", AlbumType::Show), ], }, + chan_prefix: "", + chan_suffix: "ਵ\u{a71}ਲ\u{a4b}\u{a02}", }, Language::Pl => Entry { timeago_tokens: ::phf::Map { @@ -5250,6 +5362,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiobook", AlbumType::Audiobook), ], }, + chan_prefix: "autor:", + chan_suffix: "", }, Language::Pt => Entry { timeago_tokens: ::phf::Map { @@ -5349,6 +5463,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiolivro", AlbumType::Audiobook), ], }, + chan_prefix: "por", + chan_suffix: "", }, Language::PtPt => Entry { timeago_tokens: ::phf::Map { @@ -5430,6 +5546,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiolivro", AlbumType::Audiobook), ], }, + chan_prefix: "de", + chan_suffix: "", }, Language::Ro => Entry { timeago_tokens: ::phf::Map { @@ -5529,6 +5647,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("album", AlbumType::Album), ], }, + chan_prefix: "de", + chan_suffix: "", }, Language::Ru => Entry { timeago_tokens: ::phf::Map { @@ -5642,6 +5762,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("аудиошоу", AlbumType::Show), ], }, + chan_prefix: "", + chan_suffix: "", }, Language::Si => Entry { timeago_tokens: ::phf::Map { @@ -5729,6 +5851,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ඇල\u{dca}බමය", AlbumType::Album), ], }, + chan_prefix: "", + chan_suffix: "ව\u{dd2}ස\u{dd2}න\u{dca}", }, Language::Sk => Entry { timeago_tokens: ::phf::Map { @@ -5828,6 +5952,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiokniha", AlbumType::Audiobook), ], }, + chan_prefix: "Autori:", + chan_suffix: "", }, Language::Sl => Entry { timeago_tokens: ::phf::Map { @@ -5948,6 +6074,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ep", AlbumType::Ep), ], }, + chan_prefix: "kanal", + chan_suffix: "", }, Language::Sq => Entry { timeago_tokens: ::phf::Map { @@ -6039,6 +6167,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("single", AlbumType::Single), ], }, + chan_prefix: "nga", + chan_suffix: "", }, Language::Sr => Entry { timeago_tokens: ::phf::Map { @@ -6127,6 +6257,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("серија", AlbumType::Show), ], }, + chan_prefix: "са канала", + chan_suffix: "", }, Language::SrLatn => Entry { timeago_tokens: ::phf::Map { @@ -6215,6 +6347,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("serija", AlbumType::Show), ], }, + chan_prefix: "sa kanala", + chan_suffix: "", }, Language::Sv => Entry { timeago_tokens: ::phf::Map { @@ -6313,6 +6447,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("singel", AlbumType::Single), ], }, + chan_prefix: "från", + chan_suffix: "", }, Language::Sw => Entry { timeago_tokens: ::phf::Map { @@ -6400,6 +6536,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("kipindi", AlbumType::Show), ], }, + chan_prefix: "kutoka", + chan_suffix: "", }, Language::Ta => Entry { timeago_tokens: ::phf::Map { @@ -6503,6 +6641,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("ஆடியோ புத\u{bcd}தகம\u{bcd}", AlbumType::Audiobook), ], }, + chan_prefix: "வழங\u{bcd}கியவர\u{bcd}:", + chan_suffix: "", }, Language::Te => Entry { timeago_tokens: ::phf::Map { @@ -6603,6 +6743,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("స\u{c3f}ంగ\u{c3f}ల\u{c4d}", AlbumType::Single), ], }, + chan_prefix: "", + chan_suffix: "ఛ\u{c3e}న\u{c46}ల\u{c4d} ద\u{c4d}వ\u{c3e}ర\u{c3e}", }, Language::Th => Entry { timeago_tokens: ::phf::Map { @@ -6704,6 +6846,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("อ\u{e31}ลบ\u{e31}\u{e49}ม", AlbumType::Album), ], }, + chan_prefix: "โดย", + chan_suffix: "", }, Language::Tr => Entry { timeago_tokens: ::phf::Map { @@ -6794,6 +6938,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("albüm", AlbumType::Album), ], }, + chan_prefix: "", + chan_suffix: "tarafından", }, Language::Uk => Entry { timeago_tokens: ::phf::Map { @@ -6911,6 +7057,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("аудіодрама", AlbumType::Show), ], }, + chan_prefix: "власник:", + chan_suffix: "", }, Language::Ur => Entry { timeago_tokens: ::phf::Map { @@ -7006,6 +7154,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("شو", AlbumType::Show), ], }, + chan_prefix: "منجانب", + chan_suffix: "", }, Language::Uz => Entry { timeago_tokens: ::phf::Map { @@ -7091,6 +7241,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("audiokitob", AlbumType::Audiobook), ], }, + chan_prefix: "muallif:", + chan_suffix: "", }, Language::Vi => Entry { timeago_tokens: ::phf::Map { @@ -7159,6 +7311,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("đĩa nhạc", AlbumType::Album), ], }, + chan_prefix: "của", + chan_suffix: "", }, Language::ZhCn => Entry { timeago_tokens: ::phf::Map { @@ -7228,6 +7382,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("单曲", AlbumType::Single), ], }, + chan_prefix: "创建者:", + chan_suffix: "", }, Language::ZhHk => Entry { timeago_tokens: ::phf::Map { @@ -7296,6 +7452,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("單曲", AlbumType::Single), ], }, + chan_prefix: "來自", + chan_suffix: "", }, Language::ZhTw => Entry { timeago_tokens: ::phf::Map { @@ -7363,6 +7521,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("單曲", AlbumType::Single), ], }, + chan_prefix: "由", + chan_suffix: "建立", }, Language::Zu => Entry { timeago_tokens: ::phf::Map { @@ -7467,6 +7627,8 @@ pub(crate) fn entry(lang: Language) -> Entry { ("i-ep", AlbumType::Ep), ], }, + chan_prefix: "ka-", + chan_suffix: "", }, } } diff --git a/testfiles/dict/chan_prefixes.json b/testfiles/dict/chan_prefixes.json new file mode 100644 index 0000000..9a15b68 --- /dev/null +++ b/testfiles/dict/chan_prefixes.json @@ -0,0 +1,85 @@ +{ + "af": { "prefix": "deur ", "suffix": "" }, + "am": { "prefix": "በ", "suffix": "" }, + "ar": { "prefix": "بواسطة", "suffix": "" }, + "as": { "prefix": "", "suffix": "ৰ দ্বাৰা" }, + "az": { "prefix": "by ", "suffix": "" }, + "be": { "prefix": "ад ", "suffix": "" }, + "bg": { "prefix": "от ", "suffix": "" }, + "bn": { "prefix": ", ", "suffix": " দ্বারা" }, + "bs": { "prefix": "od ", "suffix": "" }, + "ca": { "prefix": "de: ", "suffix": "" }, + "cs": { "prefix": "autor: ", "suffix": "" }, + "da": { "prefix": "af ", "suffix": "" }, + "de": { "prefix": "von ", "suffix": "" }, + "el": { "prefix": "από το χρήστη ", "suffix": "" }, + "en": { "prefix": "by ", "suffix": "" }, + "en-GB": { "prefix": "by ", "suffix": "" }, + "en-IN": { "prefix": "by ", "suffix": "" }, + "es": { "prefix": "de ", "suffix": "" }, + "es-419": { "prefix": "de ", "suffix": "" }, + "es-US": { "prefix": "de ", "suffix": "" }, + "et": { "prefix": "kanalilt ", "suffix": "" }, + "eu": { "prefix": "egilea: ", "suffix": "" }, + "fa": { "prefix": "توسط ", "suffix": "" }, + "fi": { "prefix": "tekijä: ", "suffix": "" }, + "fil": { "prefix": "ni/ng ", "suffix": "" }, + "fr": { "prefix": "de ", "suffix": "" }, + "fr-CA": { "prefix": "de ", "suffix": "" }, + "gl": { "prefix": "de ", "suffix": "" }, + "gu": { "prefix": "", "suffix": " દ્વારા" }, + "hi": { "prefix": "", "suffix": " के ज़रिए" }, + "hr": { "prefix": "omogućio kanal ", "suffix": "" }, + "hu": { "prefix": "", "suffix": " csatornától" }, + "hy": { "prefix": "հեղինակ՝ ", "suffix": "" }, + "id": { "prefix": "oleh ", "suffix": "" }, + "is": { "prefix": "eftir ", "suffix": "" }, + "it": { "prefix": "di ", "suffix": "" }, + "iw": { "prefix": "מאת ", "suffix": "" }, + "ja": { "prefix": "作成者: ", "suffix": "" }, + "ka": { "prefix": "", "suffix": "-ის მიერ" }, + "kk": { "prefix": "қосқан ", "suffix": "" }, + "km": { "prefix": "ដោយ ", "suffix": "" }, + "kn": { "prefix": "", "suffix": " ಚಾನಲ್‌ನಿಂದ" }, + "ko": { "prefix": "게시자: ", "suffix": "" }, + "ky": { "prefix": "", "suffix": " каналы аркылуу" }, + "lo": { "prefix": "ໂດຍ ", "suffix": "" }, + "lt": { "prefix": "pridėjo ", "suffix": "" }, + "lv": { "prefix": "autors: ", "suffix": "" }, + "mk": { "prefix": "од ", "suffix": "" }, + "ml": { "prefix": "", "suffix": " മുഖേന" }, + "mn": { "prefix": "сувгийн нэр: ", "suffix": "" }, + "mr": { "prefix": "", "suffix": "द्वारे" }, + "ms": { "prefix": "oleh ", "suffix": "" }, + "my": { "prefix": "", "suffix": " မှ" }, + "ne": { "prefix": "", "suffix": " द्वारा" }, + "nl": { "prefix": "door ", "suffix": "" }, + "no": { "prefix": "av ", "suffix": "" }, + "or": { "prefix": "", "suffix": " ଦ୍ଵାରା" }, + "pa": { "prefix": "", "suffix": " ਵੱਲੋਂ" }, + "pl": { "prefix": "autor: ", "suffix": "" }, + "pt": { "prefix": "por ", "suffix": "" }, + "pt-PT": { "prefix": "de ", "suffix": "" }, + "ro": { "prefix": "de ", "suffix": "" }, + "ru": { "prefix": "", "suffix": "" }, + "si": { "prefix": "", "suffix": " විසින්" }, + "sk": { "prefix": "Autori: ", "suffix": "" }, + "sl": { "prefix": "kanal ", "suffix": "" }, + "sq": { "prefix": "nga ", "suffix": "" }, + "sr": { "prefix": "са канала ", "suffix": "" }, + "sr-Latn": { "prefix": "sa kanala ", "suffix": "" }, + "sv": { "prefix": "från ", "suffix": "" }, + "sw": { "prefix": "kutoka ", "suffix": "" }, + "ta": { "prefix": "வழங்கியவர்: ", "suffix": "" }, + "te": { "prefix": "", "suffix": " ఛానెల్ ద్వారా" }, + "th": { "prefix": "โดย ", "suffix": "" }, + "tr": { "prefix": "", "suffix": " tarafından" }, + "uk": { "prefix": "власник: ", "suffix": "" }, + "ur": { "prefix": "منجانب ", "suffix": "" }, + "uz": { "prefix": "muallif: ", "suffix": "" }, + "vi": { "prefix": "của ", "suffix": "" }, + "zh-CN": { "prefix": "创建者:", "suffix": "" }, + "zh-HK": { "prefix": "來自", "suffix": "" }, + "zh-TW": { "prefix": "由", "suffix": "建立" }, + "zu": { "prefix": "ka-", "suffix": "" } +} diff --git a/testfiles/dict/dictionary.json b/testfiles/dict/dictionary.json index 0a7032e..d4c47cf 100644 --- a/testfiles/dict/dictionary.json +++ b/testfiles/dict/dictionary.json @@ -55,7 +55,9 @@ "ep": "Ep", "drama": "Show", "enkelsnit": "Single" - } + }, + "chan_prefix": "deur", + "chan_suffix": "" }, "am": { "equivalent": [], @@ -117,7 +119,9 @@ "የተራዘመ አልበም": "Ep", "ትዕይንት": "Show", "ነጠላ": "Single" - } + }, + "chan_prefix": "በ", + "chan_suffix": "" }, "ar": { "equivalent": [], @@ -180,7 +184,9 @@ "ألبوم قصير": "Ep", "عرض": "Show", "أغنية منفردة": "Single" - } + }, + "chan_prefix": "بواسطة", + "chan_suffix": "" }, "as": { "equivalent": [], @@ -226,7 +232,9 @@ "ep": "Ep", "শ্ব’": "Show", "একক": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "ৰ দ্বাৰা" }, "az": { "equivalent": [], @@ -275,7 +283,9 @@ "ep": "Ep", "şou": "Show", "tək": "Single" - } + }, + "chan_prefix": "by", + "chan_suffix": "" }, "be": { "equivalent": [], @@ -349,7 +359,9 @@ "міні-альбом": "Ep", "шоу": "Show", "сінгл": "Single" - } + }, + "chan_prefix": "ад", + "chan_suffix": "" }, "bg": { "equivalent": [], @@ -397,7 +409,9 @@ "миниалбум": "Ep", "предаване": "Show", "сингъл": "Single" - } + }, + "chan_prefix": "от", + "chan_suffix": "" }, "bn": { "equivalent": [], @@ -450,7 +464,9 @@ "ইপি": "Ep", "শো": "Show", "সিঙ্গেল": "Single" - } + }, + "chan_prefix": ",", + "chan_suffix": "দ্বারা" }, "bs": { "equivalent": [], @@ -519,7 +535,9 @@ "ep": "Ep", "serija": "Show", "singl": "Single" - } + }, + "chan_prefix": "od", + "chan_suffix": "" }, "ca": { "equivalent": [], @@ -577,7 +595,9 @@ "ep": "Ep", "programa": "Show", "single": "Single" - } + }, + "chan_prefix": "de:", + "chan_suffix": "" }, "cs": { "equivalent": [], @@ -636,7 +656,9 @@ "ep": "Ep", "zobrazit": "Show", "singl": "Single" - } + }, + "chan_prefix": "autor:", + "chan_suffix": "" }, "da": { "equivalent": [], @@ -693,7 +715,9 @@ "ep": "Ep", "lyddrama": "Show", "single": "Single" - } + }, + "chan_prefix": "af", + "chan_suffix": "" }, "de": { "equivalent": [], @@ -737,7 +761,9 @@ "ep": "Ep", "hörspiel": "Show", "single": "Single" - } + }, + "chan_prefix": "von", + "chan_suffix": "" }, "el": { "equivalent": [], @@ -798,7 +824,9 @@ "ep": "Ep", "εκπομπή": "Show", "single": "Single" - } + }, + "chan_prefix": "από το χρήστη", + "chan_suffix": "" }, "en": { "equivalent": [ @@ -872,7 +900,9 @@ "ep": "Ep", "show": "Show", "single": "Single" - } + }, + "chan_prefix": "by", + "chan_suffix": "" }, "es": { "equivalent": [], @@ -930,7 +960,9 @@ "ep": "Ep", "audiodrama": "Show", "single": "Single" - } + }, + "chan_prefix": "de", + "chan_suffix": "" }, "es-US": { "equivalent": [ @@ -991,7 +1023,9 @@ "ep": "Ep", "programa": "Show", "sencillo": "Single" - } + }, + "chan_prefix": "de", + "chan_suffix": "" }, "et": { "equivalent": [], @@ -1052,7 +1086,9 @@ "ep": "Ep", "sari": "Show", "singel": "Single" - } + }, + "chan_prefix": "kanalilt", + "chan_suffix": "" }, "eu": { "equivalent": [], @@ -1101,7 +1137,9 @@ "ep": "Ep", "saioa": "Show", "singlea": "Single" - } + }, + "chan_prefix": "egilea:", + "chan_suffix": "" }, "fa": { "equivalent": [], @@ -1150,7 +1188,9 @@ "پخش فوق‌العاده": "Ep", "نمایش": "Show", "تک آهنگ": "Single" - } + }, + "chan_prefix": "توسط", + "chan_suffix": "" }, "fi": { "equivalent": [], @@ -1200,7 +1240,9 @@ "ep": "Ep", "näytä": "Show", "single": "Single" - } + }, + "chan_prefix": "tekijä:", + "chan_suffix": "" }, "fil": { "equivalent": [], @@ -1249,7 +1291,9 @@ "ep": "Ep", "palabas": "Show", "single": "Single" - } + }, + "chan_prefix": "ni/ng", + "chan_suffix": "" }, "fr": { "equivalent": [ @@ -1315,7 +1359,9 @@ "émission": "Show", "simple": "Single", "single": "Single" - } + }, + "chan_prefix": "de", + "chan_suffix": "" }, "gl": { "equivalent": [], @@ -1372,7 +1418,9 @@ "ep": "Ep", "programa": "Show", "single": "Single" - } + }, + "chan_prefix": "de", + "chan_suffix": "" }, "gu": { "equivalent": [], @@ -1420,7 +1468,9 @@ "ep": "Ep", "શો": "Show", "સિંગલ": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "દ્વારા" }, "hi": { "equivalent": [], @@ -1472,7 +1522,9 @@ "ईपी": "Ep", "शो": "Show", "सिंगल": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "के ज़रिए" }, "hr": { "equivalent": [], @@ -1540,7 +1592,9 @@ "ep": "Ep", "serija": "Show", "singl": "Single" - } + }, + "chan_prefix": "omogućio kanal", + "chan_suffix": "" }, "hu": { "equivalent": [], @@ -1600,7 +1654,9 @@ "ep": "Ep", "műsor": "Show", "kislemez": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "csatornától" }, "hy": { "equivalent": [], @@ -1654,7 +1710,9 @@ "ep": "Ep", "աուդիոդրամա": "Show", "սինգլ": "Single" - } + }, + "chan_prefix": "հեղինակ՝", + "chan_suffix": "" }, "id": { "equivalent": [], @@ -1708,7 +1766,9 @@ "ep": "Ep", "acara": "Show", "single": "Single" - } + }, + "chan_prefix": "oleh", + "chan_suffix": "" }, "is": { "equivalent": [], @@ -1773,7 +1833,9 @@ "ep": "Ep", "þáttur": "Show", "smáskífa": "Single" - } + }, + "chan_prefix": "eftir", + "chan_suffix": "" }, "it": { "equivalent": [], @@ -1835,7 +1897,9 @@ "ep": "Ep", "programma": "Show", "singolo": "Single" - } + }, + "chan_prefix": "di", + "chan_suffix": "" }, "iw": { "equivalent": [], @@ -1902,7 +1966,9 @@ "מיני-אלבום": "Ep", "תסכית": "Show", "סינגל": "Single" - } + }, + "chan_prefix": "מאת", + "chan_suffix": "" }, "ja": { "equivalent": [], @@ -1934,7 +2000,9 @@ "ep": "Ep", "表示": "Show", "シングル": "Single" - } + }, + "chan_prefix": "作成者:", + "chan_suffix": "" }, "ka": { "equivalent": [], @@ -1988,7 +2056,9 @@ "მინი-ალბომი": "Ep", "ჩვენება": "Show", "სინგლი": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "-ის მიერ" }, "kk": { "equivalent": [], @@ -2043,7 +2113,9 @@ "ep": "Ep", "шоу": "Show", "сингл": "Single" - } + }, + "chan_prefix": "қосқан", + "chan_suffix": "" }, "km": { "equivalent": [], @@ -2091,7 +2163,9 @@ "ep": "Ep", "កម្មវិធីទូរទស្សន៍": "Show", "ចម្រៀងទោល": "Single" - } + }, + "chan_prefix": "ដោយ", + "chan_suffix": "" }, "kn": { "equivalent": [], @@ -2152,7 +2226,9 @@ "ep": "Ep", "ಶೋ": "Show", "ಒಂದೇ": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "ಚಾನಲ್‌ನಿಂದ" }, "ko": { "equivalent": [], @@ -2187,7 +2263,9 @@ "ep": "Ep", "표시": "Show", "싱글": "Single" - } + }, + "chan_prefix": "게시자:", + "chan_suffix": "" }, "ky": { "equivalent": [], @@ -2238,7 +2316,9 @@ "чакан альбом": "Ep", "шоу": "Show", "сингл": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "каналы аркылуу" }, "lo": { "equivalent": [], @@ -2294,7 +2374,9 @@ "ep": "Ep", "ສະແດງ": "Show", "ຊິງເກິນ": "Single" - } + }, + "chan_prefix": "ໂດຍ", + "chan_suffix": "" }, "lt": { "equivalent": [], @@ -2357,7 +2439,9 @@ "mini albumas": "Ep", "serialas": "Show", "singlas": "Single" - } + }, + "chan_prefix": "pridėjo", + "chan_suffix": "" }, "lv": { "equivalent": [], @@ -2423,7 +2507,9 @@ "ep ieraksts": "Ep", "pārraide": "Show", "singls": "Single" - } + }, + "chan_prefix": "autors:", + "chan_suffix": "" }, "mk": { "equivalent": [], @@ -2469,7 +2555,9 @@ "ep": "Ep", "серија": "Show", "сингл": "Single" - } + }, + "chan_prefix": "од", + "chan_suffix": "" }, "ml": { "equivalent": [], @@ -2519,7 +2607,9 @@ "ep": "Ep", "ഷോ": "Show", "സിംഗിൾ": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "മുഖേന" }, "mn": { "equivalent": [], @@ -2560,7 +2650,9 @@ "ep": "Ep", "жүжиг": "Show", "сингл": "Single" - } + }, + "chan_prefix": "сувгийн нэр:", + "chan_suffix": "" }, "mr": { "equivalent": [], @@ -2623,7 +2715,9 @@ "भाग": "Ep", "शो": "Show", "सिंगल": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "द्वारे" }, "ms": { "equivalent": [], @@ -2674,7 +2768,9 @@ "ep": "Ep", "rancangan": "Show", "rekod single": "Single" - } + }, + "chan_prefix": "oleh", + "chan_suffix": "" }, "my": { "equivalent": [], @@ -2729,7 +2825,9 @@ "ep": "Ep", "ရှိုး": "Show", "တစ်ကိုယ်တော်": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "မှ" }, "ne": { "equivalent": [], @@ -2779,7 +2877,9 @@ "ep": "Ep", "टिभी सो": "Show", "एकल एल्बम": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "द्वारा" }, "nl": { "equivalent": [], @@ -2834,7 +2934,9 @@ "ep": "Ep", "aflevering": "Show", "single": "Single" - } + }, + "chan_prefix": "door", + "chan_suffix": "" }, "no": { "equivalent": [], @@ -2898,7 +3000,9 @@ "ep": "Ep", "hørespill": "Show", "singel": "Single" - } + }, + "chan_prefix": "av", + "chan_suffix": "" }, "or": { "equivalent": [], @@ -2959,7 +3063,9 @@ "ep": "Ep", "ଶୋ": "Show", "ସିଙ୍ଗଲ୍": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "ଦ୍ଵାରା" }, "pa": { "equivalent": [], @@ -3011,7 +3117,9 @@ "ep": "Ep", "ਸ਼ੋਅ": "Show", "ਸਿੰਗਲ": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "ਵੱਲੋਂ" }, "pl": { "equivalent": [], @@ -3084,7 +3192,9 @@ "ep": "Ep", "słuchowisko": "Show", "singiel": "Single" - } + }, + "chan_prefix": "autor:", + "chan_suffix": "" }, "pt": { "equivalent": [], @@ -3144,7 +3254,9 @@ "ep": "Ep", "programa": "Show", "single": "Single" - } + }, + "chan_prefix": "por", + "chan_suffix": "" }, "pt-PT": { "equivalent": [], @@ -3188,7 +3300,9 @@ "ep": "Ep", "programa": "Show", "single": "Single" - } + }, + "chan_prefix": "de", + "chan_suffix": "" }, "ro": { "equivalent": [], @@ -3248,7 +3362,9 @@ "ep": "Ep", "emisiune": "Show", "single": "Single" - } + }, + "chan_prefix": "de", + "chan_suffix": "" }, "ru": { "equivalent": [], @@ -3319,7 +3435,9 @@ "ep": "Ep", "аудиошоу": "Show", "сингл": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "" }, "si": { "equivalent": [], @@ -3369,7 +3487,9 @@ "දීවා": "Ep", "සංදර්ශනය": "Show", "තනි": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "විසින්" }, "sk": { "equivalent": [], @@ -3428,7 +3548,9 @@ "ep": "Ep", "relácia": "Show", "singel": "Single" - } + }, + "chan_prefix": "Autori:", + "chan_suffix": "" }, "sl": { "equivalent": [], @@ -3505,7 +3627,9 @@ "ep": "Ep", "oddaja": "Show", "singel": "Single" - } + }, + "chan_prefix": "kanal", + "chan_suffix": "" }, "sq": { "equivalent": [], @@ -3558,7 +3682,9 @@ "ep": "Ep", "shfaq": "Show", "single": "Single" - } + }, + "chan_prefix": "nga", + "chan_suffix": "" }, "sr": { "equivalent": [], @@ -3608,7 +3734,9 @@ "ep": "Ep", "серија": "Show", "сингл": "Single" - } + }, + "chan_prefix": "са канала", + "chan_suffix": "" }, "sr-Latn": { "equivalent": [], @@ -3658,7 +3786,9 @@ "ep": "Ep", "serija": "Show", "singl": "Single" - } + }, + "chan_prefix": "sa kanala", + "chan_suffix": "" }, "sv": { "equivalent": [], @@ -3717,7 +3847,9 @@ "ep": "Ep", "ljuddrama": "Show", "singel": "Single" - } + }, + "chan_prefix": "från", + "chan_suffix": "" }, "sw": { "equivalent": [], @@ -3767,7 +3899,9 @@ "ep": "Ep", "kipindi": "Show", "singo": "Single" - } + }, + "chan_prefix": "kutoka", + "chan_suffix": "" }, "ta": { "equivalent": [], @@ -3830,7 +3964,9 @@ "ep": "Ep", "ஆடியோ ஷோ": "Show", "சிங்கிள்": "Single" - } + }, + "chan_prefix": "வழங்கியவர்:", + "chan_suffix": "" }, "te": { "equivalent": [], @@ -3891,7 +4027,9 @@ "ep": "Ep", "చూపించు": "Show", "సింగిల్": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "ఛానెల్ ద్వారా" }, "th": { "equivalent": [], @@ -3952,7 +4090,9 @@ "ep": "Ep", "รายการ": "Show", "ซิงเกิล": "Single" - } + }, + "chan_prefix": "โดย", + "chan_suffix": "" }, "tr": { "equivalent": [], @@ -4004,7 +4144,9 @@ "ep": "Ep", "program": "Show", "single": "Single" - } + }, + "chan_prefix": "", + "chan_suffix": "tarafından" }, "uk": { "equivalent": [], @@ -4079,7 +4221,9 @@ "мініальбом": "Ep", "аудіодрама": "Show", "сингл": "Single" - } + }, + "chan_prefix": "власник:", + "chan_suffix": "" }, "ur": { "equivalent": [], @@ -4136,7 +4280,9 @@ "ep": "Ep", "شو": "Show", "واحد": "Single" - } + }, + "chan_prefix": "منجانب", + "chan_suffix": "" }, "uz": { "equivalent": [], @@ -4184,7 +4330,9 @@ "ep": "Ep", "shou": "Show", "singl": "Single" - } + }, + "chan_prefix": "muallif:", + "chan_suffix": "" }, "vi": { "equivalent": [], @@ -4217,7 +4365,9 @@ "đĩa nhạc mở rộng (ep)": "Ep", "chương trình": "Show", "đĩa đơn": "Single" - } + }, + "chan_prefix": "của", + "chan_suffix": "" }, "zh-CN": { "equivalent": [], @@ -4251,7 +4401,9 @@ "迷你专辑": "Ep", "广播剧": "Show", "单曲": "Single" - } + }, + "chan_prefix": "创建者:", + "chan_suffix": "" }, "zh-HK": { "equivalent": [], @@ -4284,7 +4436,9 @@ "ep": "Ep", "節目": "Show", "單曲": "Single" - } + }, + "chan_prefix": "來自", + "chan_suffix": "" }, "zh-TW": { "equivalent": [], @@ -4316,7 +4470,9 @@ "ep": "Ep", "節目": "Show", "單曲": "Single" - } + }, + "chan_prefix": "由", + "chan_suffix": "建立" }, "zu": { "equivalent": [], @@ -4380,6 +4536,8 @@ "i-ep": "Ep", "bonisa": "Show", "i-single": "Single" - } + }, + "chan_prefix": "ka-", + "chan_suffix": "" } } diff --git a/testfiles/playlist/playlist_20241011_pageheader.json b/testfiles/playlist/playlist_20241011_pageheader.json new file mode 100644 index 0000000..52591b7 --- /dev/null +++ b/testfiles/playlist/playlist_20241011_pageheader.json @@ -0,0 +1,4986 @@ +{ + "responseContext": { + "visitorData": "CgtQNE9Wb3N1MU1HSSic8Ka4BjIKCgJERRIEEgAgMA%3D%3D", + "serviceTrackingParams": [ + { + "service": "GFEEDBACK", + "params": [ + { + "key": "is_podcast_show_page", + "value": "0" + }, + { + "key": "browse_id", + "value": "VLPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + }, + { + "key": "browse_id_prefix", + "value": "" + }, + { + "key": "logged_in", + "value": "0" + }, + { + "key": "e", + "value": "23804281,23966208,23986027,24004644,24077241,24166867,24181174,24241378,24439361,24453989,24499534,24542367,24547316,24548629,24552798,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51030101,51037346,51037349,51050361,51053689,51057846,51057857,51063643,51064835,51072748,51091058,51095478,51098297,51098299,51101169,51105628,51111738,51112978,51115184,51117318,51124104,51131427,51133103,51138233,51141472,51152050,51157411,51157430,51157432,51157841,51157895,51158514,51160545,51162170,51165467,51169118,51176511,51178314,51178333,51178344,51178355,51178768,51178982,51183909,51184990,51186528,51190652,51195231,51204329,51212458,51217504,51220492,51221011,51221148,51222973,51223962,51224135,51225967,51227037,51227778,51228350,51230241,51230478,51231814,51235078,51237842,51239093,51241028,51242448,51243940,51248255,51248734,51249749,51251610,51251836,51255676,51255680,51255743,51256074,51256084,51257665,51257895,51257900,51257909,51257916,51257945,51258066,51259135,51260456,51265337,51265362,51265373,51266454,51267567,51267746,51272458,51272491,51272508,51272521,51272530,51272580,51272591,51272845,51275146,51275157,51275168,51275179,51275198,51275396,51275785,51276557,51276565,51276640,51279285,51281227,51281875,51282069,51282084,51282792,51284653,51285105,51285417,51287196,51287500,51288824,51289920,51289935,51289938,51289952,51289963,51289976,51290807,51293344,51295132,51295408,51296439,51296900,51298019,51298829,51299291,51299627,51299711,51299724,51299971,51299999,51300012,51300176,51300241,51300414,51300532,51300585,51300699,51300761,51301116,51302082,51302359,51302492,51302680,51303667,51303669,51303790,51303820,51304121,51304156,51304276,51304558,51305582,51305839,51305952,51306259,51307501,51307723,51308059,51309313,51309488,51310323,51310688,51311025,51311040,51311504,51312061,51312144,51312153,51313149,51314677,51314692,51314699,51314710,51314727,51315912,51315919,51315928,51315931,51315942,51315945,51315952,51315961,51315970,51315977,51316846,51317910,51319208" + }, + { + "key": "visitor_data", + "value": "CgtQNE9Wb3N1MU1HSSic8Ka4BjIKCgJERRIEEgAgMA%3D%3D" + } + ] + }, + { + "service": "GOOGLE_HELP", + "params": [ + { + "key": "is_podcast_show_page", + "value": "0" + }, + { + "key": "browse_id", + "value": "VLPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + }, + { + "key": "browse_id_prefix", + "value": "" + } + ] + }, + { + "service": "CSI", + "params": [ + { + "key": "c", + "value": "WEB" + }, + { + "key": "cver", + "value": "2.20241010.09.00" + }, + { + "key": "yt_li", + "value": "0" + }, + { + "key": "GetPlaylist_rid", + "value": "0xa3686798fe4453c8" + } + ] + }, + { + "service": "GUIDED_HELP", + "params": [ + { + "key": "logged_in", + "value": "0" + } + ] + }, + { + "service": "ECATCHER", + "params": [ + { + "key": "client.version", + "value": "2.20241010" + }, + { + "key": "client.name", + "value": "WEB" + } + ] + } + ], + "mainAppWebResponseContext": { + "loggedOut": true, + "trackingParam": "kx_fmPxhoPZRKNSPfjI7eDTbADuo7JuSklsl0zlYYsC30NwRgkuswmIBwOcCE59TDtslLKPQ-SS" + }, + "webResponseContextExtensionData": { + "hasDecorated": true + } + }, + "contents": { + "twoColumnBrowseResultsRenderer": { + "tabs": [ + { + "tabRenderer": { + "selected": true, + "content": { + "sectionListRenderer": { + "contents": [ + { + "itemSectionRenderer": { + "contents": [ + { + "playlistVideoListRenderer": { + "contents": [ + { + "playlistVideoRenderer": { + "videoId": "DXuNJ267Vss", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBQu39qIU8WKbC5KeXQ_a_Kmeq-Mw", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAFnmg4-mRI64nmz4R4GUGo720Jzw", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLClxuSTfYdqfosJClOxA2osI934sw", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCVR7qAVJNM3flwQ_ZYfPS3iujF1w", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "dreamy night ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "dreamy night ♫ by comfi beats 15,316,716 views 4 years ago 4 minutes, 6 seconds" + } + } + }, + "index": { + "simpleText": "1" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CE4QxjQYACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "4 minutes, 6 seconds" + } + }, + "simpleText": "4:06" + }, + "navigationEndpoint": { + "clickTrackingParams": "CE4QxjQYACITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=DXuNJ267Vss&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=1&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "DXuNJ267Vss", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 0, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr4---sn-h0jelne6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=0d7b8d276ebb56cb&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "246", + "trackingParams": "CE4QxjQYACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CFEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CFEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "DXuNJ267Vss", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CFEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "DXuNJ267Vss" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "DXuNJ267Vss" + ] + } + } + ] + } + }, + "trackingParams": "CFEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CFAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "DXuNJ267Vss", + "onAddCommand": { + "clickTrackingParams": "CFAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "DXuNJ267Vss", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CFAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CE4QxjQYACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtEWHVOSjI2N1Zzcw%3D%3D", + "commands": [ + { + "clickTrackingParams": "CE4QxjQYACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CE8QjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CE4QxjQYACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CE4QxjQYACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "4 minutes, 6 seconds" + } + }, + "simpleText": "4:06" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "15M views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "eutMcjJCVqc", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDc3Ycpb5YaNFeHu8Nf5smL25Z07A", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAScc3jmGa81fZ-rdds1pLhsyeHcA", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCukgu31Ut9lp2E4t5BWlzit6JruA", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/eutMcjJCVqc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBjeA0RixBcCP2w53Ke2H43HJ9j9w", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "these days it's hard to find the words ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "these days it's hard to find the words ♫ by comfi beats 1,272,275 views 4 years ago 2 minutes, 48 seconds" + } + } + }, + "index": { + "simpleText": "2" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CEoQxjQYASITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "2 minutes, 48 seconds" + } + }, + "simpleText": "2:48" + }, + "navigationEndpoint": { + "clickTrackingParams": "CEoQxjQYASITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=eutMcjJCVqc&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=2&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "eutMcjJCVqc", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 1, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr3---sn-h0jelne6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=7aeb4c72324256a7&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "168", + "trackingParams": "CEoQxjQYASITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CE0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CE0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "eutMcjJCVqc", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CE0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "eutMcjJCVqc" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "eutMcjJCVqc" + ] + } + } + ] + } + }, + "trackingParams": "CE0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CEwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "eutMcjJCVqc", + "onAddCommand": { + "clickTrackingParams": "CEwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "eutMcjJCVqc", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CEwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CEoQxjQYASITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtldXRNY2pKQ1ZxYw%3D%3D", + "commands": [ + { + "clickTrackingParams": "CEoQxjQYASITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CEsQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CEoQxjQYASITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CEoQxjQYASITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "2 minutes, 48 seconds" + } + }, + "simpleText": "2:48" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "1.2M views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "B5eM3Q3wj0M", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBK3FpJmFmAlA7ALGjJDXrWC-jtfw", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCwzmil8fgPbrAd-ef4T3vzIzmlKg", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBDU2ur1UisffVmAXAG8lXbT49x5Q", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/B5eM3Q3wj0M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBy46YLhKfVL6Wj71RWd1Ru9C3Z0w", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "a vision ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "a vision ♫ by comfi beats 843,353 views 4 years ago 2 minutes, 49 seconds" + } + } + }, + "index": { + "simpleText": "3" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CEYQxjQYAiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "2 minutes, 49 seconds" + } + }, + "simpleText": "2:49" + }, + "navigationEndpoint": { + "clickTrackingParams": "CEYQxjQYAiITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=B5eM3Q3wj0M&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=3&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "B5eM3Q3wj0M", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 2, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr3---sn-h0jeenle.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=07978cdd0df08f43&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "169", + "trackingParams": "CEYQxjQYAiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CEkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CEkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "B5eM3Q3wj0M", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CEkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "B5eM3Q3wj0M" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "B5eM3Q3wj0M" + ] + } + } + ] + } + }, + "trackingParams": "CEkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CEgQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "B5eM3Q3wj0M", + "onAddCommand": { + "clickTrackingParams": "CEgQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "B5eM3Q3wj0M", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CEgQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CEYQxjQYAiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtCNWVNM1Ezd2owTQ%3D%3D", + "commands": [ + { + "clickTrackingParams": "CEYQxjQYAiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CEcQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CEYQxjQYAiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CEYQxjQYAiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "2 minutes, 49 seconds" + } + }, + "simpleText": "2:49" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "843K views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "MJedvm2TE8o", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBtulKIBStuPyBYbBqlE5B4-2xBaQ", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAEgWtwIZHLv5EKCZVIVibIkZLHlg", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSlJy1g4t2np6JK4hBst8b6PA2ew", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/MJedvm2TE8o/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDkDGK867GRxs9b42P7hJkK6B2pRQ", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "a stormy night ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "a stormy night ♫ by comfi beats 1,380,590 views 4 years ago 3 minutes, 22 seconds" + } + } + }, + "index": { + "simpleText": "4" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CEIQxjQYAyITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 22 seconds" + } + }, + "simpleText": "3:22" + }, + "navigationEndpoint": { + "clickTrackingParams": "CEIQxjQYAyITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=MJedvm2TE8o&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=4&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "MJedvm2TE8o", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 3, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr3---sn-h0jeenek.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=30979dbe6d9313ca&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "202", + "trackingParams": "CEIQxjQYAyITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CEUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CEUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "MJedvm2TE8o", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CEUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "MJedvm2TE8o" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "MJedvm2TE8o" + ] + } + } + ] + } + }, + "trackingParams": "CEUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CEQQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "MJedvm2TE8o", + "onAddCommand": { + "clickTrackingParams": "CEQQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "MJedvm2TE8o", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CEQQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CEIQxjQYAyITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtNSmVkdm0yVEU4bw%3D%3D", + "commands": [ + { + "clickTrackingParams": "CEIQxjQYAyITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CEMQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CEIQxjQYAyITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CEIQxjQYAyITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 22 seconds" + } + }, + "simpleText": "3:22" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "1.3M views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "HHKmS7c5ai4", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLArqrLnSpTLA-1qj-yF6AmfrHOsTA", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCOh-S60OM2Hhswihr3Glb1cM1AAg", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBEyk0qxSToWD_g9L3bTrtrsJjhsw", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/HHKmS7c5ai4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDG12RCxjnm4JHG9T8Ow_thj_ecxA", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "unknown waters ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "unknown waters ♫ by comfi beats 707,948 views 4 years ago 1 minute, 56 seconds" + } + } + }, + "index": { + "simpleText": "5" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CD4QxjQYBCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "1 minute, 56 seconds" + } + }, + "simpleText": "1:56" + }, + "navigationEndpoint": { + "clickTrackingParams": "CD4QxjQYBCITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=HHKmS7c5ai4&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=5&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "HHKmS7c5ai4", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 4, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr2---sn-h0jeln7l.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=1c72a64bb7396a2e&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "116", + "trackingParams": "CD4QxjQYBCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CEEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CEEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "HHKmS7c5ai4", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CEEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "HHKmS7c5ai4" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "HHKmS7c5ai4" + ] + } + } + ] + } + }, + "trackingParams": "CEEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CEAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "HHKmS7c5ai4", + "onAddCommand": { + "clickTrackingParams": "CEAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "HHKmS7c5ai4", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CEAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CD4QxjQYBCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtISEttUzdjNWFpNA%3D%3D", + "commands": [ + { + "clickTrackingParams": "CD4QxjQYBCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CD8QjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CD4QxjQYBCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CD4QxjQYBCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "1 minute, 56 seconds" + } + }, + "simpleText": "1:56" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "707K views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "zF32eh6PWPk", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDr2_1EoZ50kzSgDKwJQaY6Pv3WJA", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC44h27mvgtl5QBA_ed1o4kXPieBA", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDm1iJNfB4KbVMoqPMKrWNHIBaBgg", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/zF32eh6PWPk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDCJEQasRwYLo-iK___zZ767PrCWQ", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "wilting memories ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "wilting memories ♫ by comfi beats 797,946 views 4 years ago 1 minute, 48 seconds" + } + } + }, + "index": { + "simpleText": "6" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CDoQxjQYBSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "1 minute, 48 seconds" + } + }, + "simpleText": "1:48" + }, + "navigationEndpoint": { + "clickTrackingParams": "CDoQxjQYBSITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=zF32eh6PWPk&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=6&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "zF32eh6PWPk", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 5, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr5---sn-h0jeenl6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=cc5df67a1e8f58f9&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "108", + "trackingParams": "CDoQxjQYBSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CD0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CD0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "zF32eh6PWPk", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CD0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "zF32eh6PWPk" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "zF32eh6PWPk" + ] + } + } + ] + } + }, + "trackingParams": "CD0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CDwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "zF32eh6PWPk", + "onAddCommand": { + "clickTrackingParams": "CDwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "zF32eh6PWPk", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CDwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CDoQxjQYBSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "Cgt6RjMyZWg2UFdQaw%3D%3D", + "commands": [ + { + "clickTrackingParams": "CDoQxjQYBSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CDsQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CDoQxjQYBSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CDoQxjQYBSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "1 minute, 48 seconds" + } + }, + "simpleText": "1:48" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "797K views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "hbz-8K-pxpY", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDMheaVKp1qI6AOcwrLl2K_U7EnAA", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDSWaobRJuSVZFDf9aj1kHVx6WuXw", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDi33fhhNwD8Rtf56eIrPZV0Wh8ZQ", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/hbz-8K-pxpY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBt77gqVq8oLIUs7njZkvP2EvmTAw", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "sunshine & butterflies ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "sunshine & butterflies ♫ by comfi beats 2,551,746 views 4 years ago 3 minutes, 5 seconds" + } + } + }, + "index": { + "simpleText": "7" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CDYQxjQYBiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 5 seconds" + } + }, + "simpleText": "3:05" + }, + "navigationEndpoint": { + "clickTrackingParams": "CDYQxjQYBiITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=hbz-8K-pxpY&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=7&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "hbz-8K-pxpY", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 6, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr4---sn-h0jeenld.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=85bcfef0afa9c696&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "185", + "trackingParams": "CDYQxjQYBiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CDkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CDkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "hbz-8K-pxpY", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CDkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "hbz-8K-pxpY" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "hbz-8K-pxpY" + ] + } + } + ] + } + }, + "trackingParams": "CDkQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CDgQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "hbz-8K-pxpY", + "onAddCommand": { + "clickTrackingParams": "CDgQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "hbz-8K-pxpY", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CDgQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CDYQxjQYBiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtoYnotOEstcHhwWQ%3D%3D", + "commands": [ + { + "clickTrackingParams": "CDYQxjQYBiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CDcQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CDYQxjQYBiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CDYQxjQYBiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 5 seconds" + } + }, + "simpleText": "3:05" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "2.5M views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "A2zepLiuEJU", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAUpy0PRzet_xrPsGPj2Mw_ik5o0A", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCgYyZQkAGdE25F-zZ6AAHY5GuNjQ", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBWFlbG5J4x8J3pxGC2k_P2O7lKmA", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/A2zepLiuEJU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD6N47yuLYe5m50AwYPX9Cos4RSVA", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "foreverland ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "foreverland ♫ by comfi beats 983,497 views 4 years ago 2 minutes, 26 seconds" + } + } + }, + "index": { + "simpleText": "8" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CDIQxjQYByITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "2 minutes, 26 seconds" + } + }, + "simpleText": "2:26" + }, + "navigationEndpoint": { + "clickTrackingParams": "CDIQxjQYByITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=A2zepLiuEJU&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=8&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "A2zepLiuEJU", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 7, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr2---sn-h0jeenl6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=036cdea4b8ae1095&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "146", + "trackingParams": "CDIQxjQYByITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CDUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CDUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "A2zepLiuEJU", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CDUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "A2zepLiuEJU" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "A2zepLiuEJU" + ] + } + } + ] + } + }, + "trackingParams": "CDUQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CDQQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "A2zepLiuEJU", + "onAddCommand": { + "clickTrackingParams": "CDQQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "A2zepLiuEJU", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CDQQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CDIQxjQYByITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtBMnplcExpdUVKVQ%3D%3D", + "commands": [ + { + "clickTrackingParams": "CDIQxjQYByITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CDMQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CDIQxjQYByITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CDIQxjQYByITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "2 minutes, 26 seconds" + } + }, + "simpleText": "2:26" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "983K views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "5yaY7aG1Lpo", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB-5OLhj51LzsZswqPsGVPOKfkhFA", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDISujKyqhzBYW3SdgC5QTxv7i1KQ", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDBkkukABZ_d3rsEzewfiHimbM2PA", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/5yaY7aG1Lpo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCnqJbFB4UvqIKUQq5xvVH6RQBm7A", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "dreamy nightmares ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "dreamy nightmares ♫ by comfi beats 1,107,163 views 4 years ago 3 minutes, 17 seconds" + } + } + }, + "index": { + "simpleText": "9" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CC4QxjQYCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 17 seconds" + } + }, + "simpleText": "3:17" + }, + "navigationEndpoint": { + "clickTrackingParams": "CC4QxjQYCCITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=5yaY7aG1Lpo&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=9&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "5yaY7aG1Lpo", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 8, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr2---sn-h0jelnes.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=e72698eda1b52e9a&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "197", + "trackingParams": "CC4QxjQYCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CDEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CDEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "5yaY7aG1Lpo", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CDEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "5yaY7aG1Lpo" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "5yaY7aG1Lpo" + ] + } + } + ] + } + }, + "trackingParams": "CDEQ_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CDAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "5yaY7aG1Lpo", + "onAddCommand": { + "clickTrackingParams": "CDAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "5yaY7aG1Lpo", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CDAQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CC4QxjQYCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "Cgs1eWFZN2FHMUxwbw%3D%3D", + "commands": [ + { + "clickTrackingParams": "CC4QxjQYCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CC8QjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CC4QxjQYCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CC4QxjQYCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 17 seconds" + } + }, + "simpleText": "3:17" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "1.1M views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + }, + { + "playlistVideoRenderer": { + "videoId": "WwXJrMhbi-s", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLByFfew80T9RbyU8-EiLyb6HRU4Ww", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCcjh19GL-pWHpkpRD1ioCcyoZcrA", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCa7u5cp-4vH6mDG8HUOKyNTETgtQ", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/WwXJrMhbi-s/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB-vP4BDBiu9PfU-F6DQ75iUsL4xQ", + "width": 336, + "height": 188 + } + ] + }, + "title": { + "runs": [ + { + "text": "comfy vibes ♫" + } + ], + "accessibility": { + "accessibilityData": { + "label": "comfy vibes ♫ by comfi beats 1,854,224 views 4 years ago 3 minutes, 14 seconds" + } + } + }, + "index": { + "simpleText": "10" + }, + "shortBylineText": { + "runs": [ + { + "text": "comfi beats", + "navigationEndpoint": { + "clickTrackingParams": "CCoQxjQYCSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@comfibeats", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCde_xnXu2lPBmRgAp_nq29A", + "canonicalBaseUrl": "/@comfibeats" + } + } + } + ] + }, + "lengthText": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 14 seconds" + } + }, + "simpleText": "3:14" + }, + "navigationEndpoint": { + "clickTrackingParams": "CCoQxjQYCSITCPGkqOzAh4kDFbXkQgUdzt0gpTIKcGxwcF92aWRlb1okVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEHCAwQ-iwYAQ==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=WwXJrMhbi-s&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&index=10&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "WwXJrMhbi-s", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "index": 9, + "params": "OAI%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr3---sn-h0jeln7l.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=5b05c9acc85b8beb&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "lengthSeconds": "194", + "trackingParams": "CCoQxjQYCSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "isPlayable": true, + "menu": { + "menuRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Add to queue" + } + ] + }, + "icon": { + "iconType": "ADD_TO_QUEUE_TAIL" + }, + "serviceEndpoint": { + "clickTrackingParams": "CC0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CC0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "addToPlaylistCommand": { + "openMiniplayer": true, + "videoId": "WwXJrMhbi-s", + "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", + "onCreateListCommand": { + "clickTrackingParams": "CC0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/playlist/create" + } + }, + "createPlaylistServiceEndpoint": { + "videoIds": [ + "WwXJrMhbi-s" + ], + "params": "CAQ%3D" + } + }, + "videoIds": [ + "WwXJrMhbi-s" + ] + } + } + ] + } + }, + "trackingParams": "CC0Q_pgEGAYiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemDownloadRenderer": { + "serviceEndpoint": { + "clickTrackingParams": "CCwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "offlineVideoEndpoint": { + "videoId": "WwXJrMhbi-s", + "onAddCommand": { + "clickTrackingParams": "CCwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "getDownloadActionCommand": { + "videoId": "WwXJrMhbi-s", + "params": "CAIQAA%3D%3D" + } + } + } + }, + "trackingParams": "CCwQ0aoFGAciEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + { + "menuServiceItemRenderer": { + "text": { + "runs": [ + { + "text": "Share" + } + ] + }, + "icon": { + "iconType": "SHARE" + }, + "serviceEndpoint": { + "clickTrackingParams": "CCoQxjQYCSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "CgtXd1hKck1oYmktcw%3D%3D", + "commands": [ + { + "clickTrackingParams": "CCoQxjQYCSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CCsQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CCoQxjQYCSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "hasSeparator": true + } + } + ], + "trackingParams": "CCoQxjQYCSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlayTimeStatusRenderer": { + "text": { + "accessibility": { + "accessibilityData": { + "label": "3 minutes, 14 seconds" + } + }, + "simpleText": "3:14" + }, + "style": "DEFAULT" + } + }, + { + "thumbnailOverlayNowPlayingRenderer": { + "text": { + "runs": [ + { + "text": "Now playing" + } + ] + } + } + } + ], + "videoInfo": { + "runs": [ + { + "text": "1.8M views" + }, + { + "text": " • " + }, + { + "text": "4 years ago" + } + ] + } + } + } + ], + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "isEditable": false, + "canReorder": false, + "trackingParams": "CCkQ7zsYACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "targetId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + } + ], + "trackingParams": "CCgQuy8YACITCPGkqOzAh4kDFbXkQgUdzt0gpQ==" + } + }, + { + "continuationItemRenderer": { + "trigger": "CONTINUATION_TRIGGER_ON_ITEM_SHOWN", + "continuationEndpoint": { + "clickTrackingParams": "CCcQui8iEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/browse" + } + }, + "continuationCommand": { + "token": "4qmFsgJXEiRWTFBMVDJ3Mm9CZjFUWkt5dllfTTZKc0FTczczbS13akx6SDUaCGtnRURDT01JmgIkVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1", + "request": "CONTINUATION_REQUEST_TYPE_BROWSE" + } + } + } + } + ], + "trackingParams": "CCcQui8iEwjxpKjswIeJAxW15EIFHc7dIKU=", + "targetId": "VLPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + }, + "trackingParams": "CCYQ8JMBGAQiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + } + ] + } + }, + "header": { + "pageHeaderRenderer": { + "pageTitle": "LilyPichu", + "content": { + "pageHeaderViewModel": { + "title": { + "dynamicTextViewModel": { + "text": { + "content": "LilyPichu" + }, + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CCUQj-QKIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "visibility": { + "types": "12" + }, + "clientVeSpec": { + "uiType": 176655, + "veCounter": 548284775 + } + } + } + } + } + }, + "metadata": { + "contentMetadataViewModel": { + "metadataRows": [ + { + "metadataParts": [ + { + "avatarStack": { + "avatarStackViewModel": { + "avatars": [ + { + "avatarViewModel": { + "image": { + "sources": [ + { + "url": "https://yt3.ggpht.com/ytc/AIdro_kcjhSY2e8WlYjQABOB65Za8n3QYycNHP9zXwxjKpBfOg=s48-c-k-c0x00ffffff-no-rj", + "width": 48, + "height": 48 + } + ], + "processor": { + "borderImageProcessor": { + "circular": true + } + } + }, + "avatarImageSize": "AVATAR_SIZE_XS" + } + } + ], + "text": { + "content": "by Kevin Ramirez", + "commandRuns": [ + { + "startIndex": 0, + "length": 16, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CCQQi6ULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@XxthekevinramirezxX", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCai7BcI5lrXC2vdc3ySku8A", + "canonicalBaseUrl": "/@XxthekevinramirezxX" + } + } + } + } + ], + "styleRuns": [ + { + "startIndex": 0, + "length": 16, + "fontColor": 4294967295, + "weightLabel": "FONT_WEIGHT_NORMAL" + } + ] + }, + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CCQQi6ULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "visibility": { + "types": "12" + }, + "clientVeSpec": { + "uiType": 184971, + "veCounter": 548284774 + } + } + }, + "accessibilityContext": { + "label": "by Kevin Ramirez" + }, + "commandContext": { + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CCQQi6ULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@XxthekevinramirezxX", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCai7BcI5lrXC2vdc3ySku8A", + "canonicalBaseUrl": "/@XxthekevinramirezxX" + } + } + } + } + } + } + } + } + ] + }, + { + "metadataParts": [ + { + "text": { + "content": "Playlist" + } + }, + { + "text": { + "content": "10 videos" + } + }, + { + "text": { + "content": "856 views" + } + } + ] + } + ], + "delimiter": "•", + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CCMQ9eQKIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "visibility": { + "types": "12" + }, + "clientVeSpec": { + "uiType": 176757, + "veCounter": 548284773 + } + } + } + } + } + }, + "actions": { + "flexibleActionsViewModel": { + "actionsRows": [ + { + "actions": [ + { + "buttonViewModel": { + "iconName": "PLAY_ARROW", + "title": "Play all", + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CCIQ2M8CGAEiEwjxpKjswIeJAxW15EIFHc7dIKVaJFZMUExUMncyb0JmMVRaS3l2WV9NNkpzQVNzNzNtLXdqTHpINZoBAxD6LA==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=DXuNJ267Vss&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "DXuNJ267Vss", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr4---sn-h0jelne6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=0d7b8d276ebb56cb&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + } + }, + "accessibilityText": "Play all", + "style": "BUTTON_VIEW_MODEL_STYLE_OVERLAY", + "trackingParams": "CCIQ2M8CGAEiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "isFullWidth": false, + "type": "BUTTON_VIEW_MODEL_TYPE_FILLED", + "buttonSize": "BUTTON_VIEW_MODEL_SIZE_DEFAULT" + } + }, + { + "toggleButtonViewModel": { + "defaultButtonViewModel": { + "buttonViewModel": { + "iconName": "PLAYLIST_ADD", + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "ignoreNavigation": true + } + }, + "modalEndpoint": { + "modal": { + "modalWithTitleAndButtonRenderer": { + "title": { + "simpleText": "Want to save this playlist?" + }, + "content": { + "simpleText": "Sign in to save this playlist." + }, + "button": { + "buttonRenderer": { + "style": "STYLE_BLUE_TEXT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "text": { + "simpleText": "Sign in" + }, + "navigationEndpoint": { + "clickTrackingParams": "CCEQ_IYEIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "url": "https://accounts.google.com/ServiceLogin?service=youtube&uilel=3&passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3D%252Fplaylist%253Flist%253DPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&hl=en&ec=66428", + "webPageType": "WEB_PAGE_TYPE_UNKNOWN", + "rootVe": 83769 + } + }, + "signInEndpoint": { + "nextEndpoint": { + "clickTrackingParams": "CCEQ_IYEIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "url": "/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "webPageType": "WEB_PAGE_TYPE_PLAYLIST", + "rootVe": 5754, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "VLPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + }, + "idamTag": "66428" + } + }, + "trackingParams": "CCEQ_IYEIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + } + } + } + } + } + }, + "accessibilityText": "Save playlist", + "style": "BUTTON_VIEW_MODEL_STYLE_OVERLAY", + "trackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "isFullWidth": false, + "type": "BUTTON_VIEW_MODEL_TYPE_TONAL", + "buttonSize": "BUTTON_VIEW_MODEL_SIZE_DEFAULT", + "tooltip": "Save playlist" + } + }, + "toggledButtonViewModel": { + "buttonViewModel": { + "iconName": "PLAYLIST_ADD_CHECK", + "accessibilityText": "Remove from Library", + "style": "BUTTON_VIEW_MODEL_STYLE_OVERLAY", + "trackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "isFullWidth": false, + "type": "BUTTON_VIEW_MODEL_TYPE_TONAL", + "buttonSize": "BUTTON_VIEW_MODEL_SIZE_DEFAULT", + "tooltip": "Remove from Library" + } + }, + "isToggled": false, + "identifier": "", + "trackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + }, + { + "buttonViewModel": { + "iconName": "SHARE", + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "EiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1", + "commands": [ + { + "clickTrackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CCAQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + } + }, + "accessibilityText": "Share", + "style": "BUTTON_VIEW_MODEL_STYLE_OVERLAY", + "trackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "isFullWidth": false, + "type": "BUTTON_VIEW_MODEL_TYPE_TONAL", + "buttonSize": "BUTTON_VIEW_MODEL_SIZE_DEFAULT", + "tooltip": "Share" + } + }, + { + "buttonViewModel": { + "iconName": "MORE_VERT", + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "showSheetCommand": { + "panelLoadingStrategy": { + "inlineContent": { + "sheetViewModel": { + "content": { + "listViewModel": { + "listItems": [ + { + "listItemViewModel": { + "title": { + "content": "Shuffle" + }, + "leadingImage": { + "sources": [ + { + "clientResource": { + "imageName": "SHUFFLE" + } + } + ] + }, + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CB8QsssCGAUiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "enableDisplayloggerExperiment": true + } + }, + "commandContext": { + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CB8QsssCGAUiEwjxpKjswIeJAxW15EIFHc7dIKVaJFZMUExUMncyb0JmMVRaS3l2WV9NNkpzQVNzNzNtLXdqTHpINZoBAxD6LA==", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=MJedvm2TE8o&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "MJedvm2TE8o", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "params": "CP0LIAM%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr3---sn-h0jeenek.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=30979dbe6d9313ca&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + } + } + } + } + } + } + ] + } + } + } + } + } + } + } + }, + "accessibilityText": "More actions", + "style": "BUTTON_VIEW_MODEL_STYLE_OVERLAY", + "trackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "isFullWidth": false, + "type": "BUTTON_VIEW_MODEL_TYPE_TONAL", + "buttonSize": "BUTTON_VIEW_MODEL_SIZE_DEFAULT", + "state": "BUTTON_VIEW_MODEL_STATE_ACTIVE", + "enableIconButton": true + } + } + ] + } + ], + "minimumRowHeight": 44, + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CB4QjqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "visibility": { + "types": "12" + }, + "clientVeSpec": { + "uiType": 184974, + "veCounter": 548284772 + } + } + } + } + } + }, + "description": { + "descriptionPreviewViewModel": { + "truncationText": { + "content": "...more", + "styleRuns": [ + { + "startIndex": 0, + "length": 7, + "weight": 500 + } + ] + }, + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CB0Qr_4KIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "visibility": { + "types": "12" + }, + "clientVeSpec": { + "uiType": 180015, + "veCounter": 548284771 + } + } + } + } + } + }, + "heroImage": { + "contentPreviewImageViewModel": { + "image": { + "sources": [ + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLAHp6V96b70x4SWm9Pe6WEHnQhP6A", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCMQBEG5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLDPCehYWYW8HhToloH9MJWD_wKq1w", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCPYBEIoBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLA7aSRV3Ymv8oEFYT7TUpwSZLPbCA", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAYMzfwTTZbTbHcDUK9kIa450u_7g", + "width": 336, + "height": 188 + } + ] + }, + "style": "CONTENT_PREVIEW_IMAGE_STYLE_HORIZONTAL_RECTANGLE_16_BY_9", + "layoutMode": "CONTENT_PREVIEW_IMAGE_LAYOUT_MODE_FULL_WIDTH", + "overlays": [ + { + "thumbnailHoverOverlayViewModel": { + "icon": { + "sources": [ + { + "clientResource": { + "imageName": "PLAY_ALL" + } + } + ] + }, + "text": { + "content": "Play all", + "styleRuns": [ + { + "startIndex": 0, + "length": 8 + } + ] + }, + "style": "THUMBNAIL_HOVER_OVERLAY_STYLE_COVER", + "rendererContext": { + "commandContext": { + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CBwQiqULIhMI8aSo7MCHiQMVteRCBR3O3SClWiRWTFBMVDJ3Mm9CZjFUWkt5dllfTTZKc0FTczczbS13akx6SDWaAQMQ-iw=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=DXuNJ267Vss&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "DXuNJ267Vss", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr4---sn-h0jelne6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=0d7b8d276ebb56cb&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + } + } + } + } + } + } + ], + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CBwQiqULIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "visibility": { + "types": "12" + }, + "clientVeSpec": { + "uiType": 184970, + "veCounter": 548284770 + } + } + }, + "accessibilityContext": { + "label": "Play all" + } + } + } + }, + "background": { + "cinematicContainerViewModel": { + "backgroundImageConfig": { + "image": { + "sources": [ + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLAHp6V96b70x4SWm9Pe6WEHnQhP6A", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCMQBEG5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLDPCehYWYW8HhToloH9MJWD_wKq1w", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCPYBEIoBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLA7aSRV3Ymv8oEFYT7TUpwSZLPbCA", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAYMzfwTTZbTbHcDUK9kIa450u_7g", + "width": 336, + "height": 188 + } + ] + } + }, + "gradientColorConfig": [ + { + "lightThemeColor": 3426562162, + "darkThemeColor": 3426562162, + "startLocation": 0 + }, + { + "lightThemeColor": 1279078514, + "darkThemeColor": 1279078514, + "startLocation": 0.33 + }, + { + "lightThemeColor": 3426562162, + "darkThemeColor": 4279176975, + "startLocation": 1 + } + ], + "config": { + "lightThemeBackgroundColor": 4282200178, + "darkThemeBackgroundColor": 4282200178, + "colorSourceSizeMultiplier": 2, + "applyClientImageBlur": true + } + } + }, + "hasTopbarAnimation": true, + "rendererContext": { + "loggingContext": { + "loggingDirectives": { + "trackingParams": "CBsQot8KIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "visibility": { + "types": "12" + }, + "clientVeSpec": { + "uiType": 176034, + "veCounter": 548284769 + } + } + } + } + } + }, + "enableSidebarView": true + } + }, + "metadata": { + "playlistMetadataRenderer": { + "title": "LilyPichu", + "androidAppindexingLink": "android-app://com.google.android.youtube/http/www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "iosAppindexingLink": "ios-app://544007664/vnd.youtube/www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + }, + "trackingParams": "CAAQhGciEwjxpKjswIeJAxW15EIFHc7dIKU=", + "topbar": { + "desktopTopbarRenderer": { + "logo": { + "topbarLogoRenderer": { + "iconImage": { + "iconType": "YOUTUBE_LOGO" + }, + "tooltipText": { + "runs": [ + { + "text": "YouTube Home" + } + ] + }, + "endpoint": { + "clickTrackingParams": "CBoQsV4iEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/", + "webPageType": "WEB_PAGE_TYPE_BROWSE", + "rootVe": 3854, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "FEwhat_to_watch" + } + }, + "trackingParams": "CBoQsV4iEwjxpKjswIeJAxW15EIFHc7dIKU=", + "overrideEntityKey": "EgZ0b3BiYXIg9QEoAQ%3D%3D" + } + }, + "searchbox": { + "fusionSearchboxRenderer": { + "icon": { + "iconType": "SEARCH" + }, + "placeholderText": { + "runs": [ + { + "text": "Search" + } + ] + }, + "config": { + "webSearchboxConfig": { + "requestLanguage": "en", + "requestDomain": "us", + "hasOnscreenKeyboard": false, + "focusSearchbox": true + } + }, + "trackingParams": "CBgQ7VAiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "searchEndpoint": { + "clickTrackingParams": "CBgQ7VAiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/results?search_query=", + "webPageType": "WEB_PAGE_TYPE_SEARCH", + "rootVe": 4724 + } + }, + "searchEndpoint": { + "query": "" + } + }, + "clearButton": { + "buttonRenderer": { + "style": "STYLE_DEFAULT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "icon": { + "iconType": "CLOSE" + }, + "trackingParams": "CBkQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "accessibilityData": { + "accessibilityData": { + "label": "Clear search query" + } + } + } + } + } + }, + "trackingParams": "CAwQq6wBIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "topbarButtons": [ + { + "topbarMenuButtonRenderer": { + "icon": { + "iconType": "MORE_VERT" + }, + "menuRequest": { + "clickTrackingParams": "CBYQ_qsBGAAiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/account/account_menu" + } + }, + "signalServiceEndpoint": { + "signal": "GET_ACCOUNT_MENU", + "actions": [ + { + "clickTrackingParams": "CBYQ_qsBGAAiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "openPopupAction": { + "popup": { + "multiPageMenuRenderer": { + "trackingParams": "CBcQ_6sBIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "style": "MULTI_PAGE_MENU_STYLE_TYPE_SYSTEM", + "showLoadingSpinner": true + } + }, + "popupType": "DROPDOWN", + "beReused": true + } + } + ] + } + }, + "trackingParams": "CBYQ_qsBGAAiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "accessibility": { + "accessibilityData": { + "label": "Settings" + } + }, + "tooltip": "Settings", + "style": "STYLE_DEFAULT" + } + }, + { + "buttonRenderer": { + "style": "STYLE_SUGGESTIVE", + "size": "SIZE_SMALL", + "text": { + "runs": [ + { + "text": "Sign in" + } + ] + }, + "icon": { + "iconType": "AVATAR_LOGGED_OUT" + }, + "navigationEndpoint": { + "clickTrackingParams": "CBUQ1IAEGAEiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "https://accounts.google.com/ServiceLogin?service=youtube&uilel=3&passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3Dhttps%253A%252F%252Fwww.youtube.com%252Fyoutubei%252Fv1%252Fbrowse%253FprettyPrint%253Dfalse&hl=en&ec=65620", + "webPageType": "WEB_PAGE_TYPE_UNKNOWN", + "rootVe": 83769 + } + }, + "signInEndpoint": { + "idamTag": "65620" + } + }, + "trackingParams": "CBUQ1IAEGAEiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "targetId": "topbar-signin" + } + } + ], + "hotkeyDialog": { + "hotkeyDialogRenderer": { + "title": { + "runs": [ + { + "text": "Keyboard shortcuts" + } + ] + }, + "sections": [ + { + "hotkeyDialogSectionRenderer": { + "title": { + "runs": [ + { + "text": "Playback" + } + ] + }, + "options": [ + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Toggle play/pause" + } + ] + }, + "hotkey": "k" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Rewind 10 seconds" + } + ] + }, + "hotkey": "j" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Fast forward 10 seconds" + } + ] + }, + "hotkey": "l" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Previous video" + } + ] + }, + "hotkey": "P (SHIFT+p)" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Next video" + } + ] + }, + "hotkey": "N (SHIFT+n)" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Previous frame (while paused)" + } + ] + }, + "hotkey": ",", + "hotkeyAccessibilityLabel": { + "accessibilityData": { + "label": "Comma" + } + } + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Next frame (while paused)" + } + ] + }, + "hotkey": ".", + "hotkeyAccessibilityLabel": { + "accessibilityData": { + "label": "Period" + } + } + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Decrease playback rate" + } + ] + }, + "hotkey": "< (SHIFT+,)", + "hotkeyAccessibilityLabel": { + "accessibilityData": { + "label": "Less than or SHIFT + comma" + } + } + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Increase playback rate" + } + ] + }, + "hotkey": "> (SHIFT+.)", + "hotkeyAccessibilityLabel": { + "accessibilityData": { + "label": "Greater than or SHIFT + period" + } + } + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Seek to specific point in the video (7 advances to 70% of duration)" + } + ] + }, + "hotkey": "0..9" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Seek to previous chapter" + } + ] + }, + "hotkey": "CONTROL + ←" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Seek to next chapter" + } + ] + }, + "hotkey": "CONTROL + →" + } + } + ] + } + }, + { + "hotkeyDialogSectionRenderer": { + "title": { + "runs": [ + { + "text": "General" + } + ] + }, + "options": [ + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Toggle full screen" + } + ] + }, + "hotkey": "f" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Toggle theater mode" + } + ] + }, + "hotkey": "t" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Toggle miniplayer" + } + ] + }, + "hotkey": "i" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Close miniplayer or current dialog" + } + ] + }, + "hotkey": "ESCAPE" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Toggle mute" + } + ] + }, + "hotkey": "m" + } + } + ] + } + }, + { + "hotkeyDialogSectionRenderer": { + "title": { + "runs": [ + { + "text": "Subtitles and closed captions" + } + ] + }, + "options": [ + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "If the video supports captions, toggle captions ON/OFF" + } + ] + }, + "hotkey": "c" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Rotate through different text opacity levels" + } + ] + }, + "hotkey": "o" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Rotate through different window opacity levels" + } + ] + }, + "hotkey": "w" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Rotate through font sizes (increasing)" + } + ] + }, + "hotkey": "+" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Rotate through font sizes (decreasing)" + } + ] + }, + "hotkey": "-", + "hotkeyAccessibilityLabel": { + "accessibilityData": { + "label": "Minus" + } + } + } + } + ] + } + }, + { + "hotkeyDialogSectionRenderer": { + "title": { + "runs": [ + { + "text": "Spherical Videos" + } + ] + }, + "options": [ + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Pan up" + } + ] + }, + "hotkey": "w" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Pan left" + } + ] + }, + "hotkey": "a" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Pan down" + } + ] + }, + "hotkey": "s" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Pan right" + } + ] + }, + "hotkey": "d" + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Zoom in" + } + ] + }, + "hotkey": "+ on numpad or ]", + "hotkeyAccessibilityLabel": { + "accessibilityData": { + "label": "Plus on number pad or right bracket" + } + } + } + }, + { + "hotkeyDialogSectionOptionRenderer": { + "label": { + "runs": [ + { + "text": "Zoom out" + } + ] + }, + "hotkey": "- on numpad or [", + "hotkeyAccessibilityLabel": { + "accessibilityData": { + "label": "Minus on number pad or left bracket" + } + } + } + } + ] + } + } + ], + "dismissButton": { + "buttonRenderer": { + "style": "STYLE_BLUE_TEXT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "text": { + "runs": [ + { + "text": "Dismiss" + } + ] + }, + "trackingParams": "CBQQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + "trackingParams": "CBMQteYDIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + }, + "backButton": { + "buttonRenderer": { + "trackingParams": "CBIQvIYDIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "command": { + "clickTrackingParams": "CBIQvIYDIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CBIQvIYDIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "signalAction": { + "signal": "HISTORY_BACK" + } + } + ] + } + } + } + }, + "forwardButton": { + "buttonRenderer": { + "trackingParams": "CBEQvYYDIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "command": { + "clickTrackingParams": "CBEQvYYDIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CBEQvYYDIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "signalAction": { + "signal": "HISTORY_FORWARD" + } + } + ] + } + } + } + }, + "a11ySkipNavigationButton": { + "buttonRenderer": { + "style": "STYLE_DEFAULT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "text": { + "runs": [ + { + "text": "Skip navigation" + } + ] + }, + "trackingParams": "CBAQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "command": { + "clickTrackingParams": "CBAQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CBAQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "signalAction": { + "signal": "SKIP_NAVIGATION" + } + } + ] + } + } + } + }, + "voiceSearchButton": { + "buttonRenderer": { + "style": "STYLE_DEFAULT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "serviceEndpoint": { + "clickTrackingParams": "CA0Q7a8FIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "signal": "CLIENT_SIGNAL", + "actions": [ + { + "clickTrackingParams": "CA0Q7a8FIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "openPopupAction": { + "popup": { + "voiceSearchDialogRenderer": { + "placeholderHeader": { + "runs": [ + { + "text": "Listening..." + } + ] + }, + "promptHeader": { + "runs": [ + { + "text": "Didn't hear that. Try again." + } + ] + }, + "exampleQuery1": { + "runs": [ + { + "text": "\"Play Dua Lipa\"" + } + ] + }, + "exampleQuery2": { + "runs": [ + { + "text": "\"Show me my subscriptions\"" + } + ] + }, + "promptMicrophoneLabel": { + "runs": [ + { + "text": "Tap microphone to try again" + } + ] + }, + "loadingHeader": { + "runs": [ + { + "text": "Working..." + } + ] + }, + "connectionErrorHeader": { + "runs": [ + { + "text": "No connection" + } + ] + }, + "connectionErrorMicrophoneLabel": { + "runs": [ + { + "text": "Check your connection and try again" + } + ] + }, + "permissionsHeader": { + "runs": [ + { + "text": "Waiting for permission" + } + ] + }, + "permissionsSubtext": { + "runs": [ + { + "text": "Allow microphone access to search with voice" + } + ] + }, + "disabledHeader": { + "runs": [ + { + "text": "Search with your voice" + } + ] + }, + "disabledSubtext": { + "runs": [ + { + "text": "To search by voice, go to your browser settings and allow access to microphone" + } + ] + }, + "microphoneButtonAriaLabel": { + "runs": [ + { + "text": "Cancel" + } + ] + }, + "exitButton": { + "buttonRenderer": { + "style": "STYLE_DEFAULT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "icon": { + "iconType": "CLOSE" + }, + "trackingParams": "CA8Q0LEFIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "accessibilityData": { + "accessibilityData": { + "label": "Cancel" + } + } + } + }, + "trackingParams": "CA4Q7q8FIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "microphoneOffPromptHeader": { + "runs": [ + { + "text": "Microphone off. Try again." + } + ] + } + } + }, + "popupType": "TOP_ALIGNED_DIALOG" + } + } + ] + } + }, + "icon": { + "iconType": "MICROPHONE_ON" + }, + "tooltip": "Search with your voice", + "trackingParams": "CA0Q7a8FIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "accessibilityData": { + "accessibilityData": { + "label": "Search with your voice" + } + } + } + } + } + }, + "microformat": { + "microformatDataRenderer": { + "urlCanonical": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "title": "LilyPichu", + "description": "", + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDBEcCw2mrex0rozvhImix0ITAXwA&days_since_epoch=20007", + "width": 480, + "height": 270 + } + ] + }, + "siteName": "YouTube", + "appName": "YouTube", + "androidPackage": "com.google.android.youtube", + "iosAppStoreId": "544007664", + "iosAppArguments": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "ogType": "website", + "urlApplinksWeb": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&feature=applinks", + "urlApplinksIos": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&feature=applinks", + "urlApplinksAndroid": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&feature=applinks", + "urlTwitterIos": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&feature=twitter-deep-link", + "urlTwitterAndroid": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&feature=twitter-deep-link", + "twitterCardType": "summary", + "twitterSiteHandle": "@YouTube", + "schemaDotOrgType": "http://schema.org/WebPage", + "noindex": false, + "unlisted": false, + "linkAlternates": [ + { + "hrefUrl": "http://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + }, + { + "hrefUrl": "android-app://com.google.android.youtube/http/youtube.comhttp://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + }, + { + "hrefUrl": "ios-app://544007664/http/youtube.comhttp://www.youtube.com/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + ] + } + }, + "sidebar": { + "playlistSidebarRenderer": { + "items": [ + { + "playlistSidebarPrimaryInfoRenderer": { + "thumbnailRenderer": { + "playlistVideoThumbnailRenderer": { + "thumbnail": { + "thumbnails": [ + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLAHp6V96b70x4SWm9Pe6WEHnQhP6A", + "width": 168, + "height": 94 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEWCMQBEG5IWvKriqkDCQgBFQAAiEIYAQ==&rs=AOn4CLDPCehYWYW8HhToloH9MJWD_wKq1w", + "width": 196, + "height": 110 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCPYBEIoBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLA7aSRV3Ymv8oEFYT7TUpwSZLPbCA", + "width": 246, + "height": 138 + }, + { + "url": "https://i.ytimg.com/vi/DXuNJ267Vss/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAYMzfwTTZbTbHcDUK9kIa450u_7g", + "width": 336, + "height": 188 + } + ] + }, + "trackingParams": "CAsQy-wJIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + }, + "title": { + "runs": [ + { + "text": "LilyPichu", + "navigationEndpoint": { + "clickTrackingParams": "CAEQk-8CIhMI8aSo7MCHiQMVteRCBR3O3SClWiRWTFBMVDJ3Mm9CZjFUWkt5dllfTTZKc0FTczczbS13akx6SDWaAQMQ-iw=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=DXuNJ267Vss&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "DXuNJ267Vss", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr4---sn-h0jelne6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=0d7b8d276ebb56cb&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + } + } + ] + }, + "stats": [ + { + "runs": [ + { + "text": "10" + }, + { + "text": " videos" + } + ] + }, + { + "simpleText": "856 views" + }, + { + "runs": [ + { + "text": "Last updated on " + }, + { + "text": "Oct 13, 2020" + } + ] + } + ], + "menu": { + "menuRenderer": { + "items": [ + { + "menuNavigationItemRenderer": { + "text": { + "simpleText": "Report playlist" + }, + "icon": { + "iconType": "FLAG" + }, + "navigationEndpoint": { + "clickTrackingParams": "CAEQk-8CIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "ignoreNavigation": true + } + }, + "modalEndpoint": { + "modal": { + "modalWithTitleAndButtonRenderer": { + "title": { + "simpleText": "Need to report the playlist?" + }, + "content": { + "simpleText": "Sign in to report inappropriate content." + }, + "button": { + "buttonRenderer": { + "style": "STYLE_BRAND", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "text": { + "runs": [ + { + "text": "Sign in" + } + ] + }, + "navigationEndpoint": { + "clickTrackingParams": "CAoQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "https://accounts.google.com/ServiceLogin?service=youtube&uilel=3&passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3D%252Fchannel%252FPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&hl=en", + "webPageType": "WEB_PAGE_TYPE_UNKNOWN", + "rootVe": 83769 + } + }, + "signInEndpoint": { + "nextEndpoint": { + "clickTrackingParams": "CAoQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/channel/PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "webPageType": "WEB_PAGE_TYPE_BROWSE", + "rootVe": 6827, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + } + } + }, + "trackingParams": "CAoQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + } + } + } + } + }, + "trackingParams": "CAEQk-8CIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + } + ], + "trackingParams": "CAEQk-8CIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "topLevelButtons": [ + { + "toggleButtonRenderer": { + "style": { + "styleType": "STYLE_TEXT" + }, + "size": { + "sizeType": "SIZE_DEFAULT" + }, + "isToggled": false, + "isDisabled": false, + "defaultIcon": { + "iconType": "PLAYLIST_ADD" + }, + "toggledIcon": { + "iconType": "PLAYLIST_ADD_CHECK" + }, + "trackingParams": "CAgQmE0YCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "defaultTooltip": "Save playlist", + "toggledTooltip": "Remove from Library", + "defaultNavigationEndpoint": { + "clickTrackingParams": "CAgQmE0YCCITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "ignoreNavigation": true + } + }, + "modalEndpoint": { + "modal": { + "modalWithTitleAndButtonRenderer": { + "title": { + "simpleText": "Want to save this playlist?" + }, + "content": { + "simpleText": "Sign in to save this playlist." + }, + "button": { + "buttonRenderer": { + "style": "STYLE_BLUE_TEXT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "text": { + "simpleText": "Sign in" + }, + "navigationEndpoint": { + "clickTrackingParams": "CAkQ_IYEIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "url": "https://accounts.google.com/ServiceLogin?service=youtube&uilel=3&passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3D%252Fplaylist%253Flist%253DPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&hl=en&ec=66428", + "webPageType": "WEB_PAGE_TYPE_UNKNOWN", + "rootVe": 83769 + } + }, + "signInEndpoint": { + "nextEndpoint": { + "clickTrackingParams": "CAkQ_IYEIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "url": "/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "webPageType": "WEB_PAGE_TYPE_PLAYLIST", + "rootVe": 5754, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "VLPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + }, + "idamTag": "66428" + } + }, + "trackingParams": "CAkQ_IYEIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + } + } + } + } + }, + "accessibilityData": { + "accessibilityData": { + "label": "Save playlist" + } + }, + "toggledAccessibilityData": { + "accessibilityData": { + "label": "Remove from Library" + } + } + } + }, + { + "buttonRenderer": { + "style": "STYLE_TEXT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "icon": { + "iconType": "SHUFFLE" + }, + "navigationEndpoint": { + "clickTrackingParams": "CAcQ8FsYCSITCPGkqOzAh4kDFbXkQgUdzt0gpVokVkxQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1mgEDEPos", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=A2zepLiuEJU&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "A2zepLiuEJU", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "params": "CLA-IAc%3D", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr2---sn-h0jeenl6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=036cdea4b8ae1095&ip=79.205.210.218&initcwndbps=1971250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "accessibility": { + "label": "Shuffle play" + }, + "tooltip": "Shuffle play", + "trackingParams": "CAcQ8FsYCSITCPGkqOzAh4kDFbXkQgUdzt0gpQ==" + } + }, + { + "buttonRenderer": { + "style": "STYLE_DEFAULT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "serviceEndpoint": { + "clickTrackingParams": "CAUQ8FsYCiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true, + "apiUrl": "/youtubei/v1/share/get_share_panel" + } + }, + "shareEntityServiceEndpoint": { + "serializedShareEntity": "EiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1", + "commands": [ + { + "clickTrackingParams": "CAUQ8FsYCiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==", + "openPopupAction": { + "popup": { + "unifiedSharePanelRenderer": { + "trackingParams": "CAYQjmIiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "showLoadingSpinner": true + } + }, + "popupType": "DIALOG", + "beReused": true + } + } + ] + } + }, + "icon": { + "iconType": "SHARE" + }, + "accessibility": { + "label": "Share" + }, + "tooltip": "Share", + "trackingParams": "CAUQ8FsYCiITCPGkqOzAh4kDFbXkQgUdzt0gpQ==" + } + } + ], + "accessibility": { + "accessibilityData": { + "label": "Action menu" + } + } + } + }, + "thumbnailOverlays": [ + { + "thumbnailOverlaySidePanelRenderer": { + "text": { + "simpleText": "PLAY ALL" + }, + "icon": { + "iconType": "PLAY_ALL" + } + } + } + ], + "navigationEndpoint": { + "clickTrackingParams": "CAEQk-8CIhMI8aSo7MCHiQMVteRCBR3O3SClWiRWTFBMVDJ3Mm9CZjFUWkt5dllfTTZKc0FTczczbS13akx6SDWaAQMQ-iw=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/watch?v=DXuNJ267Vss&list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5&pp=iAQB8AUB", + "webPageType": "WEB_PAGE_TYPE_WATCH", + "rootVe": 3832 + } + }, + "watchEndpoint": { + "videoId": "DXuNJ267Vss", + "playlistId": "PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "playerParams": "iAQB8AUB", + "loggingContext": { + "vssLoggingContext": { + "serializedContextData": "GiJQTFQydzJvQmYxVFpLeXZZX002SnNBU3M3M20td2pMekg1" + } + }, + "watchEndpointSupportedOnesieConfig": { + "html5PlaybackOnesieConfig": { + "commonConfig": { + "url": "https://rr4---sn-h0jelne6.googlevideo.com/initplayback?source=youtube&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odepv=1&id=0d7b8d276ebb56cb&ip=79.205.210.218&initcwndbps=1851250&mt=1728689816&oweuc=&pxtags=Cg4KAnR4Egg1MTMwMzgyMA&rxtags=Cg4KAnR4Egg1MTMwMzgxOA%2CCg4KAnR4Egg1MTMwMzgxOQ%2CCg4KAnR4Egg1MTMwMzgyMA%2CCg4KAnR4Egg1MTMwMzgyMQ" + } + } + } + } + }, + "description": {}, + "showMoreText": { + "runs": [ + { + "text": "Show more" + } + ] + } + } + }, + { + "playlistSidebarSecondaryInfoRenderer": { + "videoOwner": { + "videoOwnerRenderer": { + "thumbnail": { + "thumbnails": [ + { + "url": "https://yt3.ggpht.com/ytc/AIdro_kcjhSY2e8WlYjQABOB65Za8n3QYycNHP9zXwxjKpBfOg=s48-c-k-c0x00ffffff-no-rj", + "width": 48, + "height": 48 + }, + { + "url": "https://yt3.ggpht.com/ytc/AIdro_kcjhSY2e8WlYjQABOB65Za8n3QYycNHP9zXwxjKpBfOg=s88-c-k-c0x00ffffff-no-rj", + "width": 88, + "height": 88 + }, + { + "url": "https://yt3.ggpht.com/ytc/AIdro_kcjhSY2e8WlYjQABOB65Za8n3QYycNHP9zXwxjKpBfOg=s176-c-k-c0x00ffffff-no-rj", + "width": 176, + "height": 176 + } + ] + }, + "title": { + "runs": [ + { + "text": "Kevin Ramirez", + "navigationEndpoint": { + "clickTrackingParams": "CAQQ4TkiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@XxthekevinramirezxX", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCai7BcI5lrXC2vdc3ySku8A", + "canonicalBaseUrl": "/@XxthekevinramirezxX" + } + } + } + ] + }, + "navigationEndpoint": { + "clickTrackingParams": "CAQQ4TkiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "/@XxthekevinramirezxX", + "webPageType": "WEB_PAGE_TYPE_CHANNEL", + "rootVe": 3611, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "UCai7BcI5lrXC2vdc3ySku8A", + "canonicalBaseUrl": "/@XxthekevinramirezxX" + } + }, + "trackingParams": "CAQQ4TkiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + }, + "button": { + "buttonRenderer": { + "style": "STYLE_DESTRUCTIVE", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "text": { + "runs": [ + { + "text": "Subscribe" + } + ] + }, + "navigationEndpoint": { + "clickTrackingParams": "CAIQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=", + "commandMetadata": { + "webCommandMetadata": { + "ignoreNavigation": true + } + }, + "modalEndpoint": { + "modal": { + "modalWithTitleAndButtonRenderer": { + "title": { + "simpleText": "Want to subscribe to this channel?" + }, + "content": { + "simpleText": "Sign in to subscribe to this channel." + }, + "button": { + "buttonRenderer": { + "style": "STYLE_BLUE_TEXT", + "size": "SIZE_DEFAULT", + "isDisabled": false, + "text": { + "simpleText": "Sign in" + }, + "navigationEndpoint": { + "clickTrackingParams": "CAMQ_YYEIhMI8aSo7MCHiQMVteRCBR3O3SClMglzdWJzY3JpYmU=", + "commandMetadata": { + "webCommandMetadata": { + "url": "https://accounts.google.com/ServiceLogin?service=youtube&uilel=3&passive=true&continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3D%252Fplaylist%253Flist%253DPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5%26continue_action%3DQUFFLUhqbGJjc3lRYkF2cVE4VnlxNTZpX2Q1dTRLcEUzd3xBQ3Jtc0tucXVYNHoyX2lrWm95dTVUaWV2bmNLa2llN2c3ZUFJcU5IaFhEOFFOYXlmVWQ2RlZpejlUWERLdzBnbzJVM1VuVnJqdzRWQXByMWVZOHVidTBXclNqQkVBd3QtRk9iaTBIZXBzbjVFNmswOHQxUmdSR2I3ZXdyYUROUzRmODMyWTV6bVAxbWp1R0pDSnY0eWVIV0xBVmVSSnNJelRMdlFTRmdQc2t0XzJyT05kWHRvZHlmUHUwTmJUaG8wS29kZUJQRHFoMXk&hl=en&ec=66429", + "webPageType": "WEB_PAGE_TYPE_UNKNOWN", + "rootVe": 83769 + } + }, + "signInEndpoint": { + "nextEndpoint": { + "clickTrackingParams": "CAMQ_YYEIhMI8aSo7MCHiQMVteRCBR3O3SCl", + "commandMetadata": { + "webCommandMetadata": { + "url": "/playlist?list=PLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5", + "webPageType": "WEB_PAGE_TYPE_PLAYLIST", + "rootVe": 5754, + "apiUrl": "/youtubei/v1/browse" + } + }, + "browseEndpoint": { + "browseId": "VLPLT2w2oBf1TZKyvY_M6JsASs73m-wjLzH5" + } + }, + "continueAction": "QUFFLUhqbGJjc3lRYkF2cVE4VnlxNTZpX2Q1dTRLcEUzd3xBQ3Jtc0tucXVYNHoyX2lrWm95dTVUaWV2bmNLa2llN2c3ZUFJcU5IaFhEOFFOYXlmVWQ2RlZpejlUWERLdzBnbzJVM1VuVnJqdzRWQXByMWVZOHVidTBXclNqQkVBd3QtRk9iaTBIZXBzbjVFNmswOHQxUmdSR2I3ZXdyYUROUzRmODMyWTV6bVAxbWp1R0pDSnY0eWVIV0xBVmVSSnNJelRMdlFTRmdQc2t0XzJyT05kWHRvZHlmUHUwTmJUaG8wS29kZUJQRHFoMXk", + "idamTag": "66429" + } + }, + "trackingParams": "CAMQ_YYEIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + } + } + } + } + }, + "trackingParams": "CAIQ8FsiEwjxpKjswIeJAxW15EIFHc7dIKU=" + } + } + } + } + ], + "trackingParams": "CAEQk-8CIhMI8aSo7MCHiQMVteRCBR3O3SCl" + } + } +}