From ba06e2c8c8afc36afb80a1257d751ecdd249ea8c Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Fri, 3 Nov 2023 21:46:55 +0100 Subject: [PATCH] fix: a/b test 10: channel about modal --- codegen/src/abtest.rs | 35 +- codegen/src/download_testfiles.rs | 2 +- codegen/src/gen_locales.rs | 47 +- notes/AB_Tests.md | 15 + notes/_img/ab_10.png | Bin 0 -> 44238 bytes src/client/channel.rs | 174 +- src/client/response/channel.rs | 69 +- src/client/response/mod.rs | 11 +- src/client/response/url_endpoint.rs | 12 +- src/client/response/video_item.rs | 81 +- ...ent__channel__tests__map_channel_info.snap | 180 +- src/model/mod.rs | 17 +- src/param/locale.rs | 217 +- src/serializer/text.rs | 8 +- src/util/mod.rs | 23 +- testfiles/channel/channel_info.json | 3683 ++++++----------- tests/youtube.rs | 44 +- 17 files changed, 1686 insertions(+), 2932 deletions(-) create mode 100644 notes/_img/ab_10.png diff --git a/codegen/src/abtest.rs b/codegen/src/abtest.rs index 9d6a4ce..a87873f 100644 --- a/codegen/src/abtest.rs +++ b/codegen/src/abtest.rs @@ -26,6 +26,7 @@ pub enum ABTest { ShortDateFormat = 7, TrackViewcount = 8, PlaylistsForShorts = 9, + ChannelAboutModal = 10, } const TESTS_TO_RUN: [ABTest; 3] = [ @@ -98,6 +99,7 @@ pub async fn run_test( ABTest::ShortDateFormat => short_date_format(&query).await, ABTest::PlaylistsForShorts => playlists_for_shorts(&query).await, ABTest::TrackViewcount => track_viewcount(&query).await, + ABTest::ChannelAboutModal => channel_about_modal(&query).await, } .unwrap(); pb.inc(1); @@ -259,6 +261,16 @@ pub async fn short_date_format(rp: &RustyPipeQuery) -> Result { })) } +pub async fn playlists_for_shorts(rp: &RustyPipeQuery) -> Result { + let playlist = rp.playlist("UUSHh8gHdtzO2tXd593_bjErWg").await?; + let v1 = playlist + .videos + .items + .first() + .ok_or_else(|| anyhow::anyhow!("no videos"))?; + Ok(v1.publish_date_txt.is_none()) +} + pub async fn track_viewcount(rp: &RustyPipeQuery) -> Result { let res = rp.music_search("lieblingsmensch namika").await?; @@ -273,12 +285,19 @@ pub async fn track_viewcount(rp: &RustyPipeQuery) -> Result { Ok(track.view_count.is_some()) } -pub async fn playlists_for_shorts(rp: &RustyPipeQuery) -> Result { - let playlist = rp.playlist("UUSHh8gHdtzO2tXd593_bjErWg").await?; - let v1 = playlist - .videos - .items - .first() - .ok_or_else(|| anyhow::anyhow!("no videos"))?; - Ok(v1.publish_date_txt.is_none()) +pub async fn channel_about_modal(rp: &RustyPipeQuery) -> Result { + let id = "UC2DjFE7Xf11URZqWBigcVOQ"; + 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("\"EgVhYm91dPIGBAoCEgA%3D\"")) } diff --git a/codegen/src/download_testfiles.rs b/codegen/src/download_testfiles.rs index 147db3e..239dabb 100644 --- a/codegen/src/download_testfiles.rs +++ b/codegen/src/download_testfiles.rs @@ -339,7 +339,7 @@ async fn channel_playlists() { } async fn channel_info() { - let json_path = path!(*TESTFILES_DIR / "channel" / "channel_info.json"); + let json_path = path!(*TESTFILES_DIR / "channel" / "channel_info2.json"); if json_path.exists() { return; } diff --git a/codegen/src/gen_locales.rs b/codegen/src/gen_locales.rs index 0f4ad48..fdd0410 100644 --- a/codegen/src/gen_locales.rs +++ b/codegen/src/gen_locales.rs @@ -202,11 +202,20 @@ pub enum Country { .to_owned(); let mut code_lang_array = format!( - "/// Array of all available languages\npub const LANGUAGES: [Language; {}] = [\n", + r#"/// Array of all available languages +/// The languages are sorted by their native names. This array can be used to display +/// a language selection or to get the language code from a language name using binary search. +pub const LANGUAGES: [Language; {}] = [ +"#, languages.len() ); let mut code_country_array = format!( - "/// Array of all available countries\npub const COUNTRIES: [Country; {}] = [\n", + r#"/// Array of all available countries +/// +/// The countries are sorted by their english names. This array can be used to display +/// a country selection or to get the country code from a country name using binary search. +pub const COUNTRIES: [Country; {}] = [ +"#, countries.len() ); @@ -252,9 +261,6 @@ pub enum Country { code_langs += &enum_name; code_langs += ",\n"; - // Language array - writeln!(code_lang_array, " Language::{enum_name},").unwrap(); - // Language names writeln!( code_lang_names, @@ -264,6 +270,24 @@ pub enum Country { } code_langs += "}\n"; + // Language array + let languages_by_name = languages + .iter() + .map(|(k, v)| (v, k)) + .collect::>(); + for code in languages_by_name.values() { + let enum_name = code.split('-').fold(String::new(), |mut output, c| { + let _ = write!( + output, + "{}{}", + c[0..1].to_owned().to_uppercase(), + c[1..].to_owned().to_lowercase() + ); + output + }); + writeln!(code_lang_array, " Language::{enum_name},").unwrap(); + } + for (c, n) in &countries { let enum_name = c[0..1].to_owned().to_uppercase() + &c[1..].to_owned().to_lowercase(); @@ -271,9 +295,6 @@ pub enum Country { writeln!(code_countries, " /// {n}").unwrap(); writeln!(code_countries, " {enum_name},").unwrap(); - // Country array - writeln!(code_country_array, " Country::{enum_name},").unwrap(); - // Country names writeln!( code_country_names, @@ -282,6 +303,16 @@ pub enum Country { .unwrap(); } + // Country array + let countries_by_name = countries + .iter() + .map(|(k, v)| (v, k)) + .collect::>(); + for c in countries_by_name.values() { + let enum_name = c[0..1].to_owned().to_uppercase() + &c[1..].to_owned().to_lowercase(); + writeln!(code_country_array, " Country::{enum_name},").unwrap(); + } + // Add Country::Zz / Global code_countries += " /// Global (can only be used for music charts)\n"; code_countries += " Zz,\n"; diff --git a/notes/AB_Tests.md b/notes/AB_Tests.md index 745b1e1..20efb3b 100644 --- a/notes/AB_Tests.md +++ b/notes/AB_Tests.md @@ -417,3 +417,18 @@ tab. Since the reel items dont include upload date information you can circumvent this new UI by using the mobile client. But that may change in the future. + +## [10] Channel About modal + +- **Encountered on:** 03.11.2023 +- **Impact:** 🟡 Medium +- **Endpoint:** browse (channel info) + +![A/B test 10 screenshot](./_img/ab_10.png) + +YouTube replaced the *About* channel tab with a modal. This changes the way additional +channel metadata has to be fetched. + +The new modal uses a continuation request with a token which can be easily generated. +Attempts to fetch the old about tab with the A/B test enabled will lead to a redirect to +the main tab. diff --git a/notes/_img/ab_10.png b/notes/_img/ab_10.png new file mode 100644 index 0000000000000000000000000000000000000000..21101dd1b314fe1a0de1f70b392b5b937aba090a GIT binary patch literal 44238 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 Q0kIA#%WJ?&pP9Y?Kkl)j+W-In literal 0 HcmV?d00001 diff --git a/src/client/channel.rs b/src/client/channel.rs index 3116348..4af14ee 100644 --- a/src/client/channel.rs +++ b/src/client/channel.rs @@ -1,20 +1,21 @@ use std::fmt::Debug; use serde::Serialize; +use time::OffsetDateTime; use url::Url; use crate::{ error::{Error, ExtractionError}, model::{ paginator::{ContinuationEndpoint, Paginator}, - Channel, ChannelInfo, PlaylistItem, VideoItem, YouTubeItem, + Channel, ChannelInfo, PlaylistItem, VideoItem, }, param::{ChannelOrder, ChannelVideoTab, Language}, - serializer::MapResult, - util::{self, ProtoBuilder}, + serializer::{text::TextComponent, MapResult}, + util::{self, timeago, ProtoBuilder}, }; -use super::{response, ClientType, MapResponse, RustyPipeQuery, YTContext}; +use super::{response, ClientType, MapResponse, QContinuation, RustyPipeQuery, YTContext}; #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] @@ -36,8 +37,6 @@ enum ChannelTab { Live, #[serde(rename = "EglwbGF5bGlzdHMgAQ%3D%3D")] Playlists, - #[serde(rename = "EgVhYm91dPIGBAoCEgA%3D")] - Info, #[serde(rename = "EgZzZWFyY2jyBgQKAloA")] Search, } @@ -126,7 +125,7 @@ impl RustyPipeQuery { let visitor_data = Some(self.get_visitor_data().await?); self.continuation( - order_ctoken(channel_id.as_ref(), tab, order), + order_ctoken(channel_id.as_ref(), tab, order, &random_target()), ContinuationEndpoint::Browse, visitor_data.as_deref(), ) @@ -179,19 +178,17 @@ impl RustyPipeQuery { pub async fn channel_info + Debug>( &self, channel_id: S, - ) -> Result, Error> { + ) -> Result { let channel_id = channel_id.as_ref(); - let context = self.get_context(ClientType::Desktop, true, None).await; - let request_body = QChannel { + let context = self.get_context(ClientType::Desktop, false, None).await; + let request_body = QContinuation { context, - browse_id: channel_id, - params: ChannelTab::Info, - query: None, + continuation: &channel_info_ctoken(channel_id, &random_target()), }; - self.execute_request::( + self.execute_request::( ClientType::Desktop, - "channel_info", + "channel_info2", channel_id, "browse", &request_body, @@ -290,46 +287,64 @@ impl MapResponse>> for response::Channel { } } -impl MapResponse> for response::Channel { +impl MapResponse for response::ChannelAbout { fn map_response( self, - id: &str, + _id: &str, lang: Language, _deobf: Option<&crate::deobfuscate::DeobfData>, - vdata: Option<&str>, - ) -> Result>, ExtractionError> { - let content = map_channel_content(id, self.contents, self.alerts)?; - let channel_data = map_channel( - MapChannelData { - header: self.header, - metadata: self.metadata, - microformat: self.microformat, - visitor_data: self - .response_context - .visitor_data - .or_else(|| vdata.map(str::to_owned)), - has_shorts: content.has_shorts, - has_live: content.has_live, - }, - id, - lang, - )?; + _visitor_data: Option<&str>, + ) -> Result, ExtractionError> { + let ep = self + .on_response_received_endpoints + .into_iter() + .next() + .ok_or(ExtractionError::InvalidData("no received endpoint".into()))?; + let continuations = ep.append_continuation_items_action.continuation_items; + let about = continuations + .c + .into_iter() + .next() + .ok_or(ExtractionError::InvalidData("no aboutChannel data".into()))? + .about_channel_renderer + .metadata + .about_channel_view_model; + let mut warnings = continuations.warnings; - let mut mapper = response::YouTubeListMapper::::new(lang); - mapper.map_response(content.content); - let mut warnings = mapper.warnings; - - let cinfo = mapper.channel_info.unwrap_or_else(|| { - warnings.push("no aboutFullMetadata".to_owned()); - ChannelInfo { - create_date: None, - view_count: None, - links: Vec::new(), - } - }); + let links = about + .links + .into_iter() + .filter_map(|l| { + let lv = l.channel_external_link_view_model; + if let TextComponent::Web { url, .. } = lv.link { + Some((String::from(lv.title), util::sanitize_yt_url(&url))) + } else { + None + } + }) + .collect::>(); Ok(MapResult { - c: combine_channel_data(channel_data.c, cinfo), + c: ChannelInfo { + id: about.channel_id, + url: about.canonical_channel_url, + description: about.description, + subscriber_count: about + .subscriber_count_text + .and_then(|txt| util::parse_large_numstr_or_warn(&txt, lang, &mut warnings)), + video_count: about + .video_count_text + .and_then(|txt| util::parse_numeric_or_warn(&txt, &mut warnings)), + create_date: about.joined_date_text.and_then(|txt| { + timeago::parse_textual_date_or_warn(lang, &txt, &mut warnings) + .map(OffsetDateTime::date) + }), + view_count: about + .view_count_text + .and_then(|txt| util::parse_numeric_or_warn(&txt, &mut warnings)), + country: about.country.and_then(|c| util::country_from_name(&c)), + links, + }, warnings, }) } @@ -549,18 +564,7 @@ fn combine_channel_data(channel_data: Channel<()>, content: T) -> Channel } /// Get the continuation token to fetch channel videos in the given order -fn order_ctoken(channel_id: &str, tab: ChannelVideoTab, order: ChannelOrder) -> String { - _order_ctoken( - channel_id, - tab, - order, - &format!("\n${}", util::random_uuid()), - ) -} - -/// Get the continuation token to fetch channel videos in the given order -/// (fixed targetId for testing) -fn _order_ctoken( +fn order_ctoken( channel_id: &str, tab: ChannelVideoTab, order: ChannelOrder, @@ -589,6 +593,32 @@ fn _order_ctoken( pb.to_base64() } +/// Get the continuation token to fetch channel +fn channel_info_ctoken(channel_id: &str, target_id: &str) -> String { + let mut pb_3 = ProtoBuilder::new(); + pb_3.string(19, target_id); + + let mut pb_110 = ProtoBuilder::new(); + pb_110.embedded(3, pb_3); + + let mut pbi = ProtoBuilder::new(); + pbi.embedded(110, pb_110); + + let mut pb_80226972 = ProtoBuilder::new(); + pb_80226972.string(2, channel_id); + pb_80226972.string(3, &pbi.to_base64()); + + let mut pb = ProtoBuilder::new(); + pb.embedded(80_226_972, pb_80226972); + + pb.to_base64() +} + +/// Create a random UUId to build continuation tokens +fn random_target() -> String { + format!("\n${}", util::random_uuid()) +} + #[cfg(test)] mod tests { use std::{fs::File, io::BufReader}; @@ -604,7 +634,7 @@ mod tests { util::tests::TESTFILES, }; - use super::_order_ctoken; + use super::{channel_info_ctoken, order_ctoken}; #[rstest] #[case::base("videos_base", "UC2DjFE7Xf11URZqWBigcVOQ")] @@ -668,10 +698,10 @@ mod tests { let json_path = path!(*TESTFILES / "channel" / "channel_info.json"); let json_file = File::open(json_path).unwrap(); - let channel: response::Channel = + let channel: response::ChannelAbout = serde_json::from_reader(BufReader::new(json_file)).unwrap(); - let map_res: MapResult> = channel - .map_response("UC2DjFE7Xf11URZqWBigcVOQ", Language::En, None, None) + let map_res: MapResult = channel + .map_response("UC2DjFE7Xf11U-RZqWBigcVOQ", Language::En, None, None) .unwrap(); assert!( @@ -683,10 +713,10 @@ mod tests { } #[test] - fn order_ctoken() { + fn t_order_ctoken() { let channel_id = "UCXuqSBlHAE6Xw-yeJA0Tunw"; - let videos_popular_token = _order_ctoken( + let videos_popular_token = order_ctoken( channel_id, ChannelVideoTab::Videos, ChannelOrder::Popular, @@ -694,7 +724,7 @@ mod tests { ); assert_eq!(videos_popular_token, "4qmFsgJkEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaSDhnWXVHaXg2S2hJbUNpUTJORFl4WkRkak9DMHdNREF3TFRJd05EQXRPRGRoWVMwd09EbGxNRGd5TjJVME1qQVlBZyUzRCUzRA%3D%3D"); - let shorts_popular_token = _order_ctoken( + let shorts_popular_token = order_ctoken( channel_id, ChannelVideoTab::Shorts, ChannelOrder::Popular, @@ -702,7 +732,7 @@ mod tests { ); assert_eq!(shorts_popular_token, "4qmFsgJkEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaSDhnWXVHaXhTS2hJbUNpUTJORFkzT1dabVlpMHdNREF3TFRJMllqTXRZVEZpWkMwMU9ESTBNamxrTW1NM09UUVlBZyUzRCUzRA%3D%3D"); - let live_popular_token = _order_ctoken( + let live_popular_token = order_ctoken( channel_id, ChannelVideoTab::Live, ChannelOrder::Popular, @@ -710,4 +740,12 @@ mod tests { ); assert_eq!(live_popular_token, "4qmFsgJkEhhVQ1h1cVNCbEhBRTZYdy15ZUpBMFR1bncaSDhnWXVHaXh5S2hJbUNpUTJORFk1TXpBMk9TMHdNREF3TFRKaE1XVXRPR00zWkMwMU9ESTBNamxpWkRWaVlUZ1lBZyUzRCUzRA%3D%3D"); } + + #[test] + fn t_channel_info_ctoken() { + let channel_id = "UCh8gHdtzO2tXd593_bjErWg"; + + let token = channel_info_ctoken(channel_id, "\n$655b339a-0000-20b9-92dc-582429d254b4"); + assert_eq!(token, "4qmFsgJgEhhVQ2g4Z0hkdHpPMnRYZDU5M19iakVyV2caRDhnWXJHaW1hQVNZS0pEWTFOV0l6TXpsaExUQXdNREF0TWpCaU9TMDVNbVJqTFRVNE1qUXlPV1F5TlRSaU5BJTNEJTNE"); + } } diff --git a/src/client/response/channel.rs b/src/client/response/channel.rs index 826a663..b6a9259 100644 --- a/src/client/response/channel.rs +++ b/src/client/response/channel.rs @@ -2,10 +2,10 @@ use serde::Deserialize; use serde_with::{rust::deserialize_ignore_any, serde_as, DefaultOnError, VecSkipError}; use super::{ - video_item::YouTubeListRenderer, Alert, ChannelBadge, ContentsRenderer, ResponseContext, - Thumbnails, TwoColumnBrowseResults, + video_item::YouTubeListRenderer, Alert, ChannelBadge, ContentsRenderer, ContinuationActionWrap, + ResponseContext, Thumbnails, TwoColumnBrowseResults, }; -use crate::serializer::text::Text; +use crate::serializer::text::{AttributedText, Text, TextComponent}; #[serde_as] #[derive(Debug, Deserialize)] @@ -145,3 +145,66 @@ pub(crate) struct MicroformatDataRenderer { #[serde(default)] pub tags: Vec, } + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ChannelAbout { + #[serde_as(as = "VecSkipError<_>")] + pub on_response_received_endpoints: Vec>, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct AboutChannelRendererWrap { + pub about_channel_renderer: AboutChannelRenderer, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct AboutChannelRenderer { + pub metadata: ChannelMetadata, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ChannelMetadata { + pub about_channel_view_model: ChannelMetadataView, +} + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ChannelMetadataView { + pub channel_id: String, + pub canonical_channel_url: String, + pub country: Option, + #[serde(default)] + pub description: String, + #[serde_as(as = "Option")] + pub joined_date_text: Option, + #[serde_as(as = "Option")] + pub subscriber_count_text: Option, + #[serde_as(as = "Option")] + pub video_count_text: Option, + #[serde_as(as = "Option")] + pub view_count_text: Option, + #[serde(default)] + pub links: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ExternalLink { + pub channel_external_link_view_model: ExternalLinkInner, +} + +#[serde_as] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct ExternalLinkInner { + #[serde_as(as = "AttributedText")] + pub title: TextComponent, + #[serde_as(as = "AttributedText")] + pub link: TextComponent, +} diff --git a/src/client/response/mod.rs b/src/client/response/mod.rs index 2538963..e914998 100644 --- a/src/client/response/mod.rs +++ b/src/client/response/mod.rs @@ -16,6 +16,7 @@ pub(crate) mod video_details; pub(crate) mod video_item; pub(crate) use channel::Channel; +pub(crate) use channel::ChannelAbout; pub(crate) use music_artist::MusicArtist; pub(crate) use music_artist::MusicArtistAlbums; pub(crate) use music_charts::MusicCharts; @@ -208,7 +209,7 @@ pub(crate) struct Continuation { alias = "onResponseReceivedEndpoints" )] #[serde_as(as = "Option>")] - pub on_response_received_actions: Option>, + pub on_response_received_actions: Option>>, /// Used for channel video rich grid renderer /// /// A/B test seen on 19.10.2022 @@ -217,15 +218,15 @@ pub(crate) struct Continuation { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -pub(crate) struct ContinuationActionWrap { +pub(crate) struct ContinuationActionWrap { #[serde(alias = "reloadContinuationItemsCommand")] - pub append_continuation_items_action: ContinuationAction, + pub append_continuation_items_action: ContinuationAction, } #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -pub(crate) struct ContinuationAction { - pub continuation_items: MapResult>, +pub(crate) struct ContinuationAction { + pub continuation_items: MapResult>, } #[derive(Debug, Deserialize)] diff --git a/src/client/response/url_endpoint.rs b/src/client/response/url_endpoint.rs index bbdee34..fb629fb 100644 --- a/src/client/response/url_endpoint.rs +++ b/src/client/response/url_endpoint.rs @@ -1,7 +1,7 @@ use serde::Deserialize; use serde_with::{serde_as, DefaultOnError}; -use crate::{model::UrlTarget, util}; +use crate::model::UrlTarget; /// navigation/resolve_url response model #[derive(Debug, Deserialize)] @@ -280,14 +280,4 @@ impl NavigationEndpoint { None } } - - /// Get the sanitized URL from a url endpoint - pub(crate) fn url(&self) -> Option { - match self { - NavigationEndpoint::Url { url_endpoint } => { - Some(util::sanitize_yt_url(&url_endpoint.url)) - } - _ => None, - } - } } diff --git a/src/client/response/video_item.rs b/src/client/response/video_item.rs index 3283f42..d25fe40 100644 --- a/src/client/response/video_item.rs +++ b/src/client/response/video_item.rs @@ -6,15 +6,15 @@ use serde_with::{ }; use time::OffsetDateTime; -use super::{url_endpoint::NavigationEndpoint, ChannelBadge, ContinuationEndpoint, Thumbnails}; +use super::{ChannelBadge, ContinuationEndpoint, Thumbnails}; use crate::{ model::{ - Channel, ChannelId, ChannelInfo, ChannelItem, ChannelTag, PlaylistItem, Verification, - VideoItem, YouTubeItem, + Channel, ChannelId, ChannelItem, ChannelTag, PlaylistItem, Verification, VideoItem, + YouTubeItem, }, param::Language, serializer::{ - text::{AccessibilityText, AttributedText, Text, TextComponent}, + text::{AccessibilityText, Text, TextComponent}, MapResult, }, util::{self, timeago, TryRemove}, @@ -48,9 +48,6 @@ pub(crate) enum YouTubeListItem { corrected_query: String, }, - /// Channel metadata (about tab) - ChannelAboutFullMetadataRenderer(ChannelFullMetadata), - /// Contains video on startpage /// /// Seems to be currently A/B tested on the channel page, @@ -358,47 +355,6 @@ pub(crate) struct ReelPlayerHeaderRenderer { pub timestamp_text: String, } -#[serde_as] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct ChannelFullMetadata { - #[serde_as(as = "Text")] - pub joined_date_text: String, - #[serde_as(as = "Option")] - pub view_count_text: Option, - #[serde(default)] - #[serde_as(as = "VecSkipError<_>")] - pub primary_links: Vec, - #[serde(default)] - // #[serde_as(as = "VecSkipError<_>")] - pub links: Vec, -} - -#[serde_as] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct PrimaryLink { - #[serde_as(as = "Text")] - pub title: String, - pub navigation_endpoint: NavigationEndpoint, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct ExternalLink { - pub channel_external_link_view_model: ExternalLinkInner, -} - -#[serde_as] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct ExternalLinkInner { - #[serde_as(as = "AttributedText")] - pub title: TextComponent, - #[serde_as(as = "AttributedText")] - pub link: TextComponent, -} - trait IsLive { fn is_live(&self) -> bool; } @@ -446,7 +402,6 @@ pub(crate) struct YouTubeListMapper { pub warnings: Vec, pub ctoken: Option, pub corrected_query: Option, - pub channel_info: Option, } impl YouTubeListMapper { @@ -458,7 +413,6 @@ impl YouTubeListMapper { warnings: Vec::new(), ctoken: None, corrected_query: None, - channel_info: None, } } @@ -476,7 +430,6 @@ impl YouTubeListMapper { warnings, ctoken: None, corrected_query: None, - channel_info: None, } } @@ -744,32 +697,6 @@ impl YouTubeListMapper { YouTubeListItem::ShowingResultsForRenderer { corrected_query } => { self.corrected_query = Some(corrected_query); } - YouTubeListItem::ChannelAboutFullMetadataRenderer(meta) => { - let mut links = meta - .primary_links - .into_iter() - .filter_map(|l| l.navigation_endpoint.url().map(|url| (l.title, url))) - .collect::>(); - for l in meta.links { - let l = l.channel_external_link_view_model; - if let TextComponent::Web { url, .. } = l.link { - links.push((l.title.into(), util::sanitize_yt_url(&url))); - } - } - - self.channel_info = Some(ChannelInfo { - create_date: timeago::parse_textual_date_or_warn( - self.lang, - &meta.joined_date_text, - &mut self.warnings, - ) - .map(OffsetDateTime::date), - view_count: meta - .view_count_text - .and_then(|txt| util::parse_numeric_or_warn(&txt, &mut self.warnings)), - links, - }); - } YouTubeListItem::RichItemRenderer { content } => { self.map_item(*content); } diff --git a/src/client/snapshots/rustypipe__client__channel__tests__map_channel_info.snap b/src/client/snapshots/rustypipe__client__channel__tests__map_channel_info.snap index 4bb2028..43b8e24 100644 --- a/src/client/snapshots/rustypipe__client__channel__tests__map_channel_info.snap +++ b/src/client/snapshots/rustypipe__client__channel__tests__map_channel_info.snap @@ -2,166 +2,28 @@ source: src/client/channel.rs expression: map_res.c --- -Channel( +ChannelInfo( id: "UC2DjFE7Xf11URZqWBigcVOQ", - name: "EEVblog", - subscriber_count: Some(881000), - avatar: [ - Thumbnail( - url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj", - width: 48, - height: 48, - ), - Thumbnail( - url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s88-c-k-c0x00ffffff-no-rj", - width: 88, - height: 88, - ), - Thumbnail( - url: "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s176-c-k-c0x00ffffff-no-rj", - width: 176, - height: 176, - ), - ], - verification: Verified, + url: "http://www.youtube.com/@EEVblog", description: "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON\'T DO PAID VIDEO SPONSORSHIPS, DON\'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don\'t be offended if I don\'t have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA", - tags: [ - "electronics", - "engineering", - "maker", - "hacker", - "design", - "circuit", - "hardware", - "pic", - "atmel", - "oscilloscope", - "multimeter", - "diy", - "hobby", - "review", - "teardown", - "microcontroller", - "arduino", - "video", - "blog", - "tutorial", - "how-to", - "interview", - "rant", - "industry", - "news", - "mailbag", - "dumpster diving", - "debunking", + subscriber_count: Some(920000), + video_count: Some(1920), + create_date: Some("2009-04-04"), + view_count: Some(199087682), + country: Some(AU), + links: [ + ("EEVblog Web Site", "http://www.eevblog.com/"), + ("Twitter", "http://www.twitter.com/eevblog"), + ("Facebook", "http://www.facebook.com/EEVblog"), + ("EEVdiscover", "https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ"), + ("The EEVblog Forum", "http://www.eevblog.com/forum"), + ("EEVblog Merchandise (T-Shirts)", "http://www.eevblog.com/merch"), + ("EEVblog Donations", "http://www.eevblog.com/donations/"), + ("Patreon", "https://www.patreon.com/eevblog"), + ("SubscribeStar", "https://www.subscribestar.com/eevblog"), + ("The AmpHour Radio Show", "http://www.theamphour.com/"), + ("Flickr", "http://www.flickr.com/photos/eevblog"), + ("EEVblog AMAZON Store", "http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2F&tag=ee04-20&linkCode=ur2&camp=1789&creative=390957"), + ("2nd EEVblog Channel", "http://www.youtube.com/EEVblog2"), ], - vanity_url: Some("https://www.youtube.com/c/EevblogDave"), - banner: [ - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - width: 1060, - height: 175, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - width: 1138, - height: 188, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - width: 1707, - height: 283, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - width: 2120, - height: 351, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - width: 2276, - height: 377, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - width: 2560, - height: 424, - ), - ], - mobile_banner: [ - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - width: 320, - height: 88, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - width: 640, - height: 175, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - width: 960, - height: 263, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - width: 1280, - height: 351, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - width: 1440, - height: 395, - ), - ], - tv_banner: [ - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - width: 320, - height: 180, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - width: 854, - height: 480, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - width: 1280, - height: 720, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - width: 1920, - height: 1080, - ), - Thumbnail( - url: "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - width: 2120, - height: 1192, - ), - ], - has_shorts: false, - has_live: false, - visitor_data: Some("CgszMUUzZDlGLWxiRSipqr2ZBg%3D%3D"), - content: ChannelInfo( - create_date: Some("2009-04-04"), - view_count: Some(186854342), - links: [ - ("EEVblog Web Site", "http://www.eevblog.com/"), - ("Twitter", "http://www.twitter.com/eevblog"), - ("Facebook", "http://www.facebook.com/EEVblog"), - ("EEVdiscover", "https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ"), - ("The EEVblog Forum", "http://www.eevblog.com/forum"), - ("EEVblog Merchandise (T-Shirts)", "http://www.eevblog.com/merch"), - ("EEVblog Donations", "http://www.eevblog.com/donations/"), - ("Patreon", "https://www.patreon.com/eevblog"), - ("SubscribeStar", "https://www.subscribestar.com/eevblog"), - ("The AmpHour Radio Show", "http://www.theamphour.com/"), - ("Flickr", "http://www.flickr.com/photos/eevblog"), - ("EEVblog AMAZON Store", "http://www.amazon.com/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2F&tag=ee04-20&linkCode=ur2&camp=1789&creative=390957"), - ("2nd EEVblog Channel", "http://www.youtube.com/EEVblog2"), - ], - ), ) diff --git a/src/model/mod.rs b/src/model/mod.rs index ffbf652..4bf7b37 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -738,16 +738,31 @@ pub struct Channel { pub content: T, } -/// Additional channel metadata fetched from the "About" tab. +/// Detailed channel information #[serde_as] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[non_exhaustive] pub struct ChannelInfo { + /// Unique YouTube Channel-ID (e.g. `UC-lHJZR3Gqxm24_Vd_AJ5Yw`) + pub id: String, + /// Channel URL + pub url: String, + /// Channel description text + pub description: String, + /// Channel subscriber count + /// + /// [`None`] if the subscriber count was hidden by the owner + /// or could not be parsed. + pub subscriber_count: Option, + /// Channel video count + pub video_count: Option, /// Channel creation date #[serde_as(as = "Option")] pub create_date: Option, /// Channel view count pub view_count: Option, + /// Channel origin country + pub country: Option, /// Links to other websites or social media profiles pub links: Vec<(String, String)>, } diff --git a/src/param/locale.rs b/src/param/locale.rs index 21f049d..e886666 100644 --- a/src/param/locale.rs +++ b/src/param/locale.rs @@ -419,202 +419,207 @@ pub enum Country { } /// Array of all available languages +/// The languages are sorted by their native names. This array can be used to display +/// a language selection or to get the language code from a language name using binary search. pub const LANGUAGES: [Language; 83] = [ Language::Af, - Language::Am, - Language::Ar, - Language::As, Language::Az, - Language::Be, - Language::Bg, - Language::Bn, + Language::Id, + Language::Ms, Language::Bs, Language::Ca, - Language::Cs, Language::Da, Language::De, - Language::El, - Language::En, - Language::EnGb, + Language::Et, Language::EnIn, + Language::EnGb, + Language::En, Language::Es, Language::Es419, Language::EsUs, - Language::Et, Language::Eu, - Language::Fa, - Language::Fi, Language::Fil, Language::Fr, Language::FrCa, Language::Gl, - Language::Gu, - Language::Hi, Language::Hr, - Language::Hu, - Language::Hy, - Language::Id, - Language::Is, + Language::Zu, Language::It, - Language::Iw, - Language::Ja, - Language::Ka, - Language::Kk, - Language::Km, - Language::Kn, - Language::Ko, - Language::Ky, - Language::Lo, - Language::Lt, + Language::Sw, Language::Lv, - Language::Mk, - Language::Ml, - Language::Mn, - Language::Mr, - Language::Ms, - Language::My, - Language::Ne, + Language::Lt, + Language::Hu, Language::Nl, Language::No, - Language::Or, - Language::Pa, + Language::Uz, Language::Pl, - Language::Pt, Language::PtPt, + Language::Pt, Language::Ro, - Language::Ru, - Language::Si, + Language::Sq, Language::Sk, Language::Sl, - Language::Sq, - Language::Sr, Language::SrLatn, + Language::Fi, Language::Sv, - Language::Sw, + Language::Vi, + Language::Tr, + Language::Is, + Language::Cs, + Language::El, + Language::Be, + Language::Bg, + Language::Ky, + Language::Mk, + Language::Mn, + Language::Ru, + Language::Sr, + Language::Uk, + Language::Kk, + Language::Hy, + Language::Iw, + Language::Ur, + Language::Ar, + Language::Fa, + Language::Ne, + Language::Mr, + Language::Hi, + Language::As, + Language::Bn, + Language::Pa, + Language::Gu, + Language::Or, Language::Ta, Language::Te, + Language::Kn, + Language::Ml, + Language::Si, Language::Th, - Language::Tr, - Language::Uk, - Language::Ur, - Language::Uz, - Language::Vi, + Language::Lo, + Language::My, + Language::Ka, + Language::Am, + Language::Km, Language::ZhCn, - Language::ZhHk, Language::ZhTw, - Language::Zu, + Language::ZhHk, + Language::Ja, + Language::Ko, ]; /// Array of all available countries +/// +/// The countries are sorted by their english names. This array can be used to display +/// a country selection or to get the country code from a country name using binary search. pub const COUNTRIES: [Country; 109] = [ - Country::Ae, + Country::Dz, Country::Ar, - Country::At, Country::Au, + Country::At, Country::Az, - Country::Ba, - Country::Bd, - Country::Be, - Country::Bg, Country::Bh, - Country::Bo, - Country::Br, + Country::Bd, Country::By, + Country::Be, + Country::Bo, + Country::Ba, + Country::Br, + Country::Bg, + Country::Kh, Country::Ca, - Country::Ch, Country::Cl, Country::Co, Country::Cr, + Country::Hr, Country::Cy, Country::Cz, - Country::De, Country::Dk, Country::Do, - Country::Dz, Country::Ec, - Country::Ee, Country::Eg, - Country::Es, + Country::Sv, + Country::Ee, Country::Fi, Country::Fr, - Country::Gb, Country::Ge, + Country::De, Country::Gh, Country::Gr, Country::Gt, - Country::Hk, Country::Hn, - Country::Hr, + Country::Hk, Country::Hu, + Country::Is, + Country::In, Country::Id, + Country::Iq, Country::Ie, Country::Il, - Country::In, - Country::Iq, - Country::Is, Country::It, Country::Jm, - Country::Jo, Country::Jp, - Country::Ke, - Country::Kh, - Country::Kr, - Country::Kw, + Country::Jo, Country::Kz, + Country::Ke, + Country::Kw, Country::La, + Country::Lv, Country::Lb, + Country::Ly, Country::Li, - Country::Lk, Country::Lt, Country::Lu, - Country::Lv, - Country::Ly, - Country::Ma, - Country::Me, - Country::Mk, + Country::My, Country::Mt, Country::Mx, - Country::My, - Country::Ng, - Country::Ni, - Country::Nl, - Country::No, + Country::Me, + Country::Ma, Country::Np, + Country::Nl, Country::Nz, + Country::Ni, + Country::Ng, + Country::Mk, + Country::No, Country::Om, - Country::Pa, - Country::Pe, - Country::Pg, - Country::Ph, Country::Pk, - Country::Pl, - Country::Pr, - Country::Pt, + Country::Pa, + Country::Pg, Country::Py, + Country::Pe, + Country::Ph, + Country::Pl, + Country::Pt, + Country::Pr, Country::Qa, Country::Ro, - Country::Rs, Country::Ru, Country::Sa, - Country::Se, - Country::Sg, - Country::Si, - Country::Sk, Country::Sn, - Country::Sv, + Country::Rs, + Country::Sg, + Country::Sk, + Country::Si, + Country::Za, + Country::Kr, + Country::Es, + Country::Lk, + Country::Se, + Country::Ch, + Country::Tw, + Country::Tz, Country::Th, Country::Tn, Country::Tr, - Country::Tw, - Country::Tz, - Country::Ua, Country::Ug, + Country::Ua, + Country::Ae, + Country::Gb, Country::Us, Country::Uy, Country::Ve, Country::Vn, Country::Ye, - Country::Za, Country::Zw, ]; @@ -844,11 +849,7 @@ impl FromStr for Language { Some(pos) => { sub = &sub[..pos]; } - None => { - return Err(Error::Other( - format!("could not parse language `{s}`").into(), - )) - } + None => return Err(Error::Other("could not parse language `{s}`".into())), } } } diff --git a/src/serializer/text.rs b/src/serializer/text.rs index 6b0d877..4d628af 100644 --- a/src/serializer/text.rs +++ b/src/serializer/text.rs @@ -44,13 +44,14 @@ use crate::{ #[serde(untagged)] pub(crate) enum Text { Simple { - #[serde(alias = "simpleText")] + #[serde(alias = "simpleText", alias = "content")] text: String, }, Multiple { #[serde_as(as = "Vec")] runs: Vec, }, + Str(String), } impl<'de> DeserializeAs<'de, String> for Text { @@ -60,7 +61,7 @@ impl<'de> DeserializeAs<'de, String> for Text { { let text = Text::deserialize(deserializer)?; match text { - Text::Simple { text } => Ok(text), + Text::Simple { text } | Text::Str(text) => Ok(text), Text::Multiple { runs } => Ok(runs.join("")), } } @@ -73,7 +74,7 @@ impl<'de> DeserializeAs<'de, Vec> for Text { { let text = Text::deserialize(deserializer)?; match text { - Text::Simple { text } => Ok(vec![text]), + Text::Simple { text } | Text::Str(text) => Ok(vec![text]), Text::Multiple { runs } => Ok(runs), } } @@ -542,6 +543,7 @@ mod tests { }"#, vec!["Abo für ", "MBCkpop", " beenden?"] )] + #[case(r#"{"txt":"Hello World"}"#, vec!["Hello World"])] fn t_deserialize_text(#[case] test_json: &str, #[case] exp: Vec<&str>) { #[serde_as] #[derive(Deserialize)] diff --git a/src/util/mod.rs b/src/util/mod.rs index a29a6d2..be7c50c 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -19,7 +19,11 @@ use rand::Rng; use regex::Regex; use url::Url; -use crate::{error::Error, param::Language, serializer::text::TextComponent}; +use crate::{ + error::Error, + param::{Country, Language, COUNTRIES}, + serializer::text::TextComponent, +}; pub static VIDEO_ID_REGEX: Lazy = Lazy::new(|| Regex::new(r"^[A-Za-z0-9_-]{11}$").unwrap()); pub static CHANNEL_ID_REGEX: Lazy = @@ -462,6 +466,14 @@ pub fn b64_decode>(input: T) -> Result, base64::DecodeErr base64::engine::general_purpose::STANDARD.decode(input) } +/// Get the country from its English name +pub fn country_from_name(name: &str) -> Option { + COUNTRIES + .binary_search_by_key(&name, Country::name) + .ok() + .map(|i| COUNTRIES[i]) +} + /// An iterator over the chars in a string (in str format) pub struct SplitChar<'a> { txt: &'a str, @@ -685,4 +697,13 @@ pub(crate) mod tests { let res = Language::from_str(s).ok(); assert_eq!(res, expect); } + + #[rstest] + #[case("United States", Some(Country::Us))] + #[case("Zimbabwe", Some(Country::Zw))] + #[case("foobar", None)] + fn t_country_from_name(#[case] name: &str, #[case] expect: Option) { + let res = country_from_name(name); + assert_eq!(res, expect); + } } diff --git a/testfiles/channel/channel_info.json b/testfiles/channel/channel_info.json index 939ca6e..d771f46 100644 --- a/testfiles/channel/channel_info.json +++ b/testfiles/channel/channel_info.json @@ -1,321 +1,391 @@ { - "contents": { - "twoColumnBrowseResultsRenderer": { - "tabs": [ - { - "tabRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EghmZWF0dXJlZPIGBAoCMgA%3D" - }, - "clickTrackingParams": "CCsQ8JMBGAUiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/featured", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "title": "Home", - "trackingParams": "CCsQ8JMBGAUiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "tabRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EgZ2aWRlb3PyBgQKAjoA" - }, - "clickTrackingParams": "CCoQ8JMBGAYiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/videos", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "title": "Videos", - "trackingParams": "CCoQ8JMBGAYiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "tabRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EglwbGF5bGlzdHPyBgQKAkIA" - }, - "clickTrackingParams": "CCkQ8JMBGAciEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/playlists", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "title": "Playlists", - "trackingParams": "CCkQ8JMBGAciEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "tabRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "Egljb21tdW5pdHnyBgQKAkoA" - }, - "clickTrackingParams": "CCgQ8JMBGAgiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/community", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "title": "Community", - "trackingParams": "CCgQ8JMBGAgiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "tabRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EgVzdG9yZfIGBAoCGgA%3D" - }, - "clickTrackingParams": "CCcQ8JMBGAkiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/store", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "title": "Store", - "trackingParams": "CCcQ8JMBGAkiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "tabRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EghjaGFubmVsc_IGBAoCUgA%3D" - }, - "clickTrackingParams": "CCYQ8JMBGAoiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/channels", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "title": "Channels", - "trackingParams": "CCYQ8JMBGAoiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "tabRenderer": { - "content": { - "sectionListRenderer": { - "contents": [ - { - "itemSectionRenderer": { - "contents": [ - { - "channelAboutFullMetadataRenderer": { - "avatar": { - "thumbnails": [ - { - "height": 48, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj", - "width": 48 - }, - { - "height": 88, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s88-c-k-c0x00ffffff-no-rj", - "width": 88 - }, - { - "height": 176, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s176-c-k-c0x00ffffff-no-rj", - "width": 176 - } - ] + "onResponseReceivedEndpoints": [ + { + "appendContinuationItemsAction": { + "continuationItems": [ + { + "aboutChannelRenderer": { + "metadata": { + "aboutChannelViewModel": { + "additionalInfoLabel": { + "content": "Channel details", + "styleRuns": [ + { + "length": 15, + "startIndex": 0 + } + ] + }, + "canonicalChannelUrl": "http://www.youtube.com/@EEVblog", + "channelId": "UC2DjFE7Xf11URZqWBigcVOQ", + "country": "Australia", + "customLinksLabel": { + "content": "Links", + "styleRuns": [ + { + "length": 5, + "startIndex": 0 + } + ] + }, + "customUrlOnTap": { + "innertubeCommand": { + "clickTrackingParams": "CAAQhGciEwis363HrqiCAxWfHwYAHc0nDmw=", + "commandMetadata": { + "webCommandMetadata": { + "ignoreNavigation": true + } + }, + "shareEntityEndpoint": { + "serializedShareEntity": "GhhVQzJEakZFN1hmMTFVUlpxV0JpZ2NWT1E%3D", + "sharePanelType": "SHARE_PANEL_TYPE_UNIFIED_SHARE_PANEL" + } + } + }, + "description": "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON'T DO PAID VIDEO SPONSORSHIPS, DON'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don't be offended if I don't have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA", + "descriptionLabel": { + "content": "Description", + "styleRuns": [ + { + "length": 11, + "startIndex": 0 + } + ] + }, + "joinedDateText": { + "content": "Joined Apr 4, 2009", + "styleRuns": [ + { + "length": 18, + "startIndex": 0 + } + ] + }, + "links": [ + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ", + "width": 16 }, - "businessEmailLabel": { - "runs": [ - { - "text": "For business inquiries:" - } - ] + { + "height": 24, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSRO3yoShMv5k2DaoKeuCUuLO7tqU2tq_5dmjuYm6jI5FVUVzAR3hzAYKXBLihGwpLTHHwvZytTudtTbT5BcynVneVmScYFWQD5YeySuJdm44lkuA", + "width": 24 }, - "bypassBusinessEmailCaptcha": false, - "canonicalChannelUrl": "http://www.youtube.com/c/EevblogDave", - "channelId": "UC2DjFE7Xf11URZqWBigcVOQ", - "country": { - "simpleText": "Australia" + { + "height": 32, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRIUJbfp6w0pB_u9CGjMzaTsTI7tiSAdSGBA8Hf6zMS5vjmNxUZEU01jHbVZSLbD05OQVHJDuqOf3H2kubCIp5bt4C73Y3H4zbT64CPQBojEE0HKw", + "width": 32 }, - "countryLabel": { - "runs": [ - { - "deemphasize": true, - "text": "\nLocation:\n " - } - ] + { + "height": 48, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSjc0VmcVmJs-FQFvHFOGGfCa1T2yvy_37_qvLeaEenpYij0Awawk3H_89y3FUOMQfYYoJgGEWOUeqSNiuP2HhWCepbiORY3nOV4rirtii6ZK0Okw", + "width": 48 }, - "description": { - "simpleText": "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON'T DO PAID VIDEO SPONSORSHIPS, DON'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don't be offended if I don't have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA" + { + "height": 50, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcT69ZCUPz_NCxzzBSTaa3UsDtYstRJkHNQDosDuc6opuZoSNQyfeH7q70magR_sCmcOXrhlVt90kJaYfuaxaMinr4NvcvyxLvkxablKlWLUz3dNwQ", + "width": 50 }, - "descriptionLabel": { - "runs": [ - { - "text": "Description" - } - ] + { + "height": 64, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRVbUVWS0NUsck5BjE03J5DCtX6Pddc7dbdTW-UfOYeh68FLygzZKr7m7aCt0gSW7BW1mNleXfBXdT3F2wLroI4OJCX2_hTEvzhpf7N4Vskdn_DvA", + "width": 64 }, - "detailsLabel": { - "runs": [ - { - "text": "Details" - } - ] + { + "height": 96, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTIioE30qOAuAgsby1zHK_3DQ4OM1dudwAsAJeGgsL_t1-VgVsL325ZVzk6jUiMsAUCEIpoGeDm9dCRs6b0G1HTJ-TwMVsZ9TZh5sk0hyuaoUS-PQ", + "width": 96 }, - "joinedDateText": { - "runs": [ - { - "text": "Joined " - }, - { - "text": "Apr 4, 2009" - } - ] + { + "height": 128, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcR4jzSwbUFOQnTnk8rdJjrsB83EHczjKxbbKin2Tzvn0-b-aphjcZNP6_ymFrDzQLic_m2agRA6_JWVrfZTRtmaEU2p9hUr-jy9ON_XmhCSm-8VBus", + "width": 128 }, - "onBusinessEmailRevealClickCommand": { - "clickTrackingParams": "CBgQuy8YACITCNCX8umPrvoCFcXoUQodyk0HAw==", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/channel/reveal_business_email", - "sendPost": true - } - }, - "revealBusinessEmailCommand": {} + { + "height": 180, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTj0M93LmbNQ3X0LfHkLbS80j63DGUfWfQe-HjX-TgO0_h-ff1as0nlf11EZ2OLGra-LaVc4tuO_BR6xd8KoWcG566_zyyjB_rfC8zsNjUWcrZIZyc", + "width": 180 }, - "primaryLinks": [ - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CCUQobIHGAEiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + { + "height": 256, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSe0igGE-TpaxmAu93lpaP5Mj8QreWzoqq-Egda_PGitzD3-ZOoO0bD5bpBFQDVjQnpOu2cEQOwJkohhaYiSJGk6bWt8MogG2OByyg624RjVHSbqoU", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 11, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CBIQobIHGAIiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbWtPX3hfT29YN05DV0hLbnllb1dVV0Rsb29ZQXxBQ3Jtc0tuX1ZTVW9IZExYdkpMcTQwTUxENWphU3R1dWx2RG1xVkIxNkY0Qk5qa2RRZ21kRy15YzI4Z2lOcFNoM3RiOVZNSVczNTRhRnprZFNFWmdITTNzNDItRUc4WEhzcEtKZjgtLWZGNllpbjNReW85SGtJbw&q=http%3A%2F%2Fwww.eevblog.com", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa1NiX0hYdzFzZkdPc3lhOUZ6ZHozTy05QTFyQXxBQ3Jtc0ttVG4tTDRKb0FVUkwzT0d2d2xOd092M3g4Um4yeVJXQTRCb2NrY1pJYW1YSVEyVlBnNk9BVlFSU2FxVkx3WFBCZUUzRTlQY1lVU1lzaWVlVUJWdGV2VzZqcW1mTy1xQXdqNTRsTUVJdHZ0VlkxcGJRSQ&q=http%3A%2F%2Fwww.eevblog.com", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbWtPX3hfT29YN05DV0hLbnllb1dVV0Rsb29ZQXxBQ3Jtc0tuX1ZTVW9IZExYdkpMcTQwTUxENWphU3R1dWx2RG1xVkIxNkY0Qk5qa2RRZ21kRy15YzI4Z2lOcFNoM3RiOVZNSVczNTRhRnprZFNFWmdITTNzNDItRUc4WEhzcEtKZjgtLWZGNllpbjNReW85SGtJbw&q=http%3A%2F%2Fwww.eevblog.com" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa1NiX0hYdzFzZkdPc3lhOUZ6ZHozTy05QTFyQXxBQ3Jtc0ttVG4tTDRKb0FVUkwzT0d2d2xOd092M3g4Um4yeVJXQTRCb2NrY1pJYW1YSVEyVlBnNk9BVlFSU2FxVkx3WFBCZUUzRTlQY1lVU1lzaWVlVUJWdGV2VzZqcW1mTy1xQXdqNTRsTUVJdHZ0VlkxcGJRSQ&q=http%3A%2F%2Fwww.eevblog.com" } - }, - "title": { - "simpleText": "EEVblog Web Site" - }, - "trackingParams": "CCUQobIHGAEiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSnyfGgzwnk19b891nCqykpMzr3jlkKm0Z65gNVJbtXsk9-gzW5EiqqEvM02nZyYKmI2x1JQI9OuGsWU69bgq9_rNrHCYrXLP6HqhP9iVwr0bm2IQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CCQQobIHGAIiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "eevblog.com" + }, + "title": { + "content": "EEVblog Web Site" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSnyfGgzwnk19b891nCqykpMzr3jlkKm0Z65gNVJbtXsk9-gzW5EiqqEvM02nZyYKmI2x1JQI9OuGsWU69bgq9_rNrHCYrXLP6HqhP9iVwr0bm2IQ", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcScCAZA1pWe29pjcrDQ6ARryPtvg1JzLCqkwhF6damck941gd8uDg_jxeFgVG7t3DqkSXq2egnOMb07AGBBn3Q6Zg95j7Iro9M1D_CSCVpUPQbRzw", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRpQXrl3L7Mh9_WhjFYD823T6DTyA6HEAOepg7_UMgQ7mwTd7OrCd0CsdcYiX6moKSPUH907oroRJrs-VOKiIVAU9CgUGhxvPMa1cLzLtcwRWIx2A", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRcmurwwdiD-gN00M74VmxNy57-L302TT4xgD49uw4ejJfOIP_yJkssnKNfiyeWT7GfGlX8XJBXrwPv_72R7LJcTQX24kzySpixmFGKytFUfpHZ6Q", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcTPRhtaw3kt4XYlip73DgoHG_ERUbPgYJP8QoThvpfTj4Llwa1YQKIPJkBJYSyEZ3BuVGo7lKWYvAJ3VHVbSb-279au9kdvNg6p3BbPHK1IRNTkag", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSdPY-HkyqXBC5OxvGsPoKZ67TvqoXlt9m50r5_RjKodEza608Tie-MDqpYB1Te-Snc-vDXU5kAEjnA9tsA_840ZiF0wh4iDASnuazpeR_oRH5tzw", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRcADsxfrGPrKjkJVxF0TH8uREzOhAbtAXxfAnPEUCYSxFE8gnUb-xRv7Oig5zQt3oarUs7RtqKJKB_4C7RVNblRPtB2OfWK9XTBn0UIFxk5TbbuA", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRilnE8pw1jlpQcH8L3o9D_FHJcGQi6IcaN-HYxBbsGVViHVeiZHmag5b8biEsFdAoaVh_T7u5t1_1Ip5U9sttsmUiJmEsFUWqBmHutNQOWjKznCrw", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcQV-kyjo0dRmiYBr5B0I6hU5rB5a8WrWxPvfSR76Psy5JXGznp60J9_7jfVVXk41BW0aQwr9xgVC88g6SvEnnAZwzs-fQrNMLQaI5AHC0JMbFIyfqs", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSca19F4khsR_Gvs4fJj-8RGK6A_gVRdQIz3wd-c1My9_pVi5a-vFN5FJ-QwAe_Te5gL8R06bZkdTH2Zl2bSRtznEu3H-BILV3tCQ_0U92zwGdBOag", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 19, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CBEQobIHGAMiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa0NBT2M1UkV5ejJZbXNITWdaRFh4QmNaQ0Rxd3xBQ3Jtc0tscXlScUJZWjFVUGNwampKUGwxbWVoQU9HRHFfdGZpTmxuMEY3bGlEV000em15bExiZGhiM09WSlp4cXlpWVk0OWFMdE1Wei1vYzh4aGgtS1gtUDFCb2tsOFZyU3BFSW1HdXh6OU1peThJWTBrNnZlbw&q=http%3A%2F%2Fwww.twitter.com%2Feevblog", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqazZQR1hvdnF4TGZFTVM1WFdERzRoa2lCYS04d3xBQ3Jtc0ttblJLVFdHZmppbzdwdVZWZEtFWXZURFNCYzlnU1lkOC00dVdVbm5lb3FLalZpZDY3MFNuSUx0N0VJOHdNUGxLRTdac1N2MjZaRF9EdTFKOXd3WXRiV3BMVElmRHJPc2l3T0taWTkwclFsUU9QTVRrZw&q=http%3A%2F%2Fwww.twitter.com%2Feevblog", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa0NBT2M1UkV5ejJZbXNITWdaRFh4QmNaQ0Rxd3xBQ3Jtc0tscXlScUJZWjFVUGNwampKUGwxbWVoQU9HRHFfdGZpTmxuMEY3bGlEV000em15bExiZGhiM09WSlp4cXlpWVk0OWFMdE1Wei1vYzh4aGgtS1gtUDFCb2tsOFZyU3BFSW1HdXh6OU1peThJWTBrNnZlbw&q=http%3A%2F%2Fwww.twitter.com%2Feevblog" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqazZQR1hvdnF4TGZFTVM1WFdERzRoa2lCYS04d3xBQ3Jtc0ttblJLVFdHZmppbzdwdVZWZEtFWXZURFNCYzlnU1lkOC00dVdVbm5lb3FLalZpZDY3MFNuSUx0N0VJOHdNUGxLRTdac1N2MjZaRF9EdTFKOXd3WXRiV3BMVElmRHJPc2l3T0taWTkwclFsUU9QTVRrZw&q=http%3A%2F%2Fwww.twitter.com%2Feevblog" } - }, - "title": { - "simpleText": "Twitter" - }, - "trackingParams": "CCQQobIHGAIiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRmQS0-yT-68TopCQcxwbvtkTB0rdiUtc7g4WFZBVWFT4tJ8tSTon4n5uCmm9_b69_7bgTNZNmFw3-zyF-kWNXXZJEBTm_-r1qZrKLyDfCYxiEXY50" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CCMQobIHGAMiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "twitter.com/eevblog" + }, + "title": { + "content": "Twitter" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRmQS0-yT-68TopCQcxwbvtkTB0rdiUtc7g4WFZBVWFT4tJ8tSTon4n5uCmm9_b69_7bgTNZNmFw3-zyF-kWNXXZJEBTm_-r1qZrKLyDfCYxiEXY50", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcS8otgTiKPgqN8mKk_rEms8i-dD0fPpajLNtgX3i9Ltnwt2zOCwlQE7ohhSyjTmX_QmmtwRwXswtvHnCQMTp4BzIkGSH5VrQOhhEvLPWGzOm6K_lko", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcSQwKmCiL86h8J5lhsv_kTzPmGIeRf8tpUu4kdbMKHdpA_hS8PXW8j57tZ07ZtmlIpZbh7K2YaLfDzL_pfkwnugANQd4D9yQ7aYkElDR1Az1Gq4xyc", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcQtIIRFpUFfy65PMCPCAAmH2b-wyOlfC3t6ZhPXPGUvOHz-BJiArv0mfVApyLvbyIPXBgvbIZyMWsVEWevJ0UU9yULa3WqKR4ZQdyhdxb_0ySw9aJ0", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcQh8ek3XunoGAkVEDYUaXBZ58HJx0vM9r-Z_YtKhr_uPPMNqkH05gPJaCZQx3zJrGRWHRvNiOF9W0bidd-IXQdN4XthC1d4ckyebYwEtWuZO0nucCM", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeUOxWnqrDefQZi8PgarCi1oZd40iUDem-3Ga-62W7B9uaZpMfXXVl9SfRPgmNCFYlBjlWW56IGy_pqbO-FdmLXo_nqQca0FqOo-LVQn5xzB09JU0", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRGO_28W535adEPw3Cq1zrUQ9fip21lsuPafoDtbTbD8rEnIBnZcwEkUIqwAgNBqqLU5ntuRPXHU0OKr45_SVfGTDYRB83nzudGuyQpd4x0ITlF52A", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcS5CVDk95gkKYbGrFxRwYkKEkPXTnut3B_-KAXuP2RDhs_1pSYgjx08rZd_8I3cGu9M8jy-p6mWDhoBYbJlNRByhZMGbqbTh7IW5abtfKiSaMUx53U7", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRfzOKlcHk8k6zchfRr9Jn5QIa6JREy2wav2z8MXLK9VNWeMfnWelcecYVNhaO8wJ0iKwRswuxmSThRZCw1eZp4ylFsdNSgouEbSFEwFjUwmM8mZeu-", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcQ2LIUEtAkaYZrdof_ncH1T3Qqx6XwbcIKf5Dree6ALdc661BOJg524uzYrEGAmkD11Lc4yDSlhkanMbzxY9IRL9Iimne1LKoXC9kWZLL2JC_TAXhXT", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 20, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CBAQobIHGAQiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbEZNRmEzZ05TbUxQaE1lVzRhOUd3MktPcmM0Z3xBQ3Jtc0ttck5kdXFBMGlWc3E3aTh1UTc2UWV5YXJFeVozbkl3enV6bXJsZ3huRmgtaTFXcDdXcG1pVWgycWg1NzdEMDQ3bEdSMzVjRWFkQjVQWnVsQ3FyYmRNOUN2RGkzLS0yYW9VTFNISDFqYjg4enNwRWExWQ&q=http%3A%2F%2Fwww.facebook.com%2FEEVblog", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa0RwZWhBMnNUWXFPV2o3Rmt1NzRhQ3VEQjhhQXxBQ3Jtc0ttSTdTUDMtWlRlX28zUzJ5LXNidGt2YmFTV1ZWMWo0TUUwSnpOSHB4NUQ3MlNSMFU0Ui1xOGJfb1MzekhYTGt4T3puRFY5UG5FUDZyem5MQmpZeXc2RkNHX0E3dDVLN1VOdTdSbTBPaEtXR08ydnROVQ&q=http%3A%2F%2Fwww.facebook.com%2FEEVblog", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbEZNRmEzZ05TbUxQaE1lVzRhOUd3MktPcmM0Z3xBQ3Jtc0ttck5kdXFBMGlWc3E3aTh1UTc2UWV5YXJFeVozbkl3enV6bXJsZ3huRmgtaTFXcDdXcG1pVWgycWg1NzdEMDQ3bEdSMzVjRWFkQjVQWnVsQ3FyYmRNOUN2RGkzLS0yYW9VTFNISDFqYjg4enNwRWExWQ&q=http%3A%2F%2Fwww.facebook.com%2FEEVblog" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa0RwZWhBMnNUWXFPV2o3Rmt1NzRhQ3VEQjhhQXxBQ3Jtc0ttSTdTUDMtWlRlX28zUzJ5LXNidGt2YmFTV1ZWMWo0TUUwSnpOSHB4NUQ3MlNSMFU0Ui1xOGJfb1MzekhYTGt4T3puRFY5UG5FUDZyem5MQmpZeXc2RkNHX0E3dDVLN1VOdTdSbTBPaEtXR08ydnROVQ&q=http%3A%2F%2Fwww.facebook.com%2FEEVblog" } - }, - "title": { - "simpleText": "Facebook" - }, - "trackingParams": "CCMQobIHGAMiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcRY4no9kYJtEAHXBEY2GDprV__HH1zc94olyS6G6fT5isS71bPyqvIi7-9VE1MMy3_3vsNOQLAerwcSQqGNyADWfxKpd2hLc8HuacZdgEjgZc_WLN8" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CCIQobIHGAQiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "facebook.com/EEVblog" + }, + "title": { + "content": "Facebook" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcRY4no9kYJtEAHXBEY2GDprV__HH1zc94olyS6G6fT5isS71bPyqvIi7-9VE1MMy3_3vsNOQLAerwcSQqGNyADWfxKpd2hLc8HuacZdgEjgZc_WLN8", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcR3bOXx13RY_obv-voM2TlthNpZMagIsgiu8wV9zd57RK5F8fQRcX8ZEWdYeqOhdF9-f-phFxphm8gcg6O-DjRJTkWxXlK8N7CTfLdOA5lD_ThPvP4", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcQK5VoWBWTP7Ca7anSCgAxMQf1k1TanOES5v9d-Cvsi9IgVh1v8PELi_eaSU-gpcfF4RHtEteDc0sD6AznYZ_vg3GtGigex4dpmwp39A6Tpz34UyAg", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcSvLexm8CmfHe1mWIhDwUpNa8k4W7FcoaDZ06FA3L8eynFgpea0H8hnnXafsIzd3SSOVPaZrVIXgA0JtmGGApMNR2IWHH5CoLpYEwsNBlJefu9T8q8", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcTkqbHEhNZwnQSrMwokjIhrt0Znyf5tvA7NvjJhjRD3ciZSWNIhNYDVUZaAdALePpQ6nHQZcciA8m8C3xuM_FVBtRMDNakswvL8Zq07dbyikCXgjTo", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcSZFktJQ7FEgRVlbSuaa1asP7-PYreh8SgOHqwUSbvNQftPWbmYjFqQzBTg5IbiFTRONPscrGoHQamkRRCA-pH9oluygYrxjyKrQiZHKB2ZW060914", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcRWkaZm4SFATrThoHcIEbjkNod9w0wtEceD2y2CT7updp3wKpDpWpoTyhndKu49gRzzIJJR80T_OygsgIKZsrOLSwDUrratDfLhVpP_eX59hpxKL4M", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcRELoD6mOxIwfWGX_oINw_1Sla5T2wM9QR7lnwMC_eM5JVGu0XUxkJkGzcOtqKCYDwIjDQRLfLgV_dFdpxxaZGzZ0YUS9alEqzVDYbtc4yj88cPk8KB", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcTWpG-7KVv4rTjF6NvDiCm6IYxH6Ye_MndNVoQ6PICDpfPfbPgjb3HD9abahrUwwV_wD5oFjdxaRbWchddCSpxgdUUdt6trZbfIbv4TXkpP4pwsbS0q", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcQeYEn7J_6R4HhkWWEfFuyPIN4Fz9EWNsVKCSiKtM6rSbZqKHYn0KuxjptJmIxZl7ita5EkI9cuETexUPlSl6brI8VE5jqAWA7srAcLl1QpcboEx_70", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 44, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CA8QobIHGAUiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, @@ -327,246 +397,777 @@ "nofollow": true, "url": "https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ" } - }, - "title": { - "simpleText": "EEVdiscover" - }, - "trackingParams": "CCIQobIHGAQiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CCEQobIHGAUiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ" + }, + "title": { + "content": "EEVdiscover" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSRO3yoShMv5k2DaoKeuCUuLO7tqU2tq_5dmjuYm6jI5FVUVzAR3hzAYKXBLihGwpLTHHwvZytTudtTbT5BcynVneVmScYFWQD5YeySuJdm44lkuA", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRIUJbfp6w0pB_u9CGjMzaTsTI7tiSAdSGBA8Hf6zMS5vjmNxUZEU01jHbVZSLbD05OQVHJDuqOf3H2kubCIp5bt4C73Y3H4zbT64CPQBojEE0HKw", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSjc0VmcVmJs-FQFvHFOGGfCa1T2yvy_37_qvLeaEenpYij0Awawk3H_89y3FUOMQfYYoJgGEWOUeqSNiuP2HhWCepbiORY3nOV4rirtii6ZK0Okw", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcT69ZCUPz_NCxzzBSTaa3UsDtYstRJkHNQDosDuc6opuZoSNQyfeH7q70magR_sCmcOXrhlVt90kJaYfuaxaMinr4NvcvyxLvkxablKlWLUz3dNwQ", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRVbUVWS0NUsck5BjE03J5DCtX6Pddc7dbdTW-UfOYeh68FLygzZKr7m7aCt0gSW7BW1mNleXfBXdT3F2wLroI4OJCX2_hTEvzhpf7N4Vskdn_DvA", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTIioE30qOAuAgsby1zHK_3DQ4OM1dudwAsAJeGgsL_t1-VgVsL325ZVzk6jUiMsAUCEIpoGeDm9dCRs6b0G1HTJ-TwMVsZ9TZh5sk0hyuaoUS-PQ", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcR4jzSwbUFOQnTnk8rdJjrsB83EHczjKxbbKin2Tzvn0-b-aphjcZNP6_ymFrDzQLic_m2agRA6_JWVrfZTRtmaEU2p9hUr-jy9ON_XmhCSm-8VBus", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTj0M93LmbNQ3X0LfHkLbS80j63DGUfWfQe-HjX-TgO0_h-ff1as0nlf11EZ2OLGra-LaVc4tuO_BR6xd8KoWcG566_zyyjB_rfC8zsNjUWcrZIZyc", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSe0igGE-TpaxmAu93lpaP5Mj8QreWzoqq-Egda_PGitzD3-ZOoO0bD5bpBFQDVjQnpOu2cEQOwJkohhaYiSJGk6bWt8MogG2OByyg624RjVHSbqoU", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 17, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CA4QobIHGAYiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa3lZaE8tLVBneVh2R3Z5TXplU2wzbUVRcVJ1Z3xBQ3Jtc0trQnl4NVltWkFDa3hXVUZzQ0o4UHo2dENwX3ZYaklNQzZNNDJrUFBtOVVFemVsSU4zaTd6UmZJYWRWck9mU0d1UEtZYXBQSUxkc1k0Zi1fU1BmQWVnY09NSU1KXzN1M2RsaDVnT1hsbHk0YmRLNWNlTQ&q=http%3A%2F%2Fwww.eevblog.com%2Fforum", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqblQ3NGhVMnR6R29DQkF4WDFDdHc1aE1sZkdmd3xBQ3Jtc0ttdHhMWk1aSjdaRE8zX3AtN0l2eXhhTXBiMXNLLTBtTFJaWTg1eS1PeGlGVHZ0cTdlc0dKUGFrNHJzUjA2RDU2bGFTVEZPZkEzaHV6aGduWWl6V25ETFhEMHhTYUZOUWZNckNIR3gtMVY1bzliYlFmbw&q=http%3A%2F%2Fwww.eevblog.com%2Fforum", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa3lZaE8tLVBneVh2R3Z5TXplU2wzbUVRcVJ1Z3xBQ3Jtc0trQnl4NVltWkFDa3hXVUZzQ0o4UHo2dENwX3ZYaklNQzZNNDJrUFBtOVVFemVsSU4zaTd6UmZJYWRWck9mU0d1UEtZYXBQSUxkc1k0Zi1fU1BmQWVnY09NSU1KXzN1M2RsaDVnT1hsbHk0YmRLNWNlTQ&q=http%3A%2F%2Fwww.eevblog.com%2Fforum" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqblQ3NGhVMnR6R29DQkF4WDFDdHc1aE1sZkdmd3xBQ3Jtc0ttdHhMWk1aSjdaRE8zX3AtN0l2eXhhTXBiMXNLLTBtTFJaWTg1eS1PeGlGVHZ0cTdlc0dKUGFrNHJzUjA2RDU2bGFTVEZPZkEzaHV6aGduWWl6V25ETFhEMHhTYUZOUWZNckNIR3gtMVY1bzliYlFmbw&q=http%3A%2F%2Fwww.eevblog.com%2Fforum" } - }, - "title": { - "simpleText": "The EEVblog Forum" - }, - "trackingParams": "CCEQobIHGAUiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CCAQobIHGAYiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "eevblog.com/forum" + }, + "title": { + "content": "The EEVblog Forum" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSRO3yoShMv5k2DaoKeuCUuLO7tqU2tq_5dmjuYm6jI5FVUVzAR3hzAYKXBLihGwpLTHHwvZytTudtTbT5BcynVneVmScYFWQD5YeySuJdm44lkuA", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRIUJbfp6w0pB_u9CGjMzaTsTI7tiSAdSGBA8Hf6zMS5vjmNxUZEU01jHbVZSLbD05OQVHJDuqOf3H2kubCIp5bt4C73Y3H4zbT64CPQBojEE0HKw", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSjc0VmcVmJs-FQFvHFOGGfCa1T2yvy_37_qvLeaEenpYij0Awawk3H_89y3FUOMQfYYoJgGEWOUeqSNiuP2HhWCepbiORY3nOV4rirtii6ZK0Okw", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcT69ZCUPz_NCxzzBSTaa3UsDtYstRJkHNQDosDuc6opuZoSNQyfeH7q70magR_sCmcOXrhlVt90kJaYfuaxaMinr4NvcvyxLvkxablKlWLUz3dNwQ", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRVbUVWS0NUsck5BjE03J5DCtX6Pddc7dbdTW-UfOYeh68FLygzZKr7m7aCt0gSW7BW1mNleXfBXdT3F2wLroI4OJCX2_hTEvzhpf7N4Vskdn_DvA", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTIioE30qOAuAgsby1zHK_3DQ4OM1dudwAsAJeGgsL_t1-VgVsL325ZVzk6jUiMsAUCEIpoGeDm9dCRs6b0G1HTJ-TwMVsZ9TZh5sk0hyuaoUS-PQ", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcR4jzSwbUFOQnTnk8rdJjrsB83EHczjKxbbKin2Tzvn0-b-aphjcZNP6_ymFrDzQLic_m2agRA6_JWVrfZTRtmaEU2p9hUr-jy9ON_XmhCSm-8VBus", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTj0M93LmbNQ3X0LfHkLbS80j63DGUfWfQe-HjX-TgO0_h-ff1as0nlf11EZ2OLGra-LaVc4tuO_BR6xd8KoWcG566_zyyjB_rfC8zsNjUWcrZIZyc", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSe0igGE-TpaxmAu93lpaP5Mj8QreWzoqq-Egda_PGitzD3-ZOoO0bD5bpBFQDVjQnpOu2cEQOwJkohhaYiSJGk6bWt8MogG2OByyg624RjVHSbqoU", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 17, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CA0QobIHGAciEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbHY3a0x2WU5BMTJ0SmlqVEVVay1pMW9Jc2c2Z3xBQ3Jtc0tsYktFRk4xLXNJQ1NfZDZlcVZrSVN0QWlidjcxZEY2bFpSTWVGNTJIUXJGdkhDeEJMX2lFLTVBaHNXSXlvUTVQcUhTNUcwVUktRVJuUVdCc3Ftd2F5T3VNNnRfelYtR05ENGFPaTFHOGpuajh5YzlEQQ&q=http%3A%2F%2Fwww.eevblog.com%2Fmerch", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqblVUZlV5UzZ6TmZISGd4dm5Hb1d6X3h1RzRiQXxBQ3Jtc0ttbGU4anZXVnR2VlpYNFFlU2tqbldzVkFfZGVaTTQyaUhhbUhlMU1YYkU3TThjekh5UFRKWWxUOUNuTmxraEVLcWprZkVRRjVlNzl4UzByUHktY01NRTN6ODluSzNWR0U4UWp1NC1wWXNHdjI3TUkxQQ&q=http%3A%2F%2Fwww.eevblog.com%2Fmerch", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbHY3a0x2WU5BMTJ0SmlqVEVVay1pMW9Jc2c2Z3xBQ3Jtc0tsYktFRk4xLXNJQ1NfZDZlcVZrSVN0QWlidjcxZEY2bFpSTWVGNTJIUXJGdkhDeEJMX2lFLTVBaHNXSXlvUTVQcUhTNUcwVUktRVJuUVdCc3Ftd2F5T3VNNnRfelYtR05ENGFPaTFHOGpuajh5YzlEQQ&q=http%3A%2F%2Fwww.eevblog.com%2Fmerch" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqblVUZlV5UzZ6TmZISGd4dm5Hb1d6X3h1RzRiQXxBQ3Jtc0ttbGU4anZXVnR2VlpYNFFlU2tqbldzVkFfZGVaTTQyaUhhbUhlMU1YYkU3TThjekh5UFRKWWxUOUNuTmxraEVLcWprZkVRRjVlNzl4UzByUHktY01NRTN6ODluSzNWR0U4UWp1NC1wWXNHdjI3TUkxQQ&q=http%3A%2F%2Fwww.eevblog.com%2Fmerch" } - }, - "title": { - "simpleText": "EEVblog Merchandise (T-Shirts)" - }, - "trackingParams": "CCAQobIHGAYiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CB8QobIHGAciEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "eevblog.com/merch" + }, + "title": { + "content": "EEVblog Merchandise (T-Shirts)" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSRO3yoShMv5k2DaoKeuCUuLO7tqU2tq_5dmjuYm6jI5FVUVzAR3hzAYKXBLihGwpLTHHwvZytTudtTbT5BcynVneVmScYFWQD5YeySuJdm44lkuA", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRIUJbfp6w0pB_u9CGjMzaTsTI7tiSAdSGBA8Hf6zMS5vjmNxUZEU01jHbVZSLbD05OQVHJDuqOf3H2kubCIp5bt4C73Y3H4zbT64CPQBojEE0HKw", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSjc0VmcVmJs-FQFvHFOGGfCa1T2yvy_37_qvLeaEenpYij0Awawk3H_89y3FUOMQfYYoJgGEWOUeqSNiuP2HhWCepbiORY3nOV4rirtii6ZK0Okw", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcT69ZCUPz_NCxzzBSTaa3UsDtYstRJkHNQDosDuc6opuZoSNQyfeH7q70magR_sCmcOXrhlVt90kJaYfuaxaMinr4NvcvyxLvkxablKlWLUz3dNwQ", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRVbUVWS0NUsck5BjE03J5DCtX6Pddc7dbdTW-UfOYeh68FLygzZKr7m7aCt0gSW7BW1mNleXfBXdT3F2wLroI4OJCX2_hTEvzhpf7N4Vskdn_DvA", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTIioE30qOAuAgsby1zHK_3DQ4OM1dudwAsAJeGgsL_t1-VgVsL325ZVzk6jUiMsAUCEIpoGeDm9dCRs6b0G1HTJ-TwMVsZ9TZh5sk0hyuaoUS-PQ", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcR4jzSwbUFOQnTnk8rdJjrsB83EHczjKxbbKin2Tzvn0-b-aphjcZNP6_ymFrDzQLic_m2agRA6_JWVrfZTRtmaEU2p9hUr-jy9ON_XmhCSm-8VBus", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTj0M93LmbNQ3X0LfHkLbS80j63DGUfWfQe-HjX-TgO0_h-ff1as0nlf11EZ2OLGra-LaVc4tuO_BR6xd8KoWcG566_zyyjB_rfC8zsNjUWcrZIZyc", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSe0igGE-TpaxmAu93lpaP5Mj8QreWzoqq-Egda_PGitzD3-ZOoO0bD5bpBFQDVjQnpOu2cEQOwJkohhaYiSJGk6bWt8MogG2OByyg624RjVHSbqoU", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 21, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAwQobIHGAgiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqblZ3bHNZVy11YW1IWjhHR0FIdEpQMVJoWVpOd3xBQ3Jtc0ttbnVFV2JHWnRBVUhLaE83WmpKZU4xYi1GVS0tSTVjYUtGck5zUkgyVl94VXQtakNYU0xsOER1SWdjcVhSVlQ0TWszUWNHT3pFNzVKVGZESzBRcGwwdVVlb1k2cm5LaklXcDBMN3NSdjZ5NTk5S2JGSQ&q=http%3A%2F%2Fwww.eevblog.com%2Fdonations%2F", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbkdmREdPTlIzY2pSZ2RfX1NvRTNzZVVncEdxUXxBQ3Jtc0tuQUlockhNQ2NDV2xhQkNoMWUyM2ZnU2Jac3NkZlVKR1RtV1gyNk1fRWVrLTJDY1JiUHloRGVIeGh0blhfamZTY0RhckdwSTF4elhjTkMtcmtGME9KYlhGRmtlQ3hKeUlKWWtCRDBCRGkwbnNQcTJYQQ&q=http%3A%2F%2Fwww.eevblog.com%2Fdonations%2F", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqblZ3bHNZVy11YW1IWjhHR0FIdEpQMVJoWVpOd3xBQ3Jtc0ttbnVFV2JHWnRBVUhLaE83WmpKZU4xYi1GVS0tSTVjYUtGck5zUkgyVl94VXQtakNYU0xsOER1SWdjcVhSVlQ0TWszUWNHT3pFNzVKVGZESzBRcGwwdVVlb1k2cm5LaklXcDBMN3NSdjZ5NTk5S2JGSQ&q=http%3A%2F%2Fwww.eevblog.com%2Fdonations%2F" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbkdmREdPTlIzY2pSZ2RfX1NvRTNzZVVncEdxUXxBQ3Jtc0tuQUlockhNQ2NDV2xhQkNoMWUyM2ZnU2Jac3NkZlVKR1RtV1gyNk1fRWVrLTJDY1JiUHloRGVIeGh0blhfamZTY0RhckdwSTF4elhjTkMtcmtGME9KYlhGRmtlQ3hKeUlKWWtCRDBCRGkwbnNQcTJYQQ&q=http%3A%2F%2Fwww.eevblog.com%2Fdonations%2F" } - }, - "title": { - "simpleText": "EEVblog Donations" - }, - "trackingParams": "CB8QobIHGAciEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRNePy1H3QW5dJzuE2mHt-ObVgw6hqhXf2AjZ0DoWRBGk1XNRiGO-okaP7raQeazic8D4yZgoYSQsT3WmYKNXCZf0rk6Pc4KqozGcSQDWt7jGXeYeA" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CB4QobIHGAgiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "eevblog.com/donations" + }, + "title": { + "content": "EEVblog Donations" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRNePy1H3QW5dJzuE2mHt-ObVgw6hqhXf2AjZ0DoWRBGk1XNRiGO-okaP7raQeazic8D4yZgoYSQsT3WmYKNXCZf0rk6Pc4KqozGcSQDWt7jGXeYeA", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSkFJt58idInfFAW7lrZ-6EfRiA3ThDqnAywUsJYr78mSnsfxQdWiv3tHor6qgINIu_Z7IrF-RMmKtCFPhz3-blesNh9xcotKUJv1PV4WNrBKESFCY", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcQO-SmPSHM8ETQwZDYhA4w265KjgTPxsXjE9aZpX_cQev3IpPohPRd3_GFziR3_l_kQ9uavjzUJqj2aR8MB-l4hFfT8eGv-HKRhExrkL1m0LCH-JIE", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRstfwnAaG4kF2cOJLSXbrTomU5vDwsOu6RuyY-uAmD0yM2p8Nfrp4Ycoccz_g8580M2qq6qLHXguC53YwiAIjJtl3pjX0rJKUjkyMeqhY8Sgn83qk", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTEshIGFGiBVLYGGP-t5xPGSeQ9bTSkyHDqXxcrOJTn4Wkg2lG0xzQqoJsOOGlFZLleG7WDXuMo4hcE5U-5F0nZkEo_Xtd1ovFIRgkZc1HjhMKLWlE", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcR4mq4xdRu9LRUZ2HzIIwJWwtxWhx3--EWTK9AebXRGFNBhvhTu_HdUKiHwgHsawcTKSgOz9C4FBktD3zY9FqFx_IGs82iO282qpUr5QaCD01J5RXU", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRIVNMFDnR4cqNqYXN0h9Nl5J-iSg_RfceC_ZBK5ST5BRGP9gCy7ghL7FTYks1tHusczalImHmcvqeIqE-Wx_UpTHwKtCB6mfGLg3EZ7xwH9iMEKxY", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSugACwO6xJT_J_s8qW2oIM6LwDHESwc6riWfaIuPf_7uloRpaWEJ3Kxa_yMu108U7DHkbXL5zMEut8-_G5RJ8kexXJa7mRRfY9YH59scKIbYsE_WER", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTkN-MU5mf_oxSQ6en8TSyVAqyiFyoVmqPdPSX3-4l4JkNY4xwXY2uuBXyR-OGRTeKFYNjlaL55opuJdsArK0PYd9afjUdJdVc9RrSwIFDkX9KWswRo", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcR4HPodwM-_foWK97KTrM0CQfu9jLcOjuGpZ7DoYWRPX1Rn7pfUmcPHvaWsABP-O8DoQ94LSBKXhhjyxtLExJEshdyoiYhrNxKFN0HbbtB5PTK1N50d", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 19, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAsQobIHGAkiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa3VOaGVjWmc4amtOdThCSGp3QXdQSkZYSWhQQXxBQ3Jtc0tsS29ENFZBRWJ1UkZCVUhTeWRIbWw2V1FKNnZGblJJZUhzRlRXaVd5NjNyakJXOWwtbzVIZTdLV3poYk4ya0djeXZwZi1BYnhYSjRUMHJtWkdNVzQya1AtQ0hDcGRCXzk2Tlpxa3dTVHdoNmZnNjR1dw&q=https%3A%2F%2Fwww.patreon.com%2Feevblog", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbVB6Z1dNMkdXMkstVUprZzRaZXpVczNld0p6QXxBQ3Jtc0tuZ3M2cEduTXBlR0oxOWxnSHhQcmQ4Vm5RRUlkdGNEOVRBWERQcC1JYzFXb0JLVGdMMTlra2FKaS16Q3Q2cGFrRUFrWEpvMzVxNGtlOEJXWnNHWUcwdFdFNHhnVmgxVTdaOWE5Y0lIOVpneUw3VVNfRQ&q=https%3A%2F%2Fwww.patreon.com%2Feevblog", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa3VOaGVjWmc4amtOdThCSGp3QXdQSkZYSWhQQXxBQ3Jtc0tsS29ENFZBRWJ1UkZCVUhTeWRIbWw2V1FKNnZGblJJZUhzRlRXaVd5NjNyakJXOWwtbzVIZTdLV3poYk4ya0djeXZwZi1BYnhYSjRUMHJtWkdNVzQya1AtQ0hDcGRCXzk2Tlpxa3dTVHdoNmZnNjR1dw&q=https%3A%2F%2Fwww.patreon.com%2Feevblog" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbVB6Z1dNMkdXMkstVUprZzRaZXpVczNld0p6QXxBQ3Jtc0tuZ3M2cEduTXBlR0oxOWxnSHhQcmQ4Vm5RRUlkdGNEOVRBWERQcC1JYzFXb0JLVGdMMTlra2FKaS16Q3Q2cGFrRUFrWEpvMzVxNGtlOEJXWnNHWUcwdFdFNHhnVmgxVTdaOWE5Y0lIOVpneUw3VVNfRQ&q=https%3A%2F%2Fwww.patreon.com%2Feevblog" } - }, - "title": { - "simpleText": "Patreon" - }, - "trackingParams": "CB4QobIHGAgiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcT-8_XQ6FFFUhxPG6nO8fXwP8nLrLo1gEtxRF_P1hQjbuDENZeK3-2W5bUaDp8oWDpP0PEdTBO5MsLEtmSucmSL0PMvOUOgYIWi8-_A7I9ANgBBhnemRCe8cOc" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CB0QobIHGAkiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "patreon.com/eevblog" + }, + "title": { + "content": "Patreon" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcT-8_XQ6FFFUhxPG6nO8fXwP8nLrLo1gEtxRF_P1hQjbuDENZeK3-2W5bUaDp8oWDpP0PEdTBO5MsLEtmSucmSL0PMvOUOgYIWi8-_A7I9ANgBBhnemRCe8cOc", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcQx_Ds2OBT2_iejNv8KJMfq4SkGioo9jy-wKc8TTJoEVZ-4zeYMps-5_VwxENrzklDc_xyDKrrkiag_FRRbS9maYOaDY9poYU_Zxkj__ZDvP19XoITmGgUhFa4", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcQWxtxRIq_f94D-jLf1Y5IiJgZvyLl62yUd3hQbogAA3SvF8CayVFdTenZniRJoSygkiNRt3a2k4-xjuEoTLYazE5DoFREU5NKMgHz6nP9LH0oaMlJA5vDvyms", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRn16r7E_WqC4BLd0LJCAb-K9KJDEroLRMKrXinMK5RPPzmGJLeDiXjZPkDpPgaURI15J9pnjzAGSypfYGWZ3XGMP3BCpyvmzsj9WuRrprhI2cxCpDmQnGWotg", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcTC7RINGwpFa5fJEITxaFkLuGfxdCs-uN_cdeJf5up9GHD9YeR5euLEikQibIikWp6Wtffbdjz2jflyrByVxWxgmTZU9UcXvmhy1MM75TBq12jy84StKI5f9F4", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRrWwAxDvDU4oXyhpGbSCTLk8cB6ym43sFuIMB-WWdX0eHbThFv5VhFdFPNUXozQEWzX9T_3_lPf2tinG41M4YI50HJW6eWiN4dzzvGQagSWSwHgcjYMXsWxAY", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcTlVSX75EriGP0NtQ8286O5U5i9uv0NoE5A6ZeIsKcym7G25kCXG3CPdfuZ2b4M55sM7R4pLQgRAeelK-mgRw2Ft4eDCdMs6Ube5qma--Z1HmUI1qzWNcw1_7M", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcTCVuC9skhEwVgfEz_zEcBHhG--SkHyEbnx5MYR-ZaQ83_rQTS67xJB97OPld4r5GQjTbBCVfR_P1ik6O8AbfVYbUe7XcSkv28q-GA22QkRNxaLsI5gYPmBcYHp", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcQZSj3n8tVLdCF3U5Osf1QOr18Um6zHr7vT7wHSDZmWx01F4LTTfeYrbUDr22uxi_EwFSfwcbSRJPSgDJ1DuelyrZCLqarjzRNE5M945jSFcnUaKmRutqNQbgKv", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcQnb7Y6PZyo6rRTG0fcBXEpsU8fKhlcETqpth0usbgSOmOU5IWXTPbN7JHgvEL34uF9Kf8Si2SYW2S1L6rNHjmqwzN1WEKrtZRVEKxnwpeL6WrzeCoxoyGUzU8C", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 25, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAoQobIHGAoiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbW56T0MweUZyVVdFRmlpcUtJZ0VrZHFvbUZwZ3xBQ3Jtc0ttZEp5bnNtMWlSTHg3aVF1b19jV2hVYzZRQWtpbDdjcHB2OHd5VEZNRkxQY3hSeWZsN0pIVU94cnNSMjVGWjVJNTRHQVpaNmtfWnZaTEgzQmdQMk44S3pLWFFoRnVmbEwtLVViSmdjTjVpS1c4M1F2bw&q=https%3A%2F%2Fwww.subscribestar.com%2Feevblog", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbXZESU9oZ0dHV3lyQkwyTjlKeUgxQnZfdkU4UXxBQ3Jtc0tuMHAwVDdzWVpYbDFoYjh2VXFXQnJqRVp4STh2REI1ZFJfdFNYX1VodEV3em5BSWZ6NmdsM0JZRTFhckV2VDQ5U1ZzMHNVV3lRWllNVGZSdEUzQVJxTF94X2F5WlFid3R1ZnpDbFM4NkR5a0NCaWFwbw&q=https%3A%2F%2Fwww.subscribestar.com%2Feevblog", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbW56T0MweUZyVVdFRmlpcUtJZ0VrZHFvbUZwZ3xBQ3Jtc0ttZEp5bnNtMWlSTHg3aVF1b19jV2hVYzZRQWtpbDdjcHB2OHd5VEZNRkxQY3hSeWZsN0pIVU94cnNSMjVGWjVJNTRHQVpaNmtfWnZaTEgzQmdQMk44S3pLWFFoRnVmbEwtLVViSmdjTjVpS1c4M1F2bw&q=https%3A%2F%2Fwww.subscribestar.com%2Feevblog" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbXZESU9oZ0dHV3lyQkwyTjlKeUgxQnZfdkU4UXxBQ3Jtc0tuMHAwVDdzWVpYbDFoYjh2VXFXQnJqRVp4STh2REI1ZFJfdFNYX1VodEV3em5BSWZ6NmdsM0JZRTFhckV2VDQ5U1ZzMHNVV3lRWllNVGZSdEUzQVJxTF94X2F5WlFid3R1ZnpDbFM4NkR5a0NCaWFwbw&q=https%3A%2F%2Fwww.subscribestar.com%2Feevblog" } - }, - "title": { - "simpleText": "SubscribeStar" - }, - "trackingParams": "CB0QobIHGAkiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcQM5g9rHwU86NCDHZAnvIGK40lhLrquyZVKRCGft0DGiGrzrooBQXjgRtUY4xqEBgwe57w7ytbX7kUubPHTmsWL1wIqcW8XkaoYfuC4ENqJjMhOsX592A" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBwQobIHGAoiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "subscribestar.com/eevblog" + }, + "title": { + "content": "SubscribeStar" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcQM5g9rHwU86NCDHZAnvIGK40lhLrquyZVKRCGft0DGiGrzrooBQXjgRtUY4xqEBgwe57w7ytbX7kUubPHTmsWL1wIqcW8XkaoYfuC4ENqJjMhOsX592A", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTHn1LQ7DJ9GP6-kx3WqDehgU6X3diEby7pm3m7tuxwRjfkvkYRJQonfDkOg1wsF8q7v69sNt_KB3vG-QdImTndnLOf9pon12kvDJ9WUQy7X5_GfNqB3g", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRwkdSTNpWhCOTkjaMzCAt3Si4YzJgd3u8CnzI1Hv9al4HjNk6yjnRY119-4KvVEYsy078DAsLORPTGOmWPo6YIy6fh9KEsg_inciXHZmYmIcPn-4jD2A", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcT9mwjRi5BdPHzHHJdQCE1D2yqm11S6mIkcikM6rma9xpKXy-H8ujbsZCSxAGDzfb_yenr-yTzoDG4APeiBoAyeaKro2Cpz5GxA27k_khYqFvYVAewlqw", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTWhSVgHPXadIPDfYsrPeYIiE0ajUnIBUUr9eO1YCvTrWvmcRZqnkLnWZWCwl5OAjKxtCXBNcxoYsJX2S_eIKq_ipbGDEko6wlGWZjlZH5jRJj8WOaXsA", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcQZ00OGihD4ta9FqvsoTmgMqYRALOsSytUFgsbjHW6p-Pc7z8dMCcp4jQ-YKMAaWDz6lySlrfRFfhVv5IHXoIf34ALe6ZDM1mbWWrROzIyv0vpIu0khtg", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRAR6db3LScHfv_Z-ZWev0XcFjp_LKw34d3Mqe8It81AnkC4poW5Gd97c2XI1wHbnPper7pt0Xk3rT1zYt3dVATKcLztxkxRtgR7I6NakFXhBZYznawoQ", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTzjfPKAN6eeIYAqlR6bmpzdzs6Fo-s6kxApUegIbILaVHh3eD00dNhu6g_0N_YYEFsj2aPStFWnXk9OnvQTOqRLvxoU_KnnHQv8L7QrdyZQDUNxy8nnR0", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRzZvVZUWYdDdX3zY-_2lBwVj6CSjI_eeoz9-2LFFEQIP8Lp1TbjRl7vtmSzxyMdyGIGVgXp39Rg6BvPm5VOOxOvXLHPU5ctGeu1Q2R4uLNjAEjRsvouwo", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRPVnzDMmaa61TYzZ6dM0VI-IJJvYHYdH17apVgubfGbIEiPgNrEMvKmGZkHkv1WILzGLOj5CSE9A1Y6Tj4L-TVVQG0lILAhGvxeUm9yDpWEkPB7siXQJY", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 14, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAkQobIHGAsiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbF9Mb0tHaDVHSmlJSXNNaVZRVHFHRnR0Nl9MUXxBQ3Jtc0tuYTgxUlluQV9Ga0tra09Id3N4RndoRm9zTXlzYV9qT3JEMHJNQzJoVDFBd2EydlpTWUpXTGpfb19iU2xhT1YzVzFjd2NGb2NwQnBnckJfQ3ZxRWdPTV84dE1OOVhlV2FjWjdCX1JDenA4YnFOVEVVUQ&q=http%3A%2F%2Fwww.theamphour.com", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbmlnbTB1UWYwQUtabGpmRk9MTTdlRlh1Znkxd3xBQ3Jtc0trU2JGcDkxR01qWkRDUGxkWG5ZaVZudW4wdjBuOFVSN29HMWVva092TER4bHA2anFVQldMR2ZWOENNTjJYX3JDMG9UbzA1dVZTWXYyclRKR3A4cVgyYkNsZEdERUpnVTJWLXV1Z2VfVTFYMUYxNXJpRQ&q=http%3A%2F%2Fwww.theamphour.com", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbF9Mb0tHaDVHSmlJSXNNaVZRVHFHRnR0Nl9MUXxBQ3Jtc0tuYTgxUlluQV9Ga0tra09Id3N4RndoRm9zTXlzYV9qT3JEMHJNQzJoVDFBd2EydlpTWUpXTGpfb19iU2xhT1YzVzFjd2NGb2NwQnBnckJfQ3ZxRWdPTV84dE1OOVhlV2FjWjdCX1JDenA4YnFOVEVVUQ&q=http%3A%2F%2Fwww.theamphour.com" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbmlnbTB1UWYwQUtabGpmRk9MTTdlRlh1Znkxd3xBQ3Jtc0trU2JGcDkxR01qWkRDUGxkWG5ZaVZudW4wdjBuOFVSN29HMWVva092TER4bHA2anFVQldMR2ZWOENNTjJYX3JDMG9UbzA1dVZTWXYyclRKR3A4cVgyYkNsZEdERUpnVTJWLXV1Z2VfVTFYMUYxNXJpRQ&q=http%3A%2F%2Fwww.theamphour.com" } - }, - "title": { - "simpleText": "The AmpHour Radio Show" - }, - "trackingParams": "CBwQobIHGAoiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRnAk_yQ7EPRR2O8YSDZ2dxHZpw2jM7tVeWXkyrWjjZsD-p7OcxqNNuTKvuIuc0rT97_DrMTvP4x0mu4npuOrlZEJLkffDBAiHYCWdze4lZy3Lu" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBsQobIHGAsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "theamphour.com" + }, + "title": { + "content": "The AmpHour Radio Show" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRnAk_yQ7EPRR2O8YSDZ2dxHZpw2jM7tVeWXkyrWjjZsD-p7OcxqNNuTKvuIuc0rT97_DrMTvP4x0mu4npuOrlZEJLkffDBAiHYCWdze4lZy3Lu", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcS2v39Cz2redomM_MRpcWeiJhMBX_m5LGRTdfDAwCTK4QzDB2BobuJbVoH-8WJEY9HC9AGD_8aAkvtWF1RttXUoKqEM_fP0gN-KW5pZwoxQW_Y6", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTlqgb71UZeqq_dcaeTvAJI5YIycknY-Cg2QA2i4azpKpGC_yJaFSm_Sw2cLo4-RNsJm1LgjdvKc-wWnXLKar92lk4LIghb7gh9ANUMB8lKJ-ei", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcQqi8DUu5hiSn7gVFnqeVX4L3yOaeDkX1nBrm6kVJQpOh0KiXS4JU0cwRNNS69xBLmneEfV3UQY3le42pIybD5NyS379fICaVF4IbMIAyv6Q_rc", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRd9TtySlrjaXAVIsZfXmj0empOjoXNqc2Aps256b0_JsnZ724h6BEonhJTpf_eVw9W6l_Qbt90ItmQ1Jcbxq2E25v3VkK-LqbHHIiGsnE3Aw_Q", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTHTMDAq2Hs4hfxZEXEcwzDZPaj4rfrYVg1fWtOjh8rxuJH9otHFxcdHnkF4b2FgLcevsS5ER9zQ44eGwAvl9acgr4nJ7dzacmBbePrmmsBYp3v", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTeQ_-S2rnvk0BggjC8XrCPyrjO65gOQUbMWEdssWSX9DW7hIOyIDp4doSqAxiL-m8p6fN0Omi5jzFFgRHPJY1hX9QEeNuSkRuJywEx9ShQ36e3", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcTnO-_gki4Z5ygCIP3RMYYrAU6w4lrVxkmDP7swEgbx4u2meFaqAyqNaYpviT67uhMybneJ9PijGCdV3f_1iC-Vsl9FAYUnvR1Umo2fvEmSs0Roaw", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcQxW1XjlEyK8-xt5dKRJdhaRgFk53NvqEku3cqOLWxMjj0haCp62HCa0udaY1MomzUUn1p2ZfJAFyfGO29eQSDqsyI-ZMSk2_bRsT0LJIuJsbvw4Q", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcRj3IM5Qdg3pgYJHsDzBwxBJOBNLJzkqC2Q11A3iSEC-R7a6tNI56AjXmFzmdJqpCmoJlxurdH91pYZl24ofobMK1zWUNoiQ9jnmjOFV6o6082u2Q", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 25, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAgQobIHGAwiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa0dlTkt6c0Y3NXZSTGdhNHZ5TmpQbmNvSW12UXxBQ3Jtc0ttNDBjYjZtdnZpWDRXaXJJelB5bXltOXUwSGNFYTNaeFBHYXpqemZZTk9PajhaNnlEcHRwWE5qNGJRNFhhX2t6a1BmbmE2TW5LX0NuUHNrdFA4dXdySDlqR3ZtUXhaMFNRMkN4RDM0RWxaUVpIUXZLdw&q=http%3A%2F%2Fwww.flickr.com%2Fphotos%2Feevblog", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbFBXOGttUXNPRmdJc3hzT3dfSF9sdTJPUVE3QXxBQ3Jtc0trTG9YeXVnWmp3TnFibEoxeFI5SGdVYWhhOW84ZXBLODA1RlBsNTIzc2dlSUx1ZDVRakZVWk1vbUFrZ0Z3LXJTVEp4bVl5WER1dGVyNnpyNjVFV2dtVDVDdEZVdmxGMGZyLTJUUDZpa1pERU4yLVFOOA&q=http%3A%2F%2Fwww.flickr.com%2Fphotos%2Feevblog", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa0dlTkt6c0Y3NXZSTGdhNHZ5TmpQbmNvSW12UXxBQ3Jtc0ttNDBjYjZtdnZpWDRXaXJJelB5bXltOXUwSGNFYTNaeFBHYXpqemZZTk9PajhaNnlEcHRwWE5qNGJRNFhhX2t6a1BmbmE2TW5LX0NuUHNrdFA4dXdySDlqR3ZtUXhaMFNRMkN4RDM0RWxaUVpIUXZLdw&q=http%3A%2F%2Fwww.flickr.com%2Fphotos%2Feevblog" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbFBXOGttUXNPRmdJc3hzT3dfSF9sdTJPUVE3QXxBQ3Jtc0trTG9YeXVnWmp3TnFibEoxeFI5SGdVYWhhOW84ZXBLODA1RlBsNTIzc2dlSUx1ZDVRakZVWk1vbUFrZ0Z3LXJTVEp4bVl5WER1dGVyNnpyNjVFV2dtVDVDdEZVdmxGMGZyLTJUUDZpa1pERU4yLVFOOA&q=http%3A%2F%2Fwww.flickr.com%2Fphotos%2Feevblog" } - }, - "title": { - "simpleText": "Flickr" - }, - "trackingParams": "CBsQobIHGAsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcTIK5avaVK_PPYPc2I3QDvcmXC-GidHELAcxYo4dfKL8R-W2_Q-InaaYXGbq1PHHBdA9IYwpBXt9jPhUp85jdINIk0Q8Le1oZwpm_2BTK-aVU8W" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBoQobIHGAwiEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "flickr.com/photos/eevblog" + }, + "title": { + "content": "Flickr" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcTIK5avaVK_PPYPc2I3QDvcmXC-GidHELAcxYo4dfKL8R-W2_Q-InaaYXGbq1PHHBdA9IYwpBXt9jPhUp85jdINIk0Q8Le1oZwpm_2BTK-aVU8W", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRisXmS5JlxWqB1cLsKXo9Il5Xhhj2ADOIWBnQiBq62-2vbMLZJSfGWdNId2PA9NseGWv3KGQaQscjLM6WcPxiUnqvGOXKN_llQHlcq1nyb7B0T", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcTSy_vOUsDY1ZlvopAubkCsRzAxuoSn2FyRmyAjIoECPWF8pwtFEV0A0MwKFSEHS6jg2RKfXgYLCE5H711o9FEeuVCpvGkmx_G9NK--xW_uHkBb", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSmBeYG6OxzYEA9IOiHncjPDmVEMLrhzKvJx25CZBOokVcA4qik8JSrkH549lP-BkfWf9P0MKS0Jk9EiggFUhochk7TPyqNepiE0t97W7ovNTOO", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSvmdGN1F5Tko_EI9CpOCZ-CiCEdJ2kdnLpUbE4VmZ04VXYrSwJc60GzvPHbIUtTXnSAEhAdVS8LVuuOaARKbPty4jD2b2WztlF7deGtbalbYYU", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSj85gBCl8Cmquf6eisb7T_vSTdsfri1KFlK9j6E8cUIflsRyQQm4Jb3iTUkKqypcK87A6c5sJ6CrGSf9wqjJC_6kQbVmVecEPZri5dVBgjphP-", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcQ-gB2jMcMLJns0XSEF5rzdN35kItedMdWZv5g4D3fGXO9YSxIWlQ1uy1ayhh8IqAG43QfJHKiZIVj69C1oZvEDUqq2dGGtm3ZuGuwUMDU0V_Sa", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcT5pvRbc9NgaiO1j8Yek_2rEQC38uO5uecILIOWjK12x5HnJpQYHl_mxlOQianqBu_zjQBMm2ld9LSLAQ2jNRkfigUr70riVhrC4l12VTob5tykig", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcS-NlsldoBndXre9QOxc1sjxWJ-ptM2rh4WEmMks47DJdWLm5-Fc1gyfsCluxFYmE81rBcTz6Jd4XMHRb35XoRXNXpvkSBzFVNEH3uQjqTL7D4ygA", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcQDKmiwZhX5CAa7Edp7cx02xqj8YteB34PTgNAVVNytBFROEw_9XuVNA1gOLpfJKORRnOpfjqY5MHF9qct0pXl6wEc6GrPNHh9uCk9sidFNUl6tBw", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 118, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAcQobIHGA0iEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa2Ruc0trel90SDR6cDFCdXk3TWRQQ2U2Y3UwQXxBQ3Jtc0tsdFNaUmFwbGF1NktBczd5Q3RIbGdTcDRzOXdWclJYaEp2YmlvNjdOejJfaGk5cktZQ1BiVDNsVHQ0bHFyM213QzRXeUtwZ3NLeTB1WExzZktSTmY1TTBWYnhqNENnY2ZyUTVfS2ZWN0EwRzcyY0xkdw&q=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fredirect.html%3Fie%3DUTF8%26location%3Dhttp%253A%252F%252Fwww.amazon.com%252F%26tag%3Dee04-20%26linkCode%3Dur2%26camp%3D1789%26creative%3D390957", + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbW9Dem5XNVRTeDNYc0JiZXE4OUZDRXU2OEZPQXxBQ3Jtc0trNkR6RWxfYUJUUUU1ZHZaT1NiOVZHaHZRLVRjZmpTdTlzZjhncWtDRWRfNmJJT1RXMS1kQi1aMzNDMHNyQWx0QlpxQk00Mi1YN0h5NE1kZHhsWlZyNFlqTlpkQ3licjB4b0w4RTRDRThBMW9aVkh6Yw&q=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fredirect.html%3Fie%3DUTF8%26location%3Dhttp%253A%252F%252Fwww.amazon.com%252F%26tag%3Dee04-20%26linkCode%3Dur2%26camp%3D1789%26creative%3D390957", "webPageType": "WEB_PAGE_TYPE_UNKNOWN" } }, "urlEndpoint": { "nofollow": true, "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqa2Ruc0trel90SDR6cDFCdXk3TWRQQ2U2Y3UwQXxBQ3Jtc0tsdFNaUmFwbGF1NktBczd5Q3RIbGdTcDRzOXdWclJYaEp2YmlvNjdOejJfaGk5cktZQ1BiVDNsVHQ0bHFyM213QzRXeUtwZ3NLeTB1WExzZktSTmY1TTBWYnhqNENnY2ZyUTVfS2ZWN0EwRzcyY0xkdw&q=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fredirect.html%3Fie%3DUTF8%26location%3Dhttp%253A%252F%252Fwww.amazon.com%252F%26tag%3Dee04-20%26linkCode%3Dur2%26camp%3D1789%26creative%3D390957" + "url": "https://www.youtube.com/redirect?event=channel_description&redir_token=QUFFLUhqbW9Dem5XNVRTeDNYc0JiZXE4OUZDRXU2OEZPQXxBQ3Jtc0trNkR6RWxfYUJUUUU1ZHZaT1NiOVZHaHZRLVRjZmpTdTlzZjhncWtDRWRfNmJJT1RXMS1kQi1aMzNDMHNyQWx0QlpxQk00Mi1YN0h5NE1kZHhsWlZyNFlqTlpkQ3licjB4b0w4RTRDRThBMW9aVkh6Yw&q=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fredirect.html%3Fie%3DUTF8%26location%3Dhttp%253A%252F%252Fwww.amazon.com%252F%26tag%3Dee04-20%26linkCode%3Dur2%26camp%3D1789%26creative%3D390957" } - }, - "title": { - "simpleText": "EEVblog AMAZON Store" - }, - "trackingParams": "CBoQobIHGAwiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + } }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeGSb_XctA25lE585p4Y1gzQGccBu6OcsQiaOYtMv9dElpdpPFW4MYRTO7v8N1BcnPcQxrWkcJ7N6BVSj0k5sUwpGD7MI3S-Aiyghi8eF8Zy2_7Q" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBkQobIHGA0iEwjQl_Lpj676AhXF6FEKHcpNBwM=", + "startIndex": 0 + } + ], + "content": "amazon.com/gp/redirect.html?ie=UTF8&location=http://www.amazon.com/&tag=ee04-20&linkCode=ur2&camp=1789&creative=390957" + }, + "title": { + "content": "EEVblog AMAZON Store" + } + } + }, + { + "channelExternalLinkViewModel": { + "favicon": { + "sources": [ + { + "height": 16, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeGSb_XctA25lE585p4Y1gzQGccBu6OcsQiaOYtMv9dElpdpPFW4MYRTO7v8N1BcnPcQxrWkcJ7N6BVSj0k5sUwpGD7MI3S-Aiyghi8eF8Zy2_7Q", + "width": 16 + }, + { + "height": 24, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcQQLBJqOEi7zWd3visSSBE3evcrUHsXyOsKf4FLg-smeevDxkoJP1dvIzL62wLPJNJ36XjjwClKASh1rqiMqOlQD90yHq2iFE7XHT_dL2_5SVglYQ", + "width": 24 + }, + { + "height": 32, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcTIpDkH-J1bfPjmxtW3L3ILo13ECM9jWfnEYH-wqrdBL-hRWzffwxWgaB6kLb6kxSzZ-CD9t7A66POdDIOsX0DVr6_p6RBADn_1-SJE4A73YM91VA", + "width": 32 + }, + { + "height": 48, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRzc99cQVO6xVjKEdu1y7UE7ht3yMh9XSpPSWUdKDTn-71Lhwv33Q2GrE9Nkacy-1HhbLTE0F5j-E3FV6o-YLUGOVJCdxWxi8A2H31E8M3XCollzQ", + "width": 48 + }, + { + "height": 50, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcQ3A1bUDh4-Rn1SaDBtRVDsNjk91MJdr1-vazJeAQI-GyKaDzuWLm5B5yzey2z1jkDDOHQZlHxa_TRK5EhMffiJQNe_EI3X9oU6DywxpdKm4iVKuw", + "width": 50 + }, + { + "height": 64, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcTcDD9ryu_atYv6cC51QyiLmHXA9skhB2zpqBz_fNfd-er9h-itB-qFqVeM5BpAba7d_l4yKjb5SNm8c9sSSSSaLRhNDnYNmdkze5ALC7A4PqW5ug", + "width": 64 + }, + { + "height": 96, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRKuF-3mWxkjP0YduQskxF7LUnbHZdcExwkoB7dHGXaw7_nIsB-3YaiLdq2yz3o3p5id6dI9KcPXNIh-8w7UGjapkhHSoaWihSJQXKo9NU7Cyxznw", + "width": 96 + }, + { + "height": 128, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcQ3NBhasd9pD3Uieof1sAMQh7_XHmfuSAsDl5Pi1rSmLYq-dgdXdasEU8oMtlv5SBxYsStFlbyFjF2y9ppnvEVBcxmCRFW8hQvaXtq-2JqF7tiTihs", + "width": 128 + }, + { + "height": 180, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSRgk_B4Ct3SFPG6Ch7UuUR_AGpMd9AMNoB5Du6lrOzn7wvkWQODs3WeKul2WnmmXeO8v5u0FvL8p9YMYM1t-U6AJ3S6ObPkhes289sYbuxUMTD0Vk", + "width": 180 + }, + { + "height": 256, + "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcRYr9W0zqO0yJyLRQSk8SGuwnZ_38Mc5EAi4s5BAOJEEexIPuUZYhFoUzwMmaUSyRCKmUX_ZUaM8sTGLZEHx4TWsEtCtdw_jEjNItIGHR8dQRZQhYo", + "width": 256 + } + ] + }, + "link": { + "commandRuns": [ + { + "length": 20, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAYQobIHGA4iEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { "rootVe": 83769, @@ -578,1198 +1179,218 @@ "nofollow": true, "url": "http://www.youtube.com/EEVblog2" } - }, - "title": { - "simpleText": "2nd EEVblog Channel" - }, - "trackingParams": "CBkQobIHGA0iEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - ], - "primaryLinksLabel": { - "runs": [ - { - "text": "Links" } - ] + }, + "startIndex": 0 + } + ], + "content": "youtube.com/EEVblog2" + }, + "title": { + "content": "2nd EEVblog Channel" + } + } + } + ], + "signInForBusinessEmail": { + "commandRuns": [ + { + "length": 7, + "onTap": { + "innertubeCommand": { + "clickTrackingParams": "CAAQhGciEwis363HrqiCAxWfHwYAHc0nDmw=", + "commandMetadata": { + "webCommandMetadata": { + "rootVe": 83769, + "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%252F%2540EEVblog&hl=en", + "webPageType": "WEB_PAGE_TYPE_UNKNOWN" + } }, - "showDescription": true, - "signInForBusinessEmail": { - "runs": [ - { - "navigationEndpoint": { - "clickTrackingParams": "CBgQuy8YACITCNCX8umPrvoCFcXoUQodyk0HAw==", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "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%252Fc%252FEevblogDave%252Fabout&hl=en", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "signInEndpoint": { - "nextEndpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EgVhYm91dA%3D%3D" - }, - "clickTrackingParams": "CBgQuy8YACITCNCX8umPrvoCFcXoUQodyk0HAw==", + "signInEndpoint": { + "nextEndpoint": { + "browseEndpoint": { + "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", + "canonicalBaseUrl": "/@EEVblog", + "params": "8gYECgIyAA%3D%3D" + }, + "clickTrackingParams": "CAAQhGciEwis363HrqiCAxWfHwYAHc0nDmw=", + "commandMetadata": { + "webCommandMetadata": { + "apiUrl": "/youtubei/v1/browse", + "rootVe": 3611, + "url": "/@EEVblog", + "webPageType": "WEB_PAGE_TYPE_CHANNEL" + } + } + } + } + } + }, + "startIndex": 0 + } + ], + "content": "Sign in to see email address", + "styleRuns": [ + { + "length": 28, + "startIndex": 0 + } + ] + }, + "subscriberCountText": "920K subscribers", + "videoCountText": "1,920 videos", + "viewCountText": "199,087,682 views" + } + }, + "shareChannel": { + "buttonRenderer": { + "accessibilityData": { + "accessibilityData": { + "label": "Share" + } + }, + "command": { + "clickTrackingParams": "CAEQ8FsiEwis363HrqiCAxWfHwYAHc0nDmw=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "actions": [ + { + "clickTrackingParams": "CAEQ8FsiEwis363HrqiCAxWfHwYAHc0nDmw=", + "openPopupAction": { + "popup": { + "menuPopupRenderer": { + "items": [ + { + "menuServiceItemRenderer": { + "command": { + "clickTrackingParams": "CAQQ0rYLGAEiEwis363HrqiCAxWfHwYAHc0nDmw=", "commandMetadata": { "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/about", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" + "apiUrl": "/youtubei/v1/share/get_share_panel", + "sendPost": true } + }, + "shareEntityServiceEndpoint": { + "commands": [ + { + "clickTrackingParams": "CAQQ0rYLGAEiEwis363HrqiCAxWfHwYAHc0nDmw=", + "openPopupAction": { + "beReused": true, + "popup": { + "unifiedSharePanelRenderer": { + "showLoadingSpinner": true, + "trackingParams": "CAUQjmIiEwis363HrqiCAxWfHwYAHc0nDmw=" + } + }, + "popupType": "DIALOG" + } + } + ], + "serializedShareEntity": "GhhVQzJEakZFN1hmMTFVUlpxV0JpZ2NWT1E%3D" } - } + }, + "text": { + "runs": [ + { + "text": "Share channel" + } + ] + }, + "trackingParams": "CAQQ0rYLGAEiEwis363HrqiCAxWfHwYAHc0nDmw=" } }, - "text": "Sign in" - }, - { - "text": " to see email address" - } - ] + { + "menuServiceItemRenderer": { + "command": { + "clickTrackingParams": "CAIQ07YLGAIiEwis363HrqiCAxWfHwYAHc0nDmw=", + "copyTextEndpoint": { + "successActions": [ + { + "clickTrackingParams": "CAIQ07YLGAIiEwis363HrqiCAxWfHwYAHc0nDmw=", + "commandMetadata": { + "webCommandMetadata": { + "sendPost": true + } + }, + "signalServiceEndpoint": { + "actions": [ + { + "clickTrackingParams": "CAIQ07YLGAIiEwis363HrqiCAxWfHwYAHc0nDmw=", + "openPopupAction": { + "popup": { + "notificationActionRenderer": { + "responseText": { + "runs": [ + { + "text": "Channel ID copied to clipboard" + } + ] + }, + "trackingParams": "CAMQuWoiEwis363HrqiCAxWfHwYAHc0nDmw=" + } + }, + "popupType": "TOAST" + } + } + ], + "signal": "CLIENT_SIGNAL" + } + } + ], + "text": "UC2DjFE7Xf11URZqWBigcVOQ" + } + }, + "text": { + "runs": [ + { + "text": "Copy channel ID" + } + ] + }, + "trackingParams": "CAIQ07YLGAIiEwis363HrqiCAxWfHwYAHc0nDmw=" + } + } + ] + } }, - "statsLabel": { - "runs": [ - { - "text": "Stats" - } - ] - }, - "title": { - "simpleText": "EEVblog" - }, - "viewCountText": { - "simpleText": "186,854,342 views" - } + "popupType": "RESPONSIVE_DROPDOWN" } } ], - "trackingParams": "CBgQuy8YACITCNCX8umPrvoCFcXoUQodyk0HAw==" - } - } - ], - "disablePullToRefresh": true, - "trackingParams": "CBcQui8iEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EgVhYm91dPIGBAoCEgA%3D" - }, - "clickTrackingParams": "CBYQ8JMBGAsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/about", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "selected": true, - "title": "About", - "trackingParams": "CBYQ8JMBGAsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "expandableTabRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EgZzZWFyY2jyBgQKAloA" - }, - "clickTrackingParams": "CAAQhGciEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/search", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "selected": false, - "title": "Search" - } - } - ] - } - }, - "header": { - "c4TabbedHeaderRenderer": { - "avatar": { - "thumbnails": [ - { - "height": 48, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s48-c-k-c0x00ffffff-no-rj", - "width": 48 - }, - { - "height": 88, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s88-c-k-c0x00ffffff-no-rj", - "width": 88 - }, - { - "height": 176, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s176-c-k-c0x00ffffff-no-rj", - "width": 176 - } - ] - }, - "badges": [ - { - "metadataBadgeRenderer": { - "accessibilityData": { - "label": "Verified" - }, - "icon": { - "iconType": "CHECK_CIRCLE_THICK" - }, - "style": "BADGE_STYLE_TYPE_VERIFIED", - "tooltip": "Verified", - "trackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - } - ], - "banner": { - "thumbnails": [ - { - "height": 175, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - "width": 1060 - }, - { - "height": 188, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - "width": 1138 - }, - { - "height": 283, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - "width": 1707 - }, - { - "height": 351, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - "width": 2120 - }, - { - "height": 377, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - "width": 2276 - }, - { - "height": 424, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj", - "width": 2560 - } - ] - }, - "channelId": "UC2DjFE7Xf11URZqWBigcVOQ", - "headerLinks": { - "channelHeaderLinksRenderer": { - "primaryLinks": [ - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqbUZRdjQ1dHlkMWJjdDRoRHNGcDNBaGpiRTJDZ3xBQ3Jtc0tuSVJrXzlCS2lRRXo0dEozRmx3cXhzY1pKcld5ajBHZmRtNm93TnAwUEs4ZUUtMFE0a3dNQXFHVThGNGwyYW4ycWRGamZXOEstQ0VEUTNReVNuT2hyclVkeXN0WnVBM3RHbzJxaGh2SzhoSzlWUlpDcw&q=http%3A%2F%2Fwww.eevblog.com", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "urlEndpoint": { - "nofollow": true, - "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqbUZRdjQ1dHlkMWJjdDRoRHNGcDNBaGpiRTJDZ3xBQ3Jtc0tuSVJrXzlCS2lRRXo0dEozRmx3cXhzY1pKcld5ajBHZmRtNm93TnAwUEs4ZUUtMFE0a3dNQXFHVThGNGwyYW4ycWRGamZXOEstQ0VEUTNReVNuT2hyclVkeXN0WnVBM3RHbzJxaGh2SzhoSzlWUlpDcw&q=http%3A%2F%2Fwww.eevblog.com" - } - }, - "title": { - "simpleText": "EEVblog Web Site" - } - } - ], - "secondaryLinks": [ - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn:ANd9GcSnyfGgzwnk19b891nCqykpMzr3jlkKm0Z65gNVJbtXsk9-gzW5EiqqEvM02nZyYKmI2x1JQI9OuGsWU69bgq9_rNrHCYrXLP6HqhP9iVwr0bm2IQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqbTdwZlF0dFZiNGlBWnRydFNTY2RmaVZRbk9qZ3xBQ3Jtc0trSFRFcnE5bFNTQ0VocEdmNTE5Rks0Yng2WHV1TGR4R01CczM1RndsdjNuTExDUWNDeVc3TXlFMEpEc3ZpYXZTejRaZG1XQUZjd01rN3Q3cWwwcEdCNjNrUE9xc3JZUDZqM1lIUHlBbV9FenhJU1kxUQ&q=http%3A%2F%2Fwww.twitter.com%2Feevblog", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "urlEndpoint": { - "nofollow": true, - "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqbTdwZlF0dFZiNGlBWnRydFNTY2RmaVZRbk9qZ3xBQ3Jtc0trSFRFcnE5bFNTQ0VocEdmNTE5Rks0Yng2WHV1TGR4R01CczM1RndsdjNuTExDUWNDeVc3TXlFMEpEc3ZpYXZTejRaZG1XQUZjd01rN3Q3cWwwcEdCNjNrUE9xc3JZUDZqM1lIUHlBbV9FenhJU1kxUQ&q=http%3A%2F%2Fwww.twitter.com%2Feevblog" - } - }, - "title": { - "simpleText": "Twitter" - } - }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRmQS0-yT-68TopCQcxwbvtkTB0rdiUtc7g4WFZBVWFT4tJ8tSTon4n5uCmm9_b69_7bgTNZNmFw3-zyF-kWNXXZJEBTm_-r1qZrKLyDfCYxiEXY50" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqbGtDd3d0T2ltbkxFTVRaT3lBOUtKTHRPaEZTQXxBQ3Jtc0tuR0FkTG5ZOUhrLXhUQjdXU0tWeV95WWZyRzZFcEN6TkVGbU9OSFpETGkyNjU2a2xiS1o3Um5UVEVPWFNKYS00WFBFMTN6aHdmNGZQOTg4V1Z3T00tVG03ZWdyR3dsZ0ZHXzlCRlBQZTdTY2hiNGJBRQ&q=http%3A%2F%2Fwww.facebook.com%2FEEVblog", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "urlEndpoint": { - "nofollow": true, - "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqbGtDd3d0T2ltbkxFTVRaT3lBOUtKTHRPaEZTQXxBQ3Jtc0tuR0FkTG5ZOUhrLXhUQjdXU0tWeV95WWZyRzZFcEN6TkVGbU9OSFpETGkyNjU2a2xiS1o3Um5UVEVPWFNKYS00WFBFMTN6aHdmNGZQOTg4V1Z3T00tVG03ZWdyR3dsZ0ZHXzlCRlBQZTdTY2hiNGJBRQ&q=http%3A%2F%2Fwww.facebook.com%2FEEVblog" - } - }, - "title": { - "simpleText": "Facebook" - } - }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcRY4no9kYJtEAHXBEY2GDprV__HH1zc94olyS6G6fT5isS71bPyqvIi7-9VE1MMy3_3vsNOQLAerwcSQqGNyADWfxKpd2hLc8HuacZdgEjgZc_WLN8" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "url": "https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "urlEndpoint": { - "nofollow": true, - "url": "https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ" - } - }, - "title": { - "simpleText": "EEVdiscover" - } - }, - { - "icon": { - "thumbnails": [ - { - "url": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn:ANd9GcSeeYHqSanvu-1kS8-j8snFjPciLtknpI1FBXBB6ChDhHFlCRCjevwoP5AOW1u3m9HaeGexWOI4DJeisvRR1YK_jsARgDOrkbO3qWsfWQFxBaEkSQ" - } - ] - }, - "navigationEndpoint": { - "clickTrackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqa3BMOGVzZmd3TzJ0dzdrV0xYdEIyLTZ5a0NXd3xBQ3Jtc0trdHRYRWxaMmxzV0E2Ymw1THp3SDBoRUNhY0ZTeVlCV2t6WWJCckxQc1dwdXlfakRCeFZfa2tLazF0OUtOUmZWemFKYlFjYXV6T0p4VV9xNG1CRFpjcXJnenRneHpMQmhpZHNmRDY4ZExvNWxaQWFWZw&q=http%3A%2F%2Fwww.eevblog.com%2Fforum", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "urlEndpoint": { - "nofollow": true, - "target": "TARGET_NEW_WINDOW", - "url": "https://www.youtube.com/redirect?event=channel_banner&redir_token=QUFFLUhqa3BMOGVzZmd3TzJ0dzdrV0xYdEIyLTZ5a0NXd3xBQ3Jtc0trdHRYRWxaMmxzV0E2Ymw1THp3SDBoRUNhY0ZTeVlCV2t6WWJCckxQc1dwdXlfakRCeFZfa2tLazF0OUtOUmZWemFKYlFjYXV6T0p4VV9xNG1CRFpjcXJnenRneHpMQmhpZHNmRDY4ZExvNWxaQWFWZw&q=http%3A%2F%2Fwww.eevblog.com%2Fforum" - } - }, - "title": { - "simpleText": "The EEVblog Forum" - } - } - ] - } - }, - "mobileBanner": { - "thumbnails": [ - { - "height": 88, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - "width": 320 - }, - { - "height": 175, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - "width": 640 - }, - { - "height": 263, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - "width": 960 - }, - { - "height": 351, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - "width": 1280 - }, - { - "height": 395, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj", - "width": 1440 - } - ] - }, - "navigationEndpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave" - }, - "clickTrackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - }, - "sponsorButton": { - "buttonRenderer": { - "accessibilityData": { - "accessibilityData": { - "label": "Join this channel" - } - }, - "hint": { - "hintRenderer": { - "dwellTimeMs": "60000", - "hintCap": { - "impressionCap": "1" - }, - "hintId": "sponsor-pre-purchase", - "trackingParams": "CBIQpecFIhMI0Jfy6Y-u-gIVxehRCh3KTQcD" - } - }, - "isDisabled": false, - "navigationEndpoint": { - "clickTrackingParams": "CBEQqGAiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "ignoreNavigation": true - } - }, - "modalEndpoint": { - "modal": { - "modalWithTitleAndButtonRenderer": { - "button": { - "buttonRenderer": { - "isDisabled": false, - "navigationEndpoint": { - "clickTrackingParams": "CBMQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "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%253Fkey%253DAIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8%2526prettyPrint%253Dfalse&hl=en", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "signInEndpoint": { - "hack": true - } - }, - "size": "SIZE_DEFAULT", - "style": "STYLE_BRAND", - "text": { - "simpleText": "Sign in" - }, - "trackingParams": "CBMQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" + "signal": "CLIENT_SIGNAL" } }, - "content": { + "icon": { + "iconType": "SHARE" + }, + "size": "SIZE_DEFAULT", + "style": "STYLE_DEFAULT", + "text": { "runs": [ { - "text": "Sign in to become a member." + "text": "Share channel" } ] }, - "title": { - "runs": [ - { - "text": "Want to join this channel?" - } - ] - } + "trackingParams": "CAEQ8FsiEwis363HrqiCAxWfHwYAHc0nDmw=" } } } - }, - "size": "SIZE_DEFAULT", - "style": "STYLE_SUGGESTIVE", - "targetId": "sponsorships-button", - "text": { - "runs": [ - { - "text": "Join" - } - ] - }, - "trackingParams": "CBEQqGAiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "subscribeButton": { - "buttonRenderer": { - "isDisabled": false, - "navigationEndpoint": { - "clickTrackingParams": "CBQQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "ignoreNavigation": true - } - }, - "modalEndpoint": { - "modal": { - "modalWithTitleAndButtonRenderer": { - "button": { - "buttonRenderer": { - "isDisabled": false, - "navigationEndpoint": { - "clickTrackingParams": "CBUQ_YYEIhMI0Jfy6Y-u-gIVxehRCh3KTQcDMglzdWJzY3JpYmU=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "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%252Fc%252FEevblogDave%252Fabout%26continue_action%3DQUFFLUhqbXowa0I5U2RLaG1pZTNLakhsbk1mUXRnODAxUXxBQ3Jtc0tuQXVsdjY1RTMybnVMT1lfNEQtMm5ZVWctZ2Y5dWxzc2RqQzlseHVpOXE3dExXUmI2YUZGalJuZVdZV2VHZjNDMFI5eVVwOHg5R09sSDVfRHA4RFg3YjF5YzBkSE83T0ZMUXZLLUV5X2Y1QklIb2k2TlNaRTlVZXRnSHNqRUN2czg2RGtBZWdSNmRUNy1xZnFhTGx5YkdXR294QU9wdmZYQUE0bTBBLU9hQkp1Smh3STdCYnltSS1ONUZjc3pBazVPNkFsZklmdXJBU19YcXJTVFo1SGhpTFQ5TFJB&hl=en&ec=66429", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "signInEndpoint": { - "continueAction": "QUFFLUhqbXowa0I5U2RLaG1pZTNLakhsbk1mUXRnODAxUXxBQ3Jtc0tuQXVsdjY1RTMybnVMT1lfNEQtMm5ZVWctZ2Y5dWxzc2RqQzlseHVpOXE3dExXUmI2YUZGalJuZVdZV2VHZjNDMFI5eVVwOHg5R09sSDVfRHA4RFg3YjF5YzBkSE83T0ZMUXZLLUV5X2Y1QklIb2k2TlNaRTlVZXRnSHNqRUN2czg2RGtBZWdSNmRUNy1xZnFhTGx5YkdXR294QU9wdmZYQUE0bTBBLU9hQkp1Smh3STdCYnltSS1ONUZjc3pBazVPNkFsZklmdXJBU19YcXJTVFo1SGhpTFQ5TFJB", - "idamTag": "66429", - "nextEndpoint": { - "browseEndpoint": { - "browseId": "UC2DjFE7Xf11URZqWBigcVOQ", - "canonicalBaseUrl": "/c/EevblogDave", - "params": "EgVhYm91dA%3D%3D" - }, - "clickTrackingParams": "CBUQ_YYEIhMI0Jfy6Y-u-gIVxehRCh3KTQcD", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3611, - "url": "/c/EevblogDave/about", - "webPageType": "WEB_PAGE_TYPE_CHANNEL" - } - } - } - } - }, - "size": "SIZE_DEFAULT", - "style": "STYLE_BLUE_TEXT", - "text": { - "simpleText": "Sign in" - }, - "trackingParams": "CBUQ_YYEIhMI0Jfy6Y-u-gIVxehRCh3KTQcD" - } - }, - "content": { - "simpleText": "Sign in to subscribe to this channel." - }, - "title": { - "simpleText": "Want to subscribe to this channel?" - } - } - } - } - }, - "size": "SIZE_DEFAULT", - "style": "STYLE_DESTRUCTIVE", - "text": { - "runs": [ - { - "text": "Subscribe" - } - ] - }, - "trackingParams": "CBQQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "subscriberCountText": { - "accessibility": { - "accessibilityData": { - "label": "881K subscribers" } - }, - "simpleText": "881K subscribers" + ], + "targetId": "12fccb1f-991a-1fd4-7e2e-a178c39b58d1" }, - "title": "EEVblog", - "trackingParams": "CBAQ8DsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "tvBanner": { - "thumbnails": [ - { - "height": 180, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - "width": 320 - }, - { - "height": 480, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - "width": 854 - }, - { - "height": 720, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - "width": 1280 - }, - { - "height": 1080, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - "width": 1920 - }, - { - "height": 1192, - "url": "https://yt3.ggpht.com/yIJ9ad80n49rK-YUcZLe_8bLmR-aGyg5ybDH_XKIc0GDWrC6s1Wzz8lxnq3_hux_5b6NHPZ9=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj", - "width": 2120 - } - ] - }, - "visitTracking": { - "remarketingPing": "https://www.youtube.com/pagead/viewthroughconversion/962985656/?backend=innertube&cname=1&cver=2_20220921_08_00&foc_id=2DjFE7Xf11URZqWBigcVOQ&label=followon_cvisit&ptype=no_rmkt&utuid=2DjFE7Xf11URZqWBigcVOQ" - } + "clickTrackingParams": "CAAQhGciEwis363HrqiCAxWfHwYAHc0nDmw=" } - }, - "metadata": { - "channelMetadataRenderer": { - "androidAppindexingLink": "android-app://com.google.android.youtube/http/www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ", - "androidDeepLink": "android-app://com.google.android.youtube/http/www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ", - "availableCountryCodes": [ - "LV", - "IE", - "OM", - "PF", - "IS", - "RS", - "SB", - "TR", - "ML", - "KY", - "TM", - "DK", - "TJ", - "GS", - "BT", - "AF", - "BA", - "HN", - "LC", - "SK", - "ZA", - "MZ", - "CY", - "MY", - "UY", - "GD", - "NC", - "CI", - "CM", - "GI", - "CC", - "QA", - "TV", - "BD", - "LB", - "SS", - "SY", - "MX", - "NL", - "SV", - "LS", - "GW", - "NI", - "VG", - "NP", - "HT", - "UG", - "AS", - "YE", - "KG", - "NO", - "MK", - "RE", - "BQ", - "ES", - "CO", - "CK", - "VE", - "ID", - "AR", - "FJ", - "IL", - "KE", - "UZ", - "GG", - "SA", - "CH", - "PL", - "AT", - "TW", - "BY", - "PW", - "KM", - "DE", - "VI", - "VN", - "MQ", - "PH", - "PS", - "SZ", - "FR", - "JM", - "PE", - "GR", - "NF", - "SI", - "ER", - "AX", - "EG", - "GY", - "CU", - "CZ", - "MN", - "GU", - "BL", - "LY", - "GH", - "SG", - "MU", - "AI", - "GT", - "TF", - "NA", - "SX", - "DM", - "ZM", - "JP", - "GQ", - "MF", - "PN", - "YT", - "PT", - "KN", - "AO", - "ET", - "SM", - "AL", - "BR", - "KZ", - "IQ", - "ZW", - "VU", - "MH", - "GA", - "AW", - "DZ", - "WS", - "KH", - "RW", - "CX", - "LU", - "MT", - "NZ", - "CF", - "SO", - "EH", - "BF", - "IO", - "ME", - "MO", - "PG", - "FK", - "GE", - "SE", - "ST", - "WF", - "BJ", - "HM", - "KP", - "LI", - "BB", - "UM", - "CN", - "SJ", - "BG", - "CD", - "MP", - "DO", - "GM", - "BO", - "NE", - "VA", - "LR", - "BV", - "BI", - "TD", - "CL", - "MS", - "HR", - "KW", - "MA", - "AU", - "AD", - "SD", - "IN", - "IT", - "DJ", - "NU", - "FO", - "KI", - "GN", - "TL", - "BZ", - "VC", - "MC", - "CG", - "EE", - "BS", - "SL", - "HU", - "LT", - "NR", - "AG", - "CR", - "GL", - "LA", - "PY", - "KR", - "MG", - "BW", - "BH", - "PM", - "US", - "FI", - "FM", - "IM", - "GB", - "MW", - "BE", - "BM", - "MR", - "SC", - "NG", - "CW", - "CA", - "TT", - "AE", - "JO", - "AM", - "TH", - "MD", - "CV", - "TZ", - "PR", - "UA", - "SH", - "AQ", - "EC", - "IR", - "LK", - "TO", - "SR", - "TK", - "BN", - "GP", - "MM", - "PA", - "HK", - "SN", - "TN", - "JE", - "PK", - "TC", - "GF", - "TG", - "RO", - "RU", - "MV", - "AZ" - ], - "avatar": { - "thumbnails": [ - { - "height": 900, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s900-c-k-c0x00ffffff-no-rj", - "width": 900 - } - ] - }, - "channelConversionUrl": "https://www.youtube.com/pagead/viewthroughconversion/962985656/?backend=innertube&cname=1&cver=2_20220921_08_00&foc_id=2DjFE7Xf11URZqWBigcVOQ&label=followon_cvisit&ptype=no_rmkt&utuid=2DjFE7Xf11URZqWBigcVOQ", - "channelUrl": "https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ", - "description": "NO SCRIPT, NO FEAR, ALL OPINION\nAn off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers\nHosted by Dave Jones from Sydney Australia\n\nDONATIONS:\nBitcoin: 3KqyH1U3qrMPnkLufM2oHDU7YB4zVZeFyZ\nEthereum: 0x99ccc4d2654ba40744a1f678d9868ecb15e91206\nPayPal: david@alternatezone.com\n\nPatreon: https://www.patreon.com/eevblog\n\nEEVblog2: http://www.youtube.com/EEVblog2\nEEVdiscover: https://www.youtube.com/channel/UCkGvUEt8iQLmq3aJIMjT2qQ\n\nEMAIL:\nAdvertising/Commercial: eevblog+business@gmail.com\nFan mail: eevblog+fan@gmail.com\nHate Mail: eevblog+hate@gmail.com\n\nI DON'T DO PAID VIDEO SPONSORSHIPS, DON'T ASK!\n\nPLEASE:\nDo NOT ask for personal advice on something, post it in the EEVblog forum.\nI read ALL email, but please don't be offended if I don't have time to reply, I get a LOT of email.\n\nMailbag\nPO Box 7949\nBaulkham Hills NSW 2153\nAUSTRALIA", - "doubleclickTrackingUsername": "EEVblog", - "externalId": "UC2DjFE7Xf11URZqWBigcVOQ", - "facebookProfileId": "EEVblog", - "iosAppindexingLink": "ios-app://544007664/vnd.youtube/www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ", - "isFamilySafe": true, - "keywords": "electronics engineering maker hacker design circuit hardware pic atmel oscilloscope multimeter diy hobby review teardown microcontroller arduino video blog tutorial how-to interview rant industry news mailbag \"dumpster diving\" debunking", - "ownerUrls": [ - "http://www.youtube.com/c/EevblogDave" - ], - "rssUrl": "https://www.youtube.com/feeds/videos.xml?channel_id=UC2DjFE7Xf11URZqWBigcVOQ", - "title": "EEVblog", - "vanityChannelUrl": "http://www.youtube.com/c/EevblogDave" - } - }, - "microformat": { - "microformatDataRenderer": { - "androidPackage": "com.google.android.youtube", - "appName": "YouTube", - "availableCountries": [ - "LV", - "IE", - "OM", - "PF", - "IS", - "RS", - "SB", - "TR", - "ML", - "KY", - "TM", - "DK", - "TJ", - "GS", - "BT", - "AF", - "BA", - "HN", - "LC", - "SK", - "ZA", - "MZ", - "CY", - "MY", - "UY", - "GD", - "NC", - "CI", - "CM", - "GI", - "CC", - "QA", - "TV", - "BD", - "LB", - "SS", - "SY", - "MX", - "NL", - "SV", - "LS", - "GW", - "NI", - "VG", - "NP", - "HT", - "UG", - "AS", - "YE", - "KG", - "NO", - "MK", - "RE", - "BQ", - "ES", - "CO", - "CK", - "VE", - "ID", - "AR", - "FJ", - "IL", - "KE", - "UZ", - "GG", - "SA", - "CH", - "PL", - "AT", - "TW", - "BY", - "PW", - "KM", - "DE", - "VI", - "VN", - "MQ", - "PH", - "PS", - "SZ", - "FR", - "JM", - "PE", - "GR", - "NF", - "SI", - "ER", - "AX", - "EG", - "GY", - "CU", - "CZ", - "MN", - "GU", - "BL", - "LY", - "GH", - "SG", - "MU", - "AI", - "GT", - "TF", - "NA", - "SX", - "DM", - "ZM", - "JP", - "GQ", - "MF", - "PN", - "YT", - "PT", - "KN", - "AO", - "ET", - "SM", - "AL", - "BR", - "KZ", - "IQ", - "ZW", - "VU", - "MH", - "GA", - "AW", - "DZ", - "WS", - "KH", - "RW", - "CX", - "LU", - "MT", - "NZ", - "CF", - "SO", - "EH", - "BF", - "IO", - "ME", - "MO", - "PG", - "FK", - "GE", - "SE", - "ST", - "WF", - "BJ", - "HM", - "KP", - "LI", - "BB", - "UM", - "CN", - "SJ", - "BG", - "CD", - "MP", - "DO", - "GM", - "BO", - "NE", - "VA", - "LR", - "BV", - "BI", - "TD", - "CL", - "MS", - "HR", - "KW", - "MA", - "AU", - "AD", - "SD", - "IN", - "IT", - "DJ", - "NU", - "FO", - "KI", - "GN", - "TL", - "BZ", - "VC", - "MC", - "CG", - "EE", - "BS", - "SL", - "HU", - "LT", - "NR", - "AG", - "CR", - "GL", - "LA", - "PY", - "KR", - "MG", - "BW", - "BH", - "PM", - "US", - "FI", - "FM", - "IM", - "GB", - "MW", - "BE", - "BM", - "MR", - "SC", - "NG", - "CW", - "CA", - "TT", - "AE", - "JO", - "AM", - "TH", - "MD", - "CV", - "TZ", - "PR", - "UA", - "SH", - "AQ", - "EC", - "IR", - "LK", - "TO", - "SR", - "TK", - "BN", - "GP", - "MM", - "PA", - "HK", - "SN", - "TN", - "JE", - "PK", - "TC", - "GF", - "TG", - "RO", - "RU", - "MV", - "AZ" - ], - "description": "NO SCRIPT, NO FEAR, ALL OPINION An off-the-cuff Video Blog about Electronics Engineering, for engineers, hobbyists, enthusiasts, hackers and Makers Hosted by...", - "familySafe": true, - "iosAppArguments": "https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ", - "iosAppStoreId": "544007664", - "linkAlternates": [ - { - "hrefUrl": "https://m.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ" - }, - { - "hrefUrl": "android-app://com.google.android.youtube/http/youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ" - }, - { - "hrefUrl": "ios-app://544007664/http/youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ" - } - ], - "noindex": false, - "ogType": "yt-fb-app:channel", - "schemaDotOrgType": "http://schema.org/http://schema.org/YoutubeChannelV2", - "siteName": "YouTube", - "tags": [ - "electronics", - "engineering", - "maker", - "hacker", - "design", - "circuit", - "hardware", - "pic", - "atmel", - "oscilloscope", - "multimeter", - "diy", - "hobby", - "review", - "teardown", - "microcontroller", - "arduino", - "video", - "blog", - "tutorial", - "how-to", - "interview", - "rant", - "industry", - "news", - "mailbag", - "dumpster diving", - "debunking" - ], - "thumbnail": { - "thumbnails": [ - { - "height": 200, - "url": "https://yt3.ggpht.com/ytc/AMLnZu9eKk4Nd16fX4Rn1TF1G7ReluwOl6M5558FTYAM=s200-c-k-c0x00ffffff-no-rj?days_since_epoch=19259", - "width": 200 - } - ] - }, - "title": "EEVblog", - "twitterCardType": "summary", - "twitterSiteHandle": "@YouTube", - "unlisted": false, - "urlApplinksAndroid": "vnd.youtube://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ?feature=applinks", - "urlApplinksIos": "vnd.youtube://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ?feature=applinks", - "urlApplinksWeb": "https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ?feature=applinks", - "urlCanonical": "https://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ", - "urlTwitterAndroid": "vnd.youtube://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ?feature=twitter-deep-link", - "urlTwitterIos": "vnd.youtube://www.youtube.com/channel/UC2DjFE7Xf11URZqWBigcVOQ?feature=twitter-deep-link" - } - }, + ], "responseContext": { "mainAppWebResponseContext": { - "loggedOut": true + "loggedOut": true, + "trackingParam": "kx_fmPxhoPZRKSsvcOhozrMdnXbEIEQeDWlsbukh8xl6fBwRgkuswmIBwOcCE59TDtslLKPQ-SS" }, "maxAgeSeconds": 300, "serviceTrackingParams": [ @@ -1777,7 +1398,7 @@ "params": [ { "key": "route", - "value": "channel.about" + "value": "channel.featured" }, { "key": "is_casual", @@ -1791,10 +1412,6 @@ "key": "is_monetization_enabled", "value": "true" }, - { - "key": "num_shelves", - "value": "3" - }, { "key": "is_alc_surface", "value": "false" @@ -1803,13 +1420,17 @@ "key": "browse_id", "value": "UC2DjFE7Xf11URZqWBigcVOQ" }, + { + "key": "browse_id_prefix", + "value": "" + }, { "key": "logged_in", "value": "0" }, { "key": "e", - "value": "1714240,23804281,23858057,23882685,23918597,23934970,23946420,23966208,23983296,23986025,23998056,24001373,24002022,24002025,24004644,24007246,24034168,24036947,24077241,24080738,24120820,24135310,24140247,24152442,24160837,24161116,24164186,24166867,24169501,24175559,24181174,24185614,24187043,24187377,24191629,24197275,24199724,24199774,24211178,24211242,24219713,24225483,24226335,24227844,24228637,24229161,24238596,24241378,24243988,24246430,24248385,24249085,24254502,24255165,24255543,24255545,24260441,24260783,24260844,24262346,24263796,24264860,24265820,24267564,24267570,24268142,24268870,24268936,24272785,24275322,24276632,24277923,24277989,24278489,24280256,24280303,24281190,24283093,24283281,24286003,24286010,24286017,24286396,24287795,24288047,24289901,24290131,24290276,24292296,24292715,24293107,39322278,39322357,39322382,39322386,39322399,39322456,45686551" + "value": "23804281,23885487,23943577,23946420,23966208,23983296,23986028,23998056,24004644,24007246,24034168,24036947,24077241,24080738,24120820,24135310,24140247,24166867,24181174,24187377,24241378,24255543,24255545,24288664,24290971,24291857,24363609,24367579,24371398,24371778,24373396,24377598,24377909,24379354,24382552,24385612,24387949,24390675,24428788,24439361,24451319,24453989,24458317,24458324,24458329,24458839,24463872,24468724,24485421,24499532,24506515,24506784,24515423,24517093,24518452,24524098,24526515,24526642,24526774,24526787,24526794,24526801,24526808,24526813,24526827,24528463,24528466,24528473,24528484,24528552,24528555,24528577,24528582,24528644,24528647,24528661,24528668,24531224,24531253,24537200,24539025,24540881,24541326,24541656,24542367,24542452,24543193,24543197,24543200,24543201,24546059,24546074,24547317,24548138,24548627,24548629,24548853,24549786,24550285,24550458,24559327,24559697,24560416,24561140,24561152,24561208,24561384,24563746,24564171,24566293,24566687,24569887,24585907,24586420,24586688,24588590,24589493,24694842,24696752,24697068,24698453,24699899,39324156,39324184,39324567,51000798,51003636,51004018,51006181,51009757,51009781,51009900,51009906,51010235,51010280,51011488,51011905,51012165,51012291,51012659,51014091,51016856,51017346,51017996,51019442,51019626,51020302,51020570,51021953,51022241,51024038,51025415,51025833,51027535,51027643,51027868,51027870,51028271,51030101,51030171,51030311,51030435,51030450,51031341,51031412,51032492,51033399,51033577,51034525,51035525,51035565,51036438,51036511,51036737,51037342,51037351,51037540,51038399,51038805,51040336,51040338,51040349,51040471,51041282,51041340,51041497,51041809,51042251,51043057,51043768,51043940,51044608,51044641,51045016,51045969,51046900,51046954,51047726,51048254,51048488,51049895,51051696,51052749,51053019,51053957,51054569" } ], "service": "GFEEDBACK" @@ -1819,6 +1440,10 @@ { "key": "browse_id", "value": "UC2DjFE7Xf11URZqWBigcVOQ" + }, + { + "key": "browse_id_prefix", + "value": "" } ], "service": "GOOGLE_HELP" @@ -1831,7 +1456,7 @@ }, { "key": "cver", - "value": "2.20220921.08.00" + "value": "2.20231101.05.00" }, { "key": "yt_li", @@ -1839,7 +1464,7 @@ }, { "key": "GetChannelPage_rid", - "value": "0xaada99e22093f27c" + "value": "0x1a5719f152afa89c" } ], "service": "CSI" @@ -1857,7 +1482,7 @@ "params": [ { "key": "client.version", - "value": "2.20220921" + "value": "2.20231101" }, { "key": "client.name", @@ -1865,868 +1490,16 @@ }, { "key": "client.fexp", - "value": "23966208,24140247,24272785,24286010,24161116,24286017,23983296,24267570,39322456,24226335,24268936,24286396,23882685,24243988,24277989,24255543,1714240,39322386,24280303,24185614,24283281,24199724,24036947,24268142,24187377,24260441,24290276,24248385,39322382,24120820,24293107,24211242,23858057,24169501,39322399,24219713,24002022,24080738,39322357,24225483,24249085,24199774,24265820,23918597,45686551,24260844,24254502,24246430,24255545,24077241,24175559,24290131,23946420,23804281,24001373,24152442,24276632,24197275,24181174,24228637,24280256,24034168,24275322,24160837,24238596,24281190,24292715,24002025,24262346,24166867,24283093,24227844,24287795,24278489,24255165,24263796,24267564,24264860,24191629,24292296,24260783,24229161,24241378,24187043,23986025,24164186,39322278,23934970,24007246,24277923,23998056,24135310,24288047,24004644,24211178,24286003,24268870,24289901" + "value": "24549786,51048488,24546074,24517093,51010280,51031412,51040349,24528644,51041809,24564171,51009906,51044641,51040471,24561208,24181174,51025415,24546059,51004018,24547317,24288664,51011488,24566687,24543197,51014091,51034525,24540881,24034168,51027535,51047726,51030311,51011905,24563746,51037351,24559697,24371398,24166867,51027643,51036438,24077241,24291857,24694842,51017996,24560416,24569887,51012659,24382552,24515423,51035525,23804281,24120820,24004644,24528552,24528473,51020570,24390675,51006181,51019442,24379354,24528466,24458839,51009757,51041282,24697068,24241378,24255545,23986028,51035565,24140247,51053019,51030101,24566293,24586688,24550285,24428788,24696752,24526813,24539025,24541326,24528668,24589493,24528661,24290971,24528582,51003636,24550458,51037342,24458329,51024038,24080738,24526827,51038399,51051696,51046900,24377598,24528647,24561152,23966208,51041340,24541656,51009900,51045016,51012165,24561140,24542367,24526794,23943577,24543201,51042251,51027870,24548629,24526801,24506784,24526808,24363609,39324184,24586420,51021953,51043940,51048254,24561384,51022241,51040338,24543193,24526642,23983296,24485421,24463872,24528555,51030171,51016856,24036947,51041497,23998056,24377909,24458317,51033399,24528577,51036737,51043057,24458324,24542452,24543200,24367579,24548853,24559327,39324156,24548627,24373396,24451319,24371778,24528484,24439361,51053957,24548138,51045969,24585907,51000798,24526515,51010235,24526774,51028271,51044608,24698453,24531253,24385612,39324567,51040336,51036511,51017346,51054569,23885487,24531224,24387949,51038805,24187377,51030450,51032492,51037540,51031341,24007246,24528463,51030435,24699899,24524098,51012291,51020302,51009781,51043768,51049895,51019626,24499532,24506515,23946420,51027868,24255543,24135310,24588590,24453989,51025833,51033577,51046954,24468724,24537200,51052749,24518452,24526787" } ], "service": "ECATCHER" } ], - "visitorData": "CgszMUUzZDlGLWxiRSipqr2ZBg%3D%3D", + "visitorData": "CgthaDFMbWFGWHhoUSiI3pSqBjIICgJERRICEgA%3D", "webResponseContextExtensionData": { "hasDecorated": true } }, - "topbar": { - "desktopTopbarRenderer": { - "a11ySkipNavigationButton": { - "buttonRenderer": { - "command": { - "clickTrackingParams": "CAUQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "sendPost": true - } - }, - "signalServiceEndpoint": { - "actions": [ - { - "clickTrackingParams": "CAUQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "signalAction": { - "signal": "SKIP_NAVIGATION" - } - } - ], - "signal": "CLIENT_SIGNAL" - } - }, - "isDisabled": false, - "size": "SIZE_DEFAULT", - "style": "STYLE_DEFAULT", - "text": { - "runs": [ - { - "text": "Skip navigation" - } - ] - }, - "trackingParams": "CAUQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "backButton": { - "buttonRenderer": { - "command": { - "clickTrackingParams": "CAcQvIYDIhMI0Jfy6Y-u-gIVxehRCh3KTQcD", - "commandMetadata": { - "webCommandMetadata": { - "sendPost": true - } - }, - "signalServiceEndpoint": { - "actions": [ - { - "clickTrackingParams": "CAcQvIYDIhMI0Jfy6Y-u-gIVxehRCh3KTQcD", - "signalAction": { - "signal": "HISTORY_BACK" - } - } - ], - "signal": "CLIENT_SIGNAL" - } - }, - "trackingParams": "CAcQvIYDIhMI0Jfy6Y-u-gIVxehRCh3KTQcD" - } - }, - "forwardButton": { - "buttonRenderer": { - "command": { - "clickTrackingParams": "CAYQvYYDIhMI0Jfy6Y-u-gIVxehRCh3KTQcD", - "commandMetadata": { - "webCommandMetadata": { - "sendPost": true - } - }, - "signalServiceEndpoint": { - "actions": [ - { - "clickTrackingParams": "CAYQvYYDIhMI0Jfy6Y-u-gIVxehRCh3KTQcD", - "signalAction": { - "signal": "HISTORY_FORWARD" - } - } - ], - "signal": "CLIENT_SIGNAL" - } - }, - "trackingParams": "CAYQvYYDIhMI0Jfy6Y-u-gIVxehRCh3KTQcD" - } - }, - "hotkeyDialog": { - "hotkeyDialogRenderer": { - "dismissButton": { - "buttonRenderer": { - "isDisabled": false, - "size": "SIZE_DEFAULT", - "style": "STYLE_BLUE_TEXT", - "text": { - "runs": [ - { - "text": "Dismiss" - } - ] - }, - "trackingParams": "CAkQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "sections": [ - { - "hotkeyDialogSectionRenderer": { - "options": [ - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "k", - "label": { - "runs": [ - { - "text": "Toggle play/pause" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "j", - "label": { - "runs": [ - { - "text": "Rewind 10 seconds" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "l", - "label": { - "runs": [ - { - "text": "Fast forward 10 seconds" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "P (SHIFT+p)", - "label": { - "runs": [ - { - "text": "Previous video" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "N (SHIFT+n)", - "label": { - "runs": [ - { - "text": "Next video" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": ",", - "hotkeyAccessibilityLabel": { - "accessibilityData": { - "label": "Comma" - } - }, - "label": { - "runs": [ - { - "text": "Previous frame (while paused)" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": ".", - "hotkeyAccessibilityLabel": { - "accessibilityData": { - "label": "Period" - } - }, - "label": { - "runs": [ - { - "text": "Next frame (while paused)" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "< (SHIFT+,)", - "hotkeyAccessibilityLabel": { - "accessibilityData": { - "label": "Less than or SHIFT + comma" - } - }, - "label": { - "runs": [ - { - "text": "Decrease playback rate" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "> (SHIFT+.)", - "hotkeyAccessibilityLabel": { - "accessibilityData": { - "label": "Greater than or SHIFT + period" - } - }, - "label": { - "runs": [ - { - "text": "Increase playback rate" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "0..9", - "label": { - "runs": [ - { - "text": "Seek to specific point in the video (7 advances to 70% of duration)" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "CONTROL + ←", - "label": { - "runs": [ - { - "text": "Seek to previous chapter" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "CONTROL + →", - "label": { - "runs": [ - { - "text": "Seek to next chapter" - } - ] - } - } - } - ], - "title": { - "runs": [ - { - "text": "Playback" - } - ] - } - } - }, - { - "hotkeyDialogSectionRenderer": { - "options": [ - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "f", - "label": { - "runs": [ - { - "text": "Toggle full screen" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "t", - "label": { - "runs": [ - { - "text": "Toggle theater mode" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "i", - "label": { - "runs": [ - { - "text": "Toggle miniplayer" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "ESCAPE", - "label": { - "runs": [ - { - "text": "Close miniplayer or current dialog" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "m", - "label": { - "runs": [ - { - "text": "Toggle mute" - } - ] - } - } - } - ], - "title": { - "runs": [ - { - "text": "General" - } - ] - } - } - }, - { - "hotkeyDialogSectionRenderer": { - "options": [ - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "c", - "label": { - "runs": [ - { - "text": "If the video supports captions, toggle captions ON/OFF" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "o", - "label": { - "runs": [ - { - "text": "Rotate through different text opacity levels" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "w", - "label": { - "runs": [ - { - "text": "Rotate through different window opacity levels" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "+", - "label": { - "runs": [ - { - "text": "Rotate through font sizes (increasing)" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "-", - "hotkeyAccessibilityLabel": { - "accessibilityData": { - "label": "Minus" - } - }, - "label": { - "runs": [ - { - "text": "Rotate through font sizes (decreasing)" - } - ] - } - } - } - ], - "title": { - "runs": [ - { - "text": "Subtitles and closed captions" - } - ] - } - } - }, - { - "hotkeyDialogSectionRenderer": { - "options": [ - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "w", - "label": { - "runs": [ - { - "text": "Pan up" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "a", - "label": { - "runs": [ - { - "text": "Pan left" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "s", - "label": { - "runs": [ - { - "text": "Pan down" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "d", - "label": { - "runs": [ - { - "text": "Pan right" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "+ on numpad or ]", - "hotkeyAccessibilityLabel": { - "accessibilityData": { - "label": "Plus on number pad or right bracket" - } - }, - "label": { - "runs": [ - { - "text": "Zoom in" - } - ] - } - } - }, - { - "hotkeyDialogSectionOptionRenderer": { - "hotkey": "- on numpad or [", - "hotkeyAccessibilityLabel": { - "accessibilityData": { - "label": "Minus on number pad or left bracket" - } - }, - "label": { - "runs": [ - { - "text": "Zoom out" - } - ] - } - } - } - ], - "title": { - "runs": [ - { - "text": "Spherical Videos" - } - ] - } - } - } - ], - "title": { - "runs": [ - { - "text": "Keyboard shortcuts" - } - ] - }, - "trackingParams": "CAgQteYDIhMI0Jfy6Y-u-gIVxehRCh3KTQcD" - } - }, - "logo": { - "topbarLogoRenderer": { - "endpoint": { - "browseEndpoint": { - "browseId": "FEwhat_to_watch" - }, - "clickTrackingParams": "CA8QsV4iEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/browse", - "rootVe": 3854, - "url": "/", - "webPageType": "WEB_PAGE_TYPE_BROWSE" - } - } - }, - "iconImage": { - "iconType": "YOUTUBE_LOGO" - }, - "overrideEntityKey": "EgZ0b3BiYXIg9QEoAQ%3D%3D", - "tooltipText": { - "runs": [ - { - "text": "YouTube Home" - } - ] - }, - "trackingParams": "CA8QsV4iEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "searchbox": { - "fusionSearchboxRenderer": { - "clearButton": { - "buttonRenderer": { - "accessibilityData": { - "accessibilityData": { - "label": "Clear search query" - } - }, - "icon": { - "iconType": "CLOSE" - }, - "isDisabled": false, - "size": "SIZE_DEFAULT", - "style": "STYLE_DEFAULT", - "trackingParams": "CA4Q8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "config": { - "webSearchboxConfig": { - "focusSearchbox": true, - "hasOnscreenKeyboard": false, - "requestDomain": "us", - "requestLanguage": "en" - } - }, - "icon": { - "iconType": "SEARCH" - }, - "placeholderText": { - "runs": [ - { - "text": "Search" - } - ] - }, - "searchEndpoint": { - "clickTrackingParams": "CA0Q7VAiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 4724, - "url": "/results?search_query=", - "webPageType": "WEB_PAGE_TYPE_SEARCH" - } - }, - "searchEndpoint": { - "query": "" - } - }, - "trackingParams": "CA0Q7VAiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "topbarButtons": [ - { - "topbarMenuButtonRenderer": { - "accessibility": { - "accessibilityData": { - "label": "Settings" - } - }, - "icon": { - "iconType": "MORE_VERT" - }, - "menuRequest": { - "clickTrackingParams": "CAsQ_qsBGAAiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "apiUrl": "/youtubei/v1/account/account_menu", - "sendPost": true - } - }, - "signalServiceEndpoint": { - "actions": [ - { - "clickTrackingParams": "CAsQ_qsBGAAiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "openPopupAction": { - "beReused": true, - "popup": { - "multiPageMenuRenderer": { - "showLoadingSpinner": true, - "style": "MULTI_PAGE_MENU_STYLE_TYPE_SYSTEM", - "trackingParams": "CAwQ_6sBIhMI0Jfy6Y-u-gIVxehRCh3KTQcD" - } - }, - "popupType": "DROPDOWN" - } - } - ], - "signal": "GET_ACCOUNT_MENU" - } - }, - "style": "STYLE_DEFAULT", - "tooltip": "Settings", - "trackingParams": "CAsQ_qsBGAAiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - { - "buttonRenderer": { - "icon": { - "iconType": "AVATAR_LOGGED_OUT" - }, - "navigationEndpoint": { - "clickTrackingParams": "CAoQ1IAEGAEiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "rootVe": 83769, - "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%253Fkey%253DAIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8%2526prettyPrint%253Dfalse&hl=en&ec=65620", - "webPageType": "WEB_PAGE_TYPE_UNKNOWN" - } - }, - "signInEndpoint": { - "idamTag": "65620" - } - }, - "size": "SIZE_SMALL", - "style": "STYLE_SUGGESTIVE", - "targetId": "topbar-signin", - "text": { - "runs": [ - { - "text": "Sign in" - } - ] - }, - "trackingParams": "CAoQ1IAEGAEiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - } - ], - "trackingParams": "CAEQq6wBIhMI0Jfy6Y-u-gIVxehRCh3KTQcD", - "voiceSearchButton": { - "buttonRenderer": { - "accessibilityData": { - "accessibilityData": { - "label": "Search with your voice" - } - }, - "icon": { - "iconType": "MICROPHONE_ON" - }, - "isDisabled": false, - "serviceEndpoint": { - "clickTrackingParams": "CAIQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "commandMetadata": { - "webCommandMetadata": { - "sendPost": true - } - }, - "signalServiceEndpoint": { - "actions": [ - { - "clickTrackingParams": "CAIQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=", - "openPopupAction": { - "popup": { - "voiceSearchDialogRenderer": { - "connectionErrorHeader": { - "runs": [ - { - "text": "No connection" - } - ] - }, - "connectionErrorMicrophoneLabel": { - "runs": [ - { - "text": "Check your connection and try again" - } - ] - }, - "disabledHeader": { - "runs": [ - { - "text": "Search with your voice" - } - ] - }, - "disabledSubtext": { - "runs": [ - { - "text": "To search by voice, go to your browser settings and allow access to microphone" - } - ] - }, - "exampleQuery1": { - "runs": [ - { - "text": "\"Play Dua Lipa\"" - } - ] - }, - "exampleQuery2": { - "runs": [ - { - "text": "\"Show me my subscriptions\"" - } - ] - }, - "exitButton": { - "buttonRenderer": { - "accessibilityData": { - "accessibilityData": { - "label": "Cancel" - } - }, - "icon": { - "iconType": "CLOSE" - }, - "isDisabled": false, - "size": "SIZE_DEFAULT", - "style": "STYLE_DEFAULT", - "trackingParams": "CAQQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - }, - "loadingHeader": { - "runs": [ - { - "text": "Working..." - } - ] - }, - "microphoneButtonAriaLabel": { - "runs": [ - { - "text": "Cancel" - } - ] - }, - "microphoneOffPromptHeader": { - "runs": [ - { - "text": "Microphone off. Try again." - } - ] - }, - "permissionsHeader": { - "runs": [ - { - "text": "Waiting for permission" - } - ] - }, - "permissionsSubtext": { - "runs": [ - { - "text": "Allow microphone access to search with voice" - } - ] - }, - "placeholderHeader": { - "runs": [ - { - "text": "Listening..." - } - ] - }, - "promptHeader": { - "runs": [ - { - "text": "Didn't hear that. Try again." - } - ] - }, - "promptMicrophoneLabel": { - "runs": [ - { - "text": "Tap microphone to try again" - } - ] - }, - "trackingParams": "CAMQ7q8FIhMI0Jfy6Y-u-gIVxehRCh3KTQcD" - } - }, - "popupType": "TOP_ALIGNED_DIALOG" - } - } - ], - "signal": "CLIENT_SIGNAL" - } - }, - "size": "SIZE_DEFAULT", - "style": "STYLE_DEFAULT", - "tooltip": "Search with your voice", - "trackingParams": "CAIQ8FsiEwjQl_Lpj676AhXF6FEKHcpNBwM=" - } - } - } - }, - "trackingParams": "CAAQhGciEwjQl_Lpj676AhXF6FEKHcpNBwM=" + "trackingParams": "CAAQhGciEwis363HrqiCAxWfHwYAHc0nDmw=" } diff --git a/tests/youtube.rs b/tests/youtube.rs index 4307278..687c010 100644 --- a/tests/youtube.rs +++ b/tests/youtube.rs @@ -39,7 +39,10 @@ fn get_player_from_client(#[case] client_type: ClientType, rp: RustyPipe) { // dbg!(&player_data); assert_eq!(player_data.details.id, "n4tK7LYFxI0"); - assert_eq!(player_data.details.name, "Spektrem - Shine [NCS Release]"); + assert_eq!( + player_data.details.name, + "Spektrem - Shine | Progressive House | NCS - Copyright Free Music" + ); if client_type == ClientType::DesktopMusic { assert!(player_data.details.description.is_none()); } else { @@ -68,9 +71,9 @@ fn get_player_from_client(#[case] client_type: ClientType, rp: RustyPipe) { .unwrap(); // Bitrates may change between requests - assert_approx(f64::from(video.bitrate), 1_507_068.0); - assert_eq!(video.average_bitrate, 1_345_149); - assert_eq!(video.size.unwrap(), 43_553_412); + assert_approx(f64::from(video.bitrate), 1_851_854.0); + assert_eq!(video.average_bitrate, 923_766); + assert_eq!(video.size.unwrap(), 29_909_835); assert_eq!(video.width, 1280); assert_eq!(video.height, 720); assert_eq!(video.fps, 30); @@ -102,8 +105,8 @@ fn get_player_from_client(#[case] client_type: ClientType, rp: RustyPipe) { .expect("audio stream not found"); assert_approx(f64::from(video.bitrate), 1_340_829.0); - assert_approx(f64::from(video.average_bitrate), 1_233_444.0); - assert_approx(video.size.unwrap() as f64, 39_936_630.0); + assert_approx(f64::from(video.average_bitrate), 1_046_557.0); + assert_approx(video.size.unwrap() as f64, 33_885_572.0); assert_eq!(video.width, 1280); assert_eq!(video.height, 720); assert_eq!(video.fps, 30); @@ -856,22 +859,15 @@ fn channel_playlists(rp: RustyPipe) { #[rstest] fn channel_info(rp: RustyPipe) { - let channel = - tokio_test::block_on(rp.query().channel_info("UC2DjFE7Xf11URZqWBigcVOQ")).unwrap(); + let info = tokio_test::block_on(rp.query().channel_info("UC2DjFE7Xf11URZqWBigcVOQ")).unwrap(); - // dbg!(&channel); - assert_channel_eevblog(&channel); + assert_eq!(info.create_date.unwrap(), date!(2009 - 4 - 4)); + assert_gte(info.view_count.unwrap(), 186_854_340, "channel views"); + assert_gte(info.video_count.unwrap(), 1920, "channel videos"); + assert_gte(info.subscriber_count.unwrap(), 920_000, "subscribers"); + assert_eq!(info.country.unwrap(), Country::Au); - let created = channel.content.create_date.unwrap(); - assert_eq!(created, date!(2009 - 4 - 4)); - - assert_gte( - channel.content.view_count.unwrap(), - 186_854_340, - "channel views", - ); - - insta::assert_ron_snapshot!(channel.content.links, @r###" + insta::assert_ron_snapshot!(info.links, @r###" [ ("EEVblog Web Site", "http://www.eevblog.com/"), ("Twitter", "http://www.twitter.com/eevblog"), @@ -967,8 +963,8 @@ fn channel_more( ); } - let channel_info = tokio_test::block_on(rp.query().channel_info(&id)).unwrap(); - assert_channel(&channel_info, id, name, unlocalized || name_unlocalized); + let info = tokio_test::block_on(rp.query().channel_info(&id)).unwrap(); + assert_eq!(info.id, id); } #[rstest] @@ -2447,8 +2443,8 @@ fn assert_frameset(frameset: &Frameset) { assert_gte(frameset.frame_height, 20, "frame width"); assert_gte(frameset.page_count, 1, "page count"); assert_gte(frameset.total_count, 50, "total count"); - assert_gte(frameset.frames_per_page_x, 5, "frames per page x"); - assert_gte(frameset.frames_per_page_y, 5, "frames per page y"); + assert_gte(frameset.frames_per_page_x, 3, "frames per page x"); + assert_gte(frameset.frames_per_page_y, 3, "frames per page y"); let n = frameset.urls().count() as u32; assert_eq!(n, frameset.page_count);