feat: add channel playlists

- add tests for channel videos
- small model refactor (rename Channel to ChannelTag)
This commit is contained in:
ThetaDev 2022-09-26 20:36:01 +02:00
parent 45707c4d01
commit 6f1a1c4440
30 changed files with 16831 additions and 241 deletions

View file

@ -12,16 +12,16 @@ pub async fn download_testfiles(project_root: &Path) {
let mut testfiles = project_root.to_path_buf();
testfiles.push("testfiles");
tokio::join!(
player(&testfiles),
player_model(&testfiles),
playlist(&testfiles),
video_details(&testfiles),
comments_top(&testfiles),
comments_latest(&testfiles),
recommendations(&testfiles),
channel_videos(&testfiles),
);
player(&testfiles).await;
player_model(&testfiles).await;
playlist(&testfiles).await;
video_details(&testfiles).await;
comments_top(&testfiles).await;
comments_latest(&testfiles).await;
recommendations(&testfiles).await;
channel_videos(&testfiles).await;
channel_playlists(&testfiles).await;
channel_info(&testfiles).await;
}
const CLIENT_TYPES: [ClientType; 5] = [
@ -202,6 +202,7 @@ async fn channel_videos(testfiles: &Path) {
("music", "UC_vmjW5e1xEHhYjY2a0kK1A"), // YouTube Music channels have no videos
("shorts", "UCh8gHdtzO2tXd593_bjErWg"), // shorts and livestreams are rendered differently
("live", "UChs0pSaEoNLV4mevBFGaoKA"),
("empty", "UCxBa895m48H5idw5li7h-0g"),
] {
let mut json_path = testfiles.to_path_buf();
json_path.push("channel");
@ -214,3 +215,33 @@ async fn channel_videos(testfiles: &Path) {
rp.query().channel_videos(id).await.unwrap();
}
}
async fn channel_playlists(testfiles: &Path) {
let mut json_path = testfiles.to_path_buf();
json_path.push("channel");
json_path.push("channel_playlists.json");
if json_path.exists() {
return;
}
let rp = rp_testfile(&json_path);
rp.query()
.channel_playlists("UC2DjFE7Xf11URZqWBigcVOQ")
.await
.unwrap();
}
async fn channel_info(testfiles: &Path) {
let mut json_path = testfiles.to_path_buf();
json_path.push("channel");
json_path.push("channel_info.json");
if json_path.exists() {
return;
}
let rp = rp_testfile(&json_path);
rp.query()
.channel_info("UC2DjFE7Xf11URZqWBigcVOQ")
.await
.unwrap();
}

View file

@ -1,14 +1,21 @@
use anyhow::{bail, Result};
use reqwest::Method;
use serde::Serialize;
use url::Url;
use crate::{
model::{ChannelVideos, Paginator},
model::{
Channel, ChannelInfo, ChannelOrder, ChannelPlaylist, ChannelVideo, Language, Paginator,
},
serializer::MapResult,
util,
timeago,
util::{self, TryRemove},
};
use super::{response, ClientType, MapResponse, RustyPipeQuery, YTContext};
use super::{
response::{self, IsLive, IsShort},
ClientType, MapResponse, RustyPipeQuery, YTContext,
};
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
@ -33,12 +40,28 @@ enum Params {
}
impl RustyPipeQuery {
pub async fn channel_videos(&self, channel_id: &str) -> Result<ChannelVideos> {
pub async fn channel_videos(
&self,
channel_id: &str,
) -> Result<Channel<Paginator<ChannelVideo>>> {
self.channel_videos_ordered(channel_id, ChannelOrder::default())
.await
}
pub async fn channel_videos_ordered(
&self,
channel_id: &str,
order: ChannelOrder,
) -> Result<Channel<Paginator<ChannelVideo>>> {
let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QChannel {
context,
browse_id: channel_id.to_owned(),
params: Params::VideosLatest,
params: match order {
ChannelOrder::Latest => Params::VideosLatest,
ChannelOrder::Oldest => Params::VideosOldest,
ChannelOrder::Popular => Params::VideosPopular,
},
};
self.execute_request::<response::Channel, _, _>(
@ -51,40 +74,493 @@ impl RustyPipeQuery {
)
.await
}
pub async fn channel_playlists(
&self,
channel_id: &str,
) -> Result<Channel<Paginator<ChannelPlaylist>>> {
let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QChannel {
context,
browse_id: channel_id.to_owned(),
params: Params::Playlists,
};
self.execute_request::<response::Channel, _, _>(
ClientType::Desktop,
"channel_playlists",
channel_id,
Method::POST,
"browse",
&request_body,
)
.await
}
pub async fn channel_info(&self, channel_id: &str) -> Result<Channel<ChannelInfo>> {
let context = self.get_context(ClientType::Desktop, true).await;
let request_body = QChannel {
context,
browse_id: channel_id.to_owned(),
params: Params::Info,
};
self.execute_request::<response::Channel, _, _>(
ClientType::Desktop,
"channel_info",
channel_id,
Method::POST,
"browse",
&request_body,
)
.await
}
}
impl MapResponse<ChannelVideos> for response::Channel {
impl MapResponse<Channel<Paginator<ChannelVideo>>> for response::Channel {
fn map_response(
self,
id: &str,
lang: crate::model::Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<ChannelVideos>> {
let warnings = Vec::new();
// dbg!(&self);
let header = self.header.c4_tabbed_header_renderer;
) -> Result<MapResult<Channel<Paginator<ChannelVideo>>>> {
let content = map_channel_content(self.contents, id);
let mut warnings = content.warnings;
let grid = match content.c {
response::channel::ChannelContent::GridRenderer { items } => Some(items),
_ => None,
};
if header.channel_id != id {
bail!(
"got wrong channel id {}, expected {}",
header.channel_id,
id
);
}
let mut v_res = grid.map(|g| map_videos(g, lang)).unwrap_or_default();
warnings.append(&mut v_res.warnings);
Ok(MapResult {
c: ChannelVideos {
id: header.channel_id,
name: header.title,
subscriber_count: header
.subscriber_count_text
.and_then(|txt| util::parse_large_numstr(&txt, lang)),
videos: Paginator::default(),
},
c: map_channel(
self.header,
self.metadata,
self.microformat,
v_res.c,
id,
lang,
)?,
warnings: warnings,
})
}
}
impl MapResponse<Channel<Paginator<ChannelPlaylist>>> for response::Channel {
fn map_response(
self,
id: &str,
lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Channel<Paginator<ChannelPlaylist>>>> {
let content = map_channel_content(self.contents, id);
let mut warnings = content.warnings;
let grid = match content.c {
response::channel::ChannelContent::GridRenderer { items } => Some(items),
_ => None,
};
let mut p_res = grid.map(map_playlists).unwrap_or_default();
warnings.append(&mut p_res.warnings);
Ok(MapResult {
c: map_channel(
self.header,
self.metadata,
self.microformat,
p_res.c,
id,
lang,
)?,
warnings: warnings,
})
}
}
impl MapResponse<Channel<ChannelInfo>> for response::Channel {
fn map_response(
self,
id: &str,
lang: Language,
_deobf: Option<&crate::deobfuscate::Deobfuscator>,
) -> Result<MapResult<Channel<ChannelInfo>>> {
let content = map_channel_content(self.contents, id);
let mut warnings = content.warnings;
let meta = match content.c {
response::channel::ChannelContent::ChannelAboutFullMetadataRenderer(meta) => Some(meta),
_ => None,
};
let cinfo = meta
.map(|meta| ChannelInfo {
create_date: timeago::parse_textual_date_or_warn(
lang,
&meta.joined_date_text,
&mut warnings,
),
view_count: util::parse_numeric_or_warn(&meta.view_count_text, &mut warnings),
links: meta
.primary_links
.into_iter()
.map(|l| {
(
l.title,
util::sanitize_yt_url(&l.navigation_endpoint.url_endpoint.url),
)
})
.collect(),
})
.unwrap_or_else(|| {
warnings.push("no metadata".to_owned());
ChannelInfo {
create_date: None,
view_count: None,
links: Vec::new(),
}
});
Ok(MapResult {
c: map_channel(
self.header,
self.metadata,
self.microformat,
cinfo,
id,
lang,
)?,
warnings,
})
}
}
fn map_videos(
res: MapResult<Vec<response::VideoListItem>>,
lang: Language,
) -> MapResult<Paginator<ChannelVideo>> {
let mut warnings = res.warnings;
let mut ctoken = None;
let videos = res
.c
.into_iter()
.filter_map(|item| match item {
response::VideoListItem::GridVideoRenderer(video) => {
let mut toverlays = video.thumbnail_overlays;
let is_live = toverlays.is_live();
let is_short = toverlays.is_short();
let to = toverlays.try_swap_remove(0);
Some(ChannelVideo {
id: video.video_id,
title: video.title,
// Time text is `LIVE` for livestreams, so we ignore parse errors
length: to.and_then(|to| {
util::parse_video_length(&to.thumbnail_overlay_time_status_renderer.text)
}),
thumbnail: video.thumbnail.into(),
publish_date: video
.published_time_text
.as_ref()
.and_then(|txt| timeago::parse_timeago_or_warn(lang, txt, &mut warnings)),
publish_date_txt: video.published_time_text,
view_count: video
.view_count_text
.map(|txt| util::parse_numeric(&txt).unwrap_or_default()),
is_live,
is_short,
})
}
response::VideoListItem::ContinuationItemRenderer {
continuation_endpoint,
} => {
ctoken = Some(continuation_endpoint.continuation_command.token);
None
}
_ => None,
})
.collect();
MapResult {
c: Paginator::new(None, videos, ctoken),
warnings,
}
}
fn map_playlists(
res: MapResult<Vec<response::VideoListItem>>,
) -> MapResult<Paginator<ChannelPlaylist>> {
let mut ctoken = None;
let playlists = res
.c
.into_iter()
.filter_map(|item| match item {
response::VideoListItem::GridPlaylistRenderer(playlist) => Some(ChannelPlaylist {
id: playlist.playlist_id,
name: playlist.title,
thumbnail: playlist.thumbnail.into(),
video_count: util::parse_numeric(&playlist.video_count_short_text).ok(),
}),
response::VideoListItem::ContinuationItemRenderer {
continuation_endpoint,
} => {
ctoken = Some(continuation_endpoint.continuation_command.token);
None
}
_ => None,
})
.collect();
MapResult {
c: Paginator::new(None, playlists, ctoken),
warnings: res.warnings,
}
}
fn map_vanity_url(url: &str, id: &str) -> Option<String> {
if url.contains(id) {
return None;
}
let mut parsed_url = ok_or_bail!(Url::parse(url), None);
// The vanity URL from YouTube is http for some reason
let _ = parsed_url.set_scheme("https");
Some(parsed_url.to_string())
}
fn map_channel<T>(
header: response::channel::Header,
metadata: response::channel::Metadata,
microformat: response::channel::Microformat,
content: T,
id: &str,
lang: Language,
) -> Result<Channel<T>> {
let header = header.c4_tabbed_header_renderer;
if header.channel_id != id {
bail!(
"got wrong channel id {}, expected {}",
header.channel_id,
id
);
}
Ok(Channel {
id: header.channel_id,
name: header.title,
subscriber_count: header
.subscriber_count_text
.and_then(|txt| util::parse_large_numstr(&txt, lang)),
avatar: header.avatar.into(),
description: metadata.channel_metadata_renderer.description,
tags: microformat.microformat_data_renderer.tags,
vanity_url: metadata
.channel_metadata_renderer
.vanity_channel_url
.as_ref()
.and_then(|url| map_vanity_url(url, id)),
banner: header.banner.into(),
mobile_banner: header.mobile_banner.into(),
tv_banner: header.tv_banner.into(),
content,
})
}
fn map_channel_content(
contents: response::channel::Contents,
id: &str,
) -> MapResult<response::channel::ChannelContent> {
let mut tabs = contents.two_column_browse_results_renderer.tabs;
let mut sectionlist = some_or_bail!(
tabs.try_swap_remove(0),
MapResult::error("no tab".to_owned())
)
.tab_renderer
.content
.section_list_renderer;
if let Some(target_id) = sectionlist.target_id {
// YouTube falls back to the featured page if the channel does not have a "videos" tab.
// This is the case for YouTube Music channels.
if target_id.starts_with(&format!("browse-feed{}featured", id)) {
return MapResult::ok(response::channel::ChannelContent::None);
}
}
let mut itemsection = some_or_bail!(
sectionlist.contents.try_swap_remove(0),
MapResult::error("no sectionlist".to_owned())
)
.item_section_renderer
.contents;
let content = some_or_bail!(
itemsection.try_swap_remove(0),
MapResult::error("no channel content".to_owned())
);
MapResult::ok(content)
}
#[cfg(test)]
mod tests {}
mod tests {
use std::{fs::File, io::BufReader, path::Path};
use chrono::Datelike;
use rstest::rstest;
use crate::{
client::{response, MapResponse, RustyPipe},
model::{Channel, ChannelOrder, ChannelVideo, Language, Paginator},
serializer::MapResult,
};
#[rstest]
#[case::latest(ChannelOrder::Latest)]
#[case::oldest(ChannelOrder::Oldest)]
#[case::popular(ChannelOrder::Popular)]
#[tokio::test]
async fn get_videos(#[case] order: ChannelOrder) {
let rp = RustyPipe::builder().strict().build();
let channel = rp
.query()
.channel_videos_ordered("UC2DjFE7Xf11URZqWBigcVOQ", order)
.await
.unwrap();
// dbg!(&channel);
check_channel(&channel);
assert!(
!channel.content.items.is_empty() && !channel.content.is_exhausted(),
"got no videos"
);
let first_video = &channel.content.items[0];
let first_video_date = first_video.publish_date.unwrap();
let age_days = (chrono::Local::now() - first_video_date).num_days();
match order {
ChannelOrder::Latest => {
assert!(age_days < 60, "latest video older than 60 days")
}
ChannelOrder::Oldest => {
assert!(age_days > 4700, "oldest video newer than 4700 days")
}
ChannelOrder::Popular => {
assert!(
first_video.view_count.unwrap() > 2300000,
"most popular video < 2.3M views"
)
}
}
}
#[tokio::test]
async fn get_playlists() {
let rp = RustyPipe::builder().strict().build();
let channel = rp
.query()
.channel_playlists("UC2DjFE7Xf11URZqWBigcVOQ")
.await
.unwrap();
// dbg!(&channel);
check_channel(&channel);
assert!(
!channel.content.items.is_empty() && !channel.content.is_exhausted(),
"got no playlists"
);
}
#[tokio::test]
async fn get_info() {
let rp = RustyPipe::builder().strict().build();
let channel = rp
.query()
.channel_info("UC2DjFE7Xf11URZqWBigcVOQ")
.await
.unwrap();
dbg!(&channel);
check_channel(&channel);
let created = channel.content.create_date.unwrap();
assert_eq!(created.year(), 2009);
assert_eq!(created.month(), 4);
assert_eq!(created.day(), 4);
assert!(
channel.content.view_count.unwrap() > 186854340,
"exp >186M views, got {}",
channel.content.view_count.unwrap()
);
insta::assert_ron_snapshot!(channel.content.links, @r###"
[
("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"),
]
"###);
}
fn check_channel<T>(channel: &Channel<T>) {
assert_eq!(channel.id, "UC2DjFE7Xf11URZqWBigcVOQ");
assert_eq!(channel.name, "EEVblog");
assert!(
channel.subscriber_count.unwrap() > 880000,
"exp >880K subscribers, got {}",
channel.subscriber_count.unwrap()
);
assert!(!channel.avatar.is_empty(), "got no thumbnails");
assert_eq!(channel.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");
assert!(!channel.tags.is_empty(), "got no tags");
assert_eq!(
channel.vanity_url.as_ref().unwrap(),
"https://www.youtube.com/c/EevblogDave"
);
assert!(!channel.banner.is_empty(), "got no banners");
assert!(!channel.mobile_banner.is_empty(), "got no mobile banners");
assert!(!channel.tv_banner.is_empty(), "got no tv banners");
}
#[rstest]
#[case::base("base", "UC2DjFE7Xf11URZqWBigcVOQ")]
#[case::music("music", "UC_vmjW5e1xEHhYjY2a0kK1A")]
#[case::shorts("shorts", "UCh8gHdtzO2tXd593_bjErWg")]
#[case::live("live", "UChs0pSaEoNLV4mevBFGaoKA")]
#[case::empty("empty", "UCxBa895m48H5idw5li7h-0g")]
fn t_map_channel_videos(#[case] name: &str, #[case] id: &str) {
let filename = format!("testfiles/channel/channel_videos_{}.json", name);
let json_path = Path::new(&filename);
let json_file = File::open(json_path).unwrap();
let channel: response::Channel =
serde_json::from_reader(BufReader::new(json_file)).unwrap();
let map_res: MapResult<Channel<Paginator<ChannelVideo>>> =
channel.map_response(id, Language::En, None).unwrap();
assert!(
map_res.warnings.is_empty(),
"deserialization/mapping warnings: {:?}",
map_res.warnings
);
insta::assert_ron_snapshot!(format!("map_channel_videos_{}", name), map_res.c, {
".content.items[].publish_date" => "[date]",
});
}
}

View file

@ -7,8 +7,9 @@ use anyhow::{anyhow, bail, Result};
use chrono::{Local, NaiveDateTime, NaiveTime, TimeZone};
use fancy_regex::Regex;
use once_cell::sync::Lazy;
use reqwest::{Method, Url};
use reqwest::Method;
use serde::Serialize;
use url::Url;
use crate::{
deobfuscate::Deobfuscator,
@ -174,7 +175,7 @@ impl MapResponse<VideoPlayer> for response::Player {
title: video_details.title,
description: video_details.short_description,
length: video_details.length_seconds,
thumbnails: video_details.thumbnail.unwrap_or_default().into(),
thumbnails: video_details.thumbnail.into(),
channel: ChannelId {
id: video_details.channel_id,
name: video_details.author,

View file

@ -5,13 +5,17 @@ use serde_with::VecSkipError;
use super::ChannelBadge;
use super::Thumbnails;
use super::{ContentRenderer, ContentsRenderer, VideoListItem};
use crate::serializer::ignore_any;
use crate::serializer::{text::Text, MapResult, VecLogError};
#[serde_as]
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Channel {
pub header: Header,
pub contents: Contents,
pub metadata: Metadata,
pub microformat: Microformat,
}
#[derive(Clone, Debug, Deserialize)]
@ -46,27 +50,30 @@ pub struct SectionListRendererWrap {
#[serde(rename_all = "camelCase")]
pub struct SectionListRenderer {
pub contents: Vec<ItemSectionRendererWrap>,
pub target_id: String,
/// - **Videos**: browse-feedUC2DjFE7Xf11URZqWBigcVOQvideos (...)
/// - **Playlists**: browse-feedUC2DjFE7Xf11URZqWBigcVOQplaylists104 (...)
/// - **Info**: None
pub target_id: Option<String>,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ItemSectionRendererWrap {
pub item_section_renderer: ContentsRenderer<GridRendererWrap>,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GridRendererWrap {
pub grid_renderer: GridRenderer,
pub item_section_renderer: ContentsRenderer<ChannelContent>,
}
#[serde_as]
#[derive(Clone, Debug, Deserialize)]
#[derive(Default, Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GridRenderer {
#[serde_as(as = "VecLogError<_>")]
pub items: MapResult<Vec<VideoListItem>>,
pub enum ChannelContent {
GridRenderer {
#[serde_as(as = "VecLogError<_>")]
items: MapResult<Vec<VideoListItem>>,
},
ChannelAboutFullMetadataRenderer(ChannelFullMetadata),
#[default]
#[serde(other, deserialize_with = "ignore_any")]
None,
}
#[derive(Clone, Debug, Deserialize)]
@ -87,11 +94,74 @@ pub struct HeaderRenderer {
/// `None` if the subscriber count is hidden.
#[serde_as(as = "Option<Text>")]
pub subscriber_count_text: Option<String>,
#[serde(default)]
pub avatar: Thumbnails,
#[serde_as(as = "Option<VecSkipError<_>>")]
pub badges: Option<Vec<ChannelBadge>>,
#[serde(default)]
pub banner: Thumbnails,
#[serde(default)]
pub mobile_banner: Thumbnails,
/// Fullscreen (16:9) channel banner
#[serde(default)]
pub tv_banner: Thumbnails,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Metadata {
pub channel_metadata_renderer: ChannelMetadataRenderer,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChannelMetadataRenderer {
pub description: String,
pub vanity_channel_url: Option<String>,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Microformat {
pub microformat_data_renderer: MicroformatDataRenderer,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MicroformatDataRenderer {
#[serde(default)]
pub tags: Vec<String>,
}
#[serde_as]
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChannelFullMetadata {
#[serde_as(as = "Text")]
pub joined_date_text: String,
#[serde_as(as = "Text")]
pub view_count_text: String,
#[serde_as(as = "VecSkipError<_>")]
pub primary_links: Vec<PrimaryLink>,
}
#[serde_as]
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PrimaryLink {
#[serde_as(as = "Text")]
pub title: String,
pub navigation_endpoint: NavigationEndpoint,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct NavigationEndpoint {
pub url_endpoint: UrlEndpoint,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UrlEndpoint {
pub url: String,
}

View file

@ -37,6 +37,7 @@ pub struct ContentsRenderer<T> {
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThumbnailsWrap {
#[serde(default)]
pub thumbnail: Thumbnails,
}
@ -45,6 +46,7 @@ pub struct ThumbnailsWrap {
#[derive(Default, Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Thumbnails {
#[serde(default)]
pub thumbnails: Vec<Thumbnail>,
}
@ -155,8 +157,6 @@ pub struct GridPlaylistRenderer {
pub title: String,
pub thumbnail: Thumbnails,
#[serde_as(as = "Text")]
pub published_time_text: String,
#[serde_as(as = "Text")]
pub video_count_short_text: String,
}
@ -244,6 +244,9 @@ pub struct TimeOverlay {
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TimeOverlayRenderer {
/// `29:54`
///
/// Is `LIVE` in case of a livestream
#[serde_as(as = "Text")]
pub text: String,
#[serde(default)]

View file

@ -207,7 +207,8 @@ pub struct VideoDetails {
pub keywords: Option<Vec<String>>,
pub channel_id: String,
pub short_description: Option<String>,
pub thumbnail: Option<Thumbnails>,
#[serde(default)]
pub thumbnail: Thumbnails,
#[serde_as(as = "JsonString")]
pub view_count: u64,
pub author: String,

View file

@ -344,6 +344,7 @@ pub struct MacroMarkersListItem {
pub struct MacroMarkersListItemRenderer {
/// Contains chapter start time in seconds
pub on_tap: MacroMarkersListItemOnTap,
#[serde(default)]
pub thumbnail: Thumbnails,
/// Chapter title
#[serde_as(as = "Text")]
@ -528,6 +529,7 @@ pub struct CommentRenderer {
#[serde(default)]
#[serde_as(as = "DefaultOnError<Option<Text>>")]
pub author_text: Option<String>,
#[serde(default)]
pub author_thumbnail: Thumbnails,
#[serde(default)]
/// ID of the author's channel

View file

@ -0,0 +1,37 @@
---
source: src/client/channel.rs
expression: map_res.c
---
Channel(
id: "UCxBa895m48H5idw5li7h-0g",
name: "Sebastian Figurroa",
subscriber_count: None,
avatar: [
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_hsZ1XlUXHzXsGNHJw0np79WhWZcC4j8eFdy-tiUCDBKAjJyJOzE5kXFRiqL2S=s48-c-k-c0x00ffffff-no-rj",
width: 48,
height: 48,
),
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_hsZ1XlUXHzXsGNHJw0np79WhWZcC4j8eFdy-tiUCDBKAjJyJOzE5kXFRiqL2S=s88-c-k-c0x00ffffff-no-rj",
width: 88,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_hsZ1XlUXHzXsGNHJw0np79WhWZcC4j8eFdy-tiUCDBKAjJyJOzE5kXFRiqL2S=s176-c-k-c0x00ffffff-no-rj",
width: 176,
height: 176,
),
],
description: "",
tags: [],
vanity_url: None,
banner: [],
mobile_banner: [],
tv_banner: [],
content: Paginator(
count: Some(0),
items: [],
ctoken: None,
),
)

View file

@ -0,0 +1,806 @@
---
source: src/client/channel.rs
expression: map_res.c
---
Channel(
id: "UChs0pSaEoNLV4mevBFGaoKA",
name: "The Good Life Radio x Sensual Musique",
subscriber_count: Some(760000),
avatar: [
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_V9mOdHaorjNFqGXCecFeOBZhDWB8tVYG_I8gJwA=s48-c-k-c0x00ffffff-no-rj",
width: 48,
height: 48,
),
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_V9mOdHaorjNFqGXCecFeOBZhDWB8tVYG_I8gJwA=s88-c-k-c0x00ffffff-no-rj",
width: 88,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/ytc/AMLnZu_V9mOdHaorjNFqGXCecFeOBZhDWB8tVYG_I8gJwA=s176-c-k-c0x00ffffff-no-rj",
width: 176,
height: 176,
),
],
description: "Welcome to The Good Life by Sensual Musique.\nThe second official channel of Sensual Musique. You can find a lot of music, live streams and some other things on this channel. Stay tuned :)\n\nSubmit your music here: submit.sensualmusiquenetwork@gmail.com",
tags: [
"live radio",
"live stream",
"live radio",
"the good life radio",
"chill radio",
"chill music",
"chill-out music",
"music",
"live music",
"deep house",
"tropical house",
"house music",
],
vanity_url: Some("https://www.youtube.com/c/TheGoodLiferadio"),
banner: [
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1060,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1138,
height: 188,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1707,
height: 283,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w2120-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2276,
height: 377,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2560,
height: 424,
),
],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/fL4x31Q80O_BvnhVIMI9YlV3apsiFvBENwGiSA-Hw9An6djAGw92RSOFax6z2r_rJNbRWPMA=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
content: Paginator(
count: Some(21),
items: [
ChannelVideo(
id: "csP93FGy0bs",
title: "Chill Out Music Mix • 24/7 Live Radio | Relaxing Deep House, Chillout Lounge, Vocal & Instrumental",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/csP93FGy0bs/hqdefault_live.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDq5TEpXIGH_OHZhn2_Jx7lp2kMUQ",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/csP93FGy0bs/hqdefault_live.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC9qL4JVwhDYjLBx6SvJHk6W92nqw",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/csP93FGy0bs/hqdefault_live.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB4ocU3LUEK0_pKLnGDc4VktaxXiQ",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/csP93FGy0bs/hqdefault_live.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCXgkgVSHFrMa8V8N5v2UjWO28hsA",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: None,
view_count: Some(94),
is_live: true,
is_short: false,
),
ChannelVideo(
id: "19hKXI1ENrY",
title: "Deep House Radio | Relaxing & Chill House, Best Summer Mix 2022, Gym & Workout Music",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/19hKXI1ENrY/hqdefault_live.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAmi9jgARxMYdZpIOLw5RhQkRx0Dg",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/19hKXI1ENrY/hqdefault_live.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBsgHDcgMqq7QY7EzTfkqRlgQnctQ",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/19hKXI1ENrY/hqdefault_live.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBUlUVC0PKWdLgAIuM-plZNXvLCpw",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/19hKXI1ENrY/hqdefault_live.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDKTKtHa8U33nGE3z90NHdw1hg0gA",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: None,
view_count: Some(381),
is_live: true,
is_short: false,
),
ChannelVideo(
id: "CqMUC5eXX7c",
title: "Back To School / Work 📚 Deep Focus Chillout Mix | The Good Life Radio #4",
length: Some(4667),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/CqMUC5eXX7c/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDJglNaF89w0KFxzGn4Y3UAwu9ydg",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/CqMUC5eXX7c/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBUInjw2qHf7fffZFisSpebAZx4ZQ",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/CqMUC5eXX7c/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLChdljUBQgZrwYI4X1iHOFLqJFleg",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/CqMUC5eXX7c/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCP-eLq1BjkztFjdvT9oDC28CQ0Ig",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 year ago"),
view_count: Some(241528),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "A77SYlXKQEM",
title: "Chillout Lounge 🏖\u{fe0f} Calm & Relaxing Background Music | The Good Life Radio #3",
length: Some(1861),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/A77SYlXKQEM/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA6c0iWB5IjXrbncP1JT2gvljTwyw",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/A77SYlXKQEM/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC57WRX_9Q-NbZJM8BbSY4_exA-0w",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/A77SYlXKQEM/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDuYQKcxdJYJ70wktFpQ6PNLre4Kg",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/A77SYlXKQEM/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC5AR1BxL-OKSWyAbDtVM1-riWmBA",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 year ago"),
view_count: Some(118351),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "72vkRHQfjbk",
title: "Summer Lovers 💖 A Beautiful & Relaxing Chillout Deep House Mix | The Good Life Radio #2",
length: Some(1832),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/72vkRHQfjbk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBBMAUBpqHTq2IalWplaJugEhf4eQ",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/72vkRHQfjbk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAUuACBQx4vbQhbtGEDOZp0L_pYOw",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/72vkRHQfjbk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBsPzh5wHVrjbNpIPuxd0ZR5B5WUQ",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/72vkRHQfjbk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBp4U-iN5-c9Y8F_8ojMY1RAyM9sg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 year ago"),
view_count: Some(157971),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "AMWMDhibROw",
title: "Relaxing & Chill House 🌴 Summer \'21 Chill-Out Mix | The Good Life Radio #1",
length: Some(1949),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/AMWMDhibROw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCDO-i7ZMHpgILmTxjIvtFEDl3fTQ",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/AMWMDhibROw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAALFU5VLgPrCUeKWmZXTACCGwoLw",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/AMWMDhibROw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD_vOVH7ergjvzgGATU_PotDMRtRQ",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/AMWMDhibROw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBZL8jux8zUDLrO428C6ZPzb5eppg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 year ago"),
view_count: Some(82309),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "9UMxZofMNbA",
title: "Chillout Lounge - Calm & Relaxing Background Music | Study, Work, Sleep, Meditation, Chill",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/9UMxZofMNbA/hqdefault_live.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDc3KEjaAI_syibPmnpLN04x1Wv7g",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/9UMxZofMNbA/hqdefault_live.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDRgMqXrbV8u8WDQzqiod2XONVyCA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/9UMxZofMNbA/hqdefault_live.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAdp0PT_vctOHl9kJI9M3GSTnvtgA",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/9UMxZofMNbA/hqdefault_live.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBwEl5g33rTRmvNLPTnYs9F8Tf0pg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: None,
view_count: Some(2043),
is_live: true,
is_short: false,
),
ChannelVideo(
id: "a2sEYVwBvX4",
title: "Paratone - Heaven Is A Place On Earth (feat. kaii)",
length: Some(161),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/a2sEYVwBvX4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBwBX3CEEc3ZK1SsP8iUbebtp5hUw",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/a2sEYVwBvX4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCl_B8hp9iizLS28rJFG081PUwW_Q",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/a2sEYVwBvX4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBUNlxWkdbMF_RwjZBztehCB73kvQ",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/a2sEYVwBvX4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAwp0X-W_JovMyp4-2YhCrqv3kpTg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(186475),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "JAY-prtJnGY",
title: "Joseph Feinstein - Where I Belong",
length: Some(126),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/JAY-prtJnGY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC79uFNaKWCm0lQ8_uxV0s2G0jJ-Q",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/JAY-prtJnGY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD5zFzigEu4lYRH-DU8QZOoGYqtSQ",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/JAY-prtJnGY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB2WhmMwj0Z5E-MYsyCcCBgYHYk-A",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/JAY-prtJnGY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCl8HeilZsI4BEpGzgXezAcrNf6_w",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(66425),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "DySa8OrQDi4",
title: "LA Vision & Gigi D\'Agostino - Hollywood",
length: Some(200),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/DySa8OrQDi4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAzPj5ZqrnaLQELc8EDtgLlUhDdRQ",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/DySa8OrQDi4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCyVpPBISgyCbQofRmZ00ayOAdR7g",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/DySa8OrQDi4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSUtrS1H9zmYCwWVtpvNJs5YDFgA",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/DySa8OrQDi4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAYq82JCAfQGWw72Y5uD5c4FqGzng",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(1520020),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "NqzXULaB8MA",
title: "LO - Home",
length: Some(163),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/NqzXULaB8MA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDFvB5JbSQIUtb-pldtNWWHb2Y3SQ",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/NqzXULaB8MA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAkMv60hZgnUzX6BPy439JVlC4qYA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/NqzXULaB8MA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC_RMNhjVIE9uIoL2eUsCsgqz4osA",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/NqzXULaB8MA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCvzbfRApS7SCw-mDrXBiOEVSiKng",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(37549),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "UGzy6uhZkmw",
title: "Luca - Sunset",
length: Some(153),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/UGzy6uhZkmw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD93d5foF1_yGd6ej5_8t-PM7ZCDw",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/UGzy6uhZkmw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCqscP2y4jsbU5WUo8QcEVtcojQRQ",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/UGzy6uhZkmw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBicCc5-9Cn7cyhzQXWRh-U1osFZw",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/UGzy6uhZkmw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLClbjl9Zl8eWI-_QGEoaA6H2a-dRg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(33002),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "iuvapHKpW8A",
title: "nourii - Better Off (feat. BCS)",
length: Some(126),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/iuvapHKpW8A/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCsDj4nWrDpmF-BTY_9REtx8xiHjA",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/iuvapHKpW8A/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAEqlsR_ujvaxo3po2UvHw10YpR4A",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/iuvapHKpW8A/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDL9vVk4L_OaiKxI_gT558zR108ow",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/iuvapHKpW8A/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLANK0ZOm-_hUACCRFBKHBgtcLCNMw",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(42036),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "n_1Nwht-Gh4",
title: "Deep House Covers & Remixes of Popular Songs 2020 🌴 Deep House, G-House, Chill-Out Music Playlist",
length: Some(2940),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/n_1Nwht-Gh4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAwRnMWNt4fNmmGR4THSsTh-9MiCw",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/n_1Nwht-Gh4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDFFVRUt-yQgt_-FWViG8gNyEet1g",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/n_1Nwht-Gh4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCX7K2IMIJWSXr6yvcwqo2cte7kWw",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/n_1Nwht-Gh4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDwJpjOiz8CUrGyd1SFGcwj_sSGNg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(322935),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "6TptI5BtP5U",
title: "The Good Life Radio Mix #2 | Summer Memories ☀\u{fe0f} (Chill Music Playlist 2020)",
length: Some(3448),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/6TptI5BtP5U/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBGvxAmGVff9uk5AOxBij56uB6azw",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/6TptI5BtP5U/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCbAAXy7HAh6VkQdPvO4wm4pR7RQA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/6TptI5BtP5U/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB238nXmpbUcIcVEPy1uGwcJEvMuw",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/6TptI5BtP5U/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLANSe4a_jtstlVxx5-rkIOvbmuR8g",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(91980),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "36YnV9STBqc",
title: "The Good Life Radio\u{a0}•\u{a0}24/7 Live Radio | Best Relax House, Chillout, Study, Running, Gym, Happy Music",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/36YnV9STBqc/hqdefault_live.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCe7OwcMt2h8bSNHbTTULV9-SST1Q",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/36YnV9STBqc/hqdefault_live.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAkzzBY_o86Nn0PbJftRE2t2NcUfQ",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/36YnV9STBqc/hqdefault_live.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBzzuLLFgJ072fAxz3yaAzkmnwJWA",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/36YnV9STBqc/hqdefault_live.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAeyiCUWTnj3nPmf80TIrS5zu9__g",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: None,
view_count: Some(4030),
is_live: true,
is_short: false,
),
ChannelVideo(
id: "7x6ii2TcsPE",
title: "The Good Life Radio Mix #1 | Relaxing & Chill House Music Playlist 2020",
length: Some(2726),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/7x6ii2TcsPE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC-CNpKCSMnLIscrYKNPX7DRZ0buA",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/7x6ii2TcsPE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBzsfvaKcxkUInkuC4effHqf5E3HA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/7x6ii2TcsPE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAJLHolRQLl2mVsHhWMPTNeVbNQMg",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/7x6ii2TcsPE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSDc5C90T2SYrmMhqddmiKaGPAiA",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(288098),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "mxV5MBZYYDE",
title: "Christmas Music with Vocals 🎅 Best Relaxing Christmas Songs 2020",
length: Some(5863),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/mxV5MBZYYDE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCVUbM3MtN0zZcE_8lY4eyo-Ly5Kw",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/mxV5MBZYYDE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBajcqiVFnWHZXTBBO4Dzq-gDYDyg",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/mxV5MBZYYDE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDbHzxHH7a4tjvIhH9DB3FYwihiyQ",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/mxV5MBZYYDE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD7NMECi-qMT4a_6fg9cOrc1C3-Ng",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(50818),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "hh2AOoPoAIo",
title: "The Good Life Radio Mix 2019 🎅 Winter & Christmas Relax House Playlist [Best of Part 1]",
length: Some(2530),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/hh2AOoPoAIo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAMmrbiYHz-7STgazeW2PAuGCkCcg",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/hh2AOoPoAIo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDKterYUnJQ9cm1HL9poDBtZenWXQ",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/hh2AOoPoAIo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCKoxgX2sbbbLesBvjuOglua7pyPw",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/hh2AOoPoAIo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCsqVhjHSvimVEEflkNZjqkfatEDQ",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 years ago"),
view_count: Some(98431),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "aFlvhtWsJ0g",
title: "Chillout Playlist | Relaxing Summer Music Mix 2019 [Deep & Tropical House]",
length: Some(2483),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/aFlvhtWsJ0g/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAvMC2I82wG7eQPDQmnyC3RbUGFWg",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/aFlvhtWsJ0g/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCBvVndf5HiT5-l-kuemFzm8JD3Sg",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/aFlvhtWsJ0g/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAOsKJmf_L47jJyyZssTbb-1adoSw",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/aFlvhtWsJ0g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBsPLkhBu3g5BDQrs6YiMXhsLbS6Q",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("3 years ago"),
view_count: Some(572456),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "cD-d7u6fnEI",
title: "Chill House Playlist | Relaxing Summer Music 2019",
length: Some(3165),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/cD-d7u6fnEI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBU_f1nTElkLg9ic2eKjM6luGgVcw",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/cD-d7u6fnEI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCguCnp0eiwA3P2rcMehJFYhPYaVA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/cD-d7u6fnEI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBixvXbxOAuFROr670t_uM1eQr7FA",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/cD-d7u6fnEI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD0vklW2iG6fJ2aZOop8A7tQswm0g",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("3 years ago"),
view_count: Some(3114909),
is_live: false,
is_short: false,
),
],
ctoken: None,
),
)

View file

@ -0,0 +1,120 @@
---
source: src/client/channel.rs
expression: map_res.c
---
Channel(
id: "UC_vmjW5e1xEHhYjY2a0kK1A",
name: "Oonagh - Topic",
subscriber_count: None,
avatar: [
Thumbnail(
url: "https://yt3.ggpht.com/pqKv4iqSjmMKPxsMCeyklTbpROSyInGNR4XvD1DqKD0AlROlsHzvoAlTvtMTO1g1x2WxaQ2Enxw=s48-c-k-c0x00ffffff-no-rj",
width: 48,
height: 48,
),
Thumbnail(
url: "https://yt3.ggpht.com/pqKv4iqSjmMKPxsMCeyklTbpROSyInGNR4XvD1DqKD0AlROlsHzvoAlTvtMTO1g1x2WxaQ2Enxw=s88-c-k-c0x00ffffff-no-rj",
width: 88,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/pqKv4iqSjmMKPxsMCeyklTbpROSyInGNR4XvD1DqKD0AlROlsHzvoAlTvtMTO1g1x2WxaQ2Enxw=s176-c-k-c0x00ffffff-no-rj",
width: 176,
height: 176,
),
],
description: "",
tags: [],
vanity_url: None,
banner: [
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1060,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1138,
height: 188,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1707,
height: 283,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w2120-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2276,
height: 377,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2560,
height: 424,
),
],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/EDatBjgcL94-qSfQa5Twr8l88hYcAXQJksDrwARWbotrWzJhG03gRyZLKV1mk1a1tMI_LSg4qg=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
content: Paginator(
count: Some(0),
items: [],
ctoken: None,
),
)

View file

@ -0,0 +1,721 @@
---
source: src/client/channel.rs
expression: map_res.c
---
Channel(
id: "UCh8gHdtzO2tXd593_bjErWg",
name: "Doobydobap",
subscriber_count: Some(2840000),
avatar: [
Thumbnail(
url: "https://yt3.ggpht.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s48-c-k-c0x00ffffff-no-rj",
width: 48,
height: 48,
),
Thumbnail(
url: "https://yt3.ggpht.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s88-c-k-c0x00ffffff-no-rj",
width: 88,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/dm5Aq93xvVJz0NoVO88ieBkDXmuShCujGPlZ7qETMEPTrXvPUCFI3-BB6Xs_P-r6Uk3mnBy9zA=s176-c-k-c0x00ffffff-no-rj",
width: 176,
height: 176,
),
],
description: "Hi, Im Tina, aka Doobydobap!\n\nFood is the medium I use to tell stories and connect with people who share the same passion as I do. Whether its because youre hungry at midnight or trying to learn how to cook, I hope you enjoy watching my content and recipes. Don\'t yuck my yum!\n\nwww.doobydobap.com\n",
tags: [],
vanity_url: Some("https://www.youtube.com/c/Doobydobap"),
banner: [
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1060,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1138,
height: 188,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 1707,
height: 283,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w2120-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2276,
height: 377,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
width: 2560,
height: 424,
),
],
mobile_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 320,
height: 88,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 640,
height: 175,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 960,
height: 263,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 351,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
width: 1440,
height: 395,
),
],
tv_banner: [
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 320,
height: 180,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 854,
height: 480,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1280,
height: 720,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 1920,
height: 1080,
),
Thumbnail(
url: "https://yt3.ggpht.com/BvnAqgiursrXpmS9AgDLtkOSTQfOG_Dqn0KzY5hcwO9XrHTEQTVgaflI913f9KRp7d0U2qBp=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
width: 2120,
height: 1192,
),
],
content: Paginator(
count: None,
items: [
ChannelVideo(
id: "JBUZE0mIlg8",
title: "small but sure joy",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/JBUZE0mIlg8/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLCRBlyIUBUm_aypWz4tGkrDNJxIZw",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 day ago"),
view_count: Some(443549),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "SRrvxFc2b2c",
title: "i don\'t believe in long distance relationships",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/SRrvxFc2b2c/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLA0hJdOfUp-zMI-vW43sYnKgufocA",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 days ago"),
view_count: Some(1154962),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "l9TiwunjzgA",
title: "long distance",
length: Some(1043),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/l9TiwunjzgA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDjM6SZ7ScyfFRr13QdVmIvWEWWrQ",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/l9TiwunjzgA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDmjuvrAkYrdvhuU-Nl8jzx4so9oA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/l9TiwunjzgA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBJ5ZEDrtK_1oM20uRPmzPjDpUhrQ",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/l9TiwunjzgA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCb6F-jiGZ5aYaq7HBh2if85d_t0A",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("3 days ago"),
view_count: Some(477460),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "cNx0ql9gnf4",
title: "come over :)",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/cNx0ql9gnf4/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLBvAKRZE2LyKIo6_6prX9pzfiWoVw",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("6 days ago"),
view_count: Some(1388173),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "fGQUWI4o__A",
title: "Baskin Robbins in South Korea",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/fGQUWI4o__A/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDyPuI762qzLAZM0QikxjFKVpoF9w",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("7 days ago"),
view_count: Some(1738301),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "Q73VTjdqVA8",
title: "dry hot pot",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/Q73VTjdqVA8/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLBfJXtFWfAnyMOvaJfvpYJ5WrhbSA",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("9 days ago"),
view_count: Some(1316594),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "pRVSdUxdsVw",
title: "Repairing...",
length: Some(965),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/pRVSdUxdsVw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAQWneuYcJcccgooBfa3WI4LdYF3w",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/pRVSdUxdsVw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAO8o5qPYTUPF4yyBLSpYBeE6lMSA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/pRVSdUxdsVw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLClJOy_nxUK-ACJUduXzk-khvwmpQ",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/pRVSdUxdsVw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB6k0Egq5r3hNjamUiia-lh-n2EEA",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("10 days ago"),
view_count: Some(478703),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "gTG2WDbiYGo",
title: "time machine",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/gTG2WDbiYGo/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDw5Lw19mNLJnoIF3aCGkMbxvgILQ",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("11 days ago"),
view_count: Some(1412213),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "y5JK5YFp92g",
title: "tiramissu",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/y5JK5YFp92g/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLCR66ytQIBWWw_ajvgyaUdUawHVIg",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("13 days ago"),
view_count: Some(1513305),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "pvSWHm4wlxY",
title: "having kids",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/pvSWHm4wlxY/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDt7ZAwQoObfa5A7gC_hJnU1WH4Ug",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"),
view_count: Some(8936223),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "2FJVhdOO0F0",
title: "a health scare",
length: Some(1238),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/2FJVhdOO0F0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA5ambaz-euRsB9VG5ANaYFUUSEbg",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/2FJVhdOO0F0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBAbpE1_Iiqdmwbm_IbUFPxkyjmhg",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/2FJVhdOO0F0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCLrwdM2QBdnaFPEpsmMVaAQq3vug",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/2FJVhdOO0F0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAccJCJ5-5TLOBSooo4jeojbbfn9A",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"),
view_count: Some(987083),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "CqFGACRrWJE",
title: "just do it",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/CqFGACRrWJE/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDyAIF4S_foRXsyvq16YCPJWNKewQ",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 weeks ago"),
view_count: Some(2769717),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "CutR_1SDDzY",
title: "feels good to be back",
length: Some(1159),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/CutR_1SDDzY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAt413Uk4xhHjYwpLI5-DXuOsFouA",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/CutR_1SDDzY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDd-m1YaVdVXcUh98FRzstRUn03Pw",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/CutR_1SDDzY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBHgcMGTg11_LzuQOHo4oAUBtsfKg",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/CutR_1SDDzY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDZtPA-3fS7BwVhuIHDbusLbw0Dqg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"),
view_count: Some(497660),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "DdGr6t2NqKc",
title: "coming soon",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/DdGr6t2NqKc/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDRYfxh25EjK3zuOJORNNahxeBanA",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"),
view_count: Some(572107),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "jKS44NMWuXw",
title: "adult money",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/jKS44NMWuXw/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLAIexckdN7FXJUgkeJvITHyzXw1TQ",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"),
view_count: Some(1707132),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "kx1YtJM_vbI",
title: "a fig\'s journey",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/kx1YtJM_vbI/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLAi03nhSbt84LL7PFD2ij8GmaDlLQ",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("3 weeks ago"),
view_count: Some(933094),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "Sdbzs-1WWH0",
title: "How to.. Mozzarella 🧀",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/Sdbzs-1WWH0/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLC8IkwAif4wXhBGxHiosiILbPCSBw",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(5985184),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "9qBHyJIDous",
title: "how to drink like a real korean",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/9qBHyJIDous/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLB9Ib_E0siDiRMZ_GVHVxBfMd0Dkw",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(14741387),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "mBeFDb4gp8s",
title: "mr. krabs soup",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/mBeFDb4gp8s/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLCzAPzv16WTJLr4ma-sAz6fNkFL0g",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(2511322),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "b38r1UYqoBQ",
title: "in five years",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/b38r1UYqoBQ/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLCGB9IpC2Enx5iZ-YCl0vEpMGpo9A",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(2364408),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "KUz7oArksR4",
title: "running away",
length: Some(1023),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/KUz7oArksR4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD1NwuIgJuJy2oPAiHqMre6rbcuPA",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/KUz7oArksR4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBW8VcMIUoAKbd8tNzfO1KmmZp9eA",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/KUz7oArksR4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDr9DmdJzOC9_PIqkx2GO7xol_2vA",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/KUz7oArksR4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLABH3-3faYHCYhoZUFbOey9w3HD2w",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(706059),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "RdFk4WaifEo",
title: "a weeknight dinner",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/RdFk4WaifEo/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLBlKLBjBagaTQj24nYb-HkCQQcWHA",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(1947627),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "GuyGyzZcumI",
title: "McDonald\'s Michelin Burger",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/GuyGyzZcumI/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDtmyilZAgMw8VWNy518etIKi4phA",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(4763839),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "07Zipsb3-qU",
title: "cwispy potato pancake",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/07Zipsb3-qU/hq720_2.jpg?sqp=-oaymwEdCJYDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLARXBTZlNStCVemXSkHfAWksRogng",
width: 406,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(1915695),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "3kaePnU6Clo",
title: "authenticity is overrated",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/3kaePnU6Clo/hq720_2.jpg?sqp=-oaymwEdCJYDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDq0MY9dsMvr9Y6yaJ7069fgtdpGA",
width: 406,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(7268944),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "rt4rXMftnpg",
title: "you can kimchi anything (T&C applies)",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/rt4rXMftnpg/hq720_2.jpg?sqp=-oaymwEdCJUDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLC7WfSTGHkH2FEmn9gQ5E4AqpRtug",
width: 405,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("1 month ago"),
view_count: Some(2539103),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "DTyLUvbf128",
title: "egg, soy, and perfect pot rice",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/DTyLUvbf128/hq720_2.jpg?sqp=-oaymwEdCJYDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLAN1AtPya1D1NyiO0XYKOjIZIyhhQ",
width: 406,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 months ago"),
view_count: Some(5545680),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "DzjLBgIe_aI",
title: "love language",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/DzjLBgIe_aI/hq720_2.jpg?sqp=-oaymwEdCJYDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLDWVkrYrt64LvvxrMRfs29g_lGrNw",
width: 406,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 months ago"),
view_count: Some(2202314),
is_live: false,
is_short: true,
),
ChannelVideo(
id: "sPb2gyN-hnE",
title: "worth fighting for",
length: Some(1232),
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/sPb2gyN-hnE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBidXnS47SJMkvOlqt2DgzHxr6wKQ",
width: 168,
height: 94,
),
Thumbnail(
url: "https://i.ytimg.com/vi/sPb2gyN-hnE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCOxYF8A5DQVdZHh5O1vAdK-1qH1g",
width: 196,
height: 110,
),
Thumbnail(
url: "https://i.ytimg.com/vi/sPb2gyN-hnE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBhQ9ZJs0bgGqdGb8t26tbjtmIKWA",
width: 246,
height: 138,
),
Thumbnail(
url: "https://i.ytimg.com/vi/sPb2gyN-hnE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB35l1byuqA4pkl2SzE8Cr0vmPVGg",
width: 336,
height: 188,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 months ago"),
view_count: Some(613416),
is_live: false,
is_short: false,
),
ChannelVideo(
id: "9JboRKeJ2m4",
title: "Rating Italian McDonald\'s",
length: None,
thumbnail: [
Thumbnail(
url: "https://i.ytimg.com/vi/9JboRKeJ2m4/hq720_2.jpg?sqp=-oaymwEdCJYDENAFSFXyq4qpAw8IARUAAIhCcAHAAQbQAQE=&rs=AOn4CLC7xktrbnAqJq2nHH9aDggULsb3Cg",
width: 406,
height: 720,
),
],
publish_date: "[date]",
publish_date_txt: Some("2 months ago"),
view_count: Some(6443699),
is_live: false,
is_short: true,
),
],
ctoken: Some("4qmFsgKrARIYVUNoOGdIZHR6TzJ0WGQ1OTNfYmpFcldnGmBFZ1oyYVdSbGIzTVlBeUFBTUFFNEFlb0RNRVZuYzBrM2NsTnVkazF4U1hWemRqQkJVMmQ1VFVGRk5FaHJTVXhEVUhac2NscHJSMFZKWVhWd016RkpRVlpCUVElM0QlM0SaAixicm93c2UtZmVlZFVDaDhnSGR0ek8ydFhkNTkzX2JqRXJXZ3ZpZGVvczEwMg%3D%3D"),
),
)

View file

@ -14,7 +14,7 @@ Paginator(
Text("🏻"),
Text("💗"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCKv2ITDFlBf8sCaM4bGAq9w",
name: "rüyaabiee",
avatar: [
@ -55,7 +55,7 @@ Paginator(
text: RichText([
Text("Mys, spotify wraps comes in a few months..so start str3ming Aespa all songs on spotify."),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCpO0iV02gvz1zY0xaEip-Lw",
name: "Ashdeep Sidashi",
avatar: [
@ -97,7 +97,7 @@ Paginator(
Text("Cerita black mamba kan udah tutup buku. Kira2 nanti konsep comebacknya apa yaa? "),
Text("😍"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC8Uu90kmT1uBXMuylOe5F2g",
name: "Ini Aku",
avatar: [
@ -142,7 +142,7 @@ Paginator(
Text("\n"),
Text("👇"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCKBVxnCV35xZ9Oe1U6DLENQ",
name: "Brian Kenneth",
avatar: [
@ -183,7 +183,7 @@ Paginator(
text: RichText([
Text("Love this song so much"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCsJS5T1NM3Ra7HLmiPjxeGg",
name: "milky way",
avatar: [
@ -224,7 +224,7 @@ Paginator(
text: RichText([
Text("They are the background of our karaoke"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCh6Qqw1NFPNi6l7kfU1b4PA",
name: "ae 💜",
avatar: [
@ -265,7 +265,7 @@ Paginator(
text: RichText([
Text("AESPA"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCh6Qqw1NFPNi6l7kfU1b4PA",
name: "ae 💜",
avatar: [
@ -306,7 +306,7 @@ Paginator(
text: RichText([
Text("AVATAR EXPERIENCE ASPECT"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCh6Qqw1NFPNi6l7kfU1b4PA",
name: "ae 💜",
avatar: [
@ -347,7 +347,7 @@ Paginator(
text: RichText([
Text("HEIHH!!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCgTOQ5KTAurWso9Hw2IGVow",
name: "WinterMyUniverse",
avatar: [
@ -388,7 +388,7 @@ Paginator(
text: RichText([
Text("Road to 234M!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCuTNUUpUzXVljMSEy1YooZw",
name: "The Ultimate 1",
avatar: [
@ -429,7 +429,7 @@ Paginator(
text: RichText([
Text("Happy 4m likes!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCbfj_QOoelszMm1JlXpY7nw",
name: "Sim Layla",
avatar: [
@ -470,7 +470,7 @@ Paginator(
text: RichText([
Text("MY\'s and aespa go fighting!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCh6Qqw1NFPNi6l7kfU1b4PA",
name: "ae 💜",
avatar: [
@ -511,7 +511,7 @@ Paginator(
text: RichText([
Text("I hope they bring back this colorful set for the next comeback"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCh6Qqw1NFPNi6l7kfU1b4PA",
name: "ae 💜",
avatar: [
@ -552,7 +552,7 @@ Paginator(
text: RichText([
Text("Keep str3aming MY\'s"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCh6Qqw1NFPNi6l7kfU1b4PA",
name: "ae 💜",
avatar: [
@ -593,7 +593,7 @@ Paginator(
text: RichText([
Text("Ji-min-jeong Cross!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCh6Qqw1NFPNi6l7kfU1b4PA",
name: "ae 💜",
avatar: [
@ -634,7 +634,7 @@ Paginator(
text: RichText([
Text("BEST DEBUT EVER !!!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC-wGUUnJO1gTAw011kCGwfQ",
name: "darkangel",
avatar: [
@ -675,7 +675,7 @@ Paginator(
text: RichText([
Text("เพลงโครตน\u{e48}าเบ\u{e37}\u{e48}อ ด\u{e35}แค\u{e48} cg"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCE7UmaNfXFkZ8iO8SZnx1_g",
name: "Hopi your",
avatar: [
@ -716,7 +716,7 @@ Paginator(
text: RichText([
Text("233230"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCTV1SSSkB8Rr9Y5pD1tN8eA",
name: "Agus Sudrajat",
avatar: [

View file

@ -13,7 +13,7 @@ Paginator(
Text("\n"),
Text("👇"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC--QwZHg12dkw8UKw5yB1MQ",
name: "Agalla, Andre",
avatar: [
@ -54,7 +54,7 @@ Paginator(
text: RichText([
Text("Chicas vamos por los 300M, démosle a todas esas haters chorrillo masivo fulminante de la envidia. Vamos, Mys puede a llegar a ser poderoso si nos unimos. Vamos por los 300M solo nos falta poco para llegar!!!!!!! Vamos Mys, alcemos nuestro teléfonos y brindemos por lo que puede hacer las Mys por Aespa"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCqT9iACjb69o254SFlUjcDQ",
name: "Camila paz",
avatar: [
@ -95,7 +95,7 @@ Paginator(
text: RichText([
Text("The best 4th gen group debut for me. Camerawork, artistic value, choreography, concept, make up and styling, this one nailed ALL."),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC00F5JjCjDDum6MlP3eloxw",
name: "The Charging Knight of Amarapura",
avatar: [
@ -136,7 +136,7 @@ Paginator(
text: RichText([
Text("Black Manba o MV mais icônico do aespa amooooi"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCbfGo61YSYOlfyF1cWejhng",
name: "Kim Jamily Sun",
avatar: [
@ -177,7 +177,7 @@ Paginator(
text: RichText([
Text("MYs if we want to make Black Mamba the most debut MV for 4th gen- let us keep on strêaming. Consistency is the key."),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCITMz9SiXQrV-cltI-9Auuw",
name: "Stream Girls, Savage, Next Level and Black Mamba",
avatar: [
@ -223,7 +223,7 @@ Paginator(
Text("\n"),
Text("(ps. Winter is my love <3)"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCDaOL1lsanMlpbzaQunz47Q",
name: "ehe",
avatar: [
@ -270,7 +270,7 @@ Paginator(
Text("\n"),
Text("Forever, Dreams come true --> 50 M"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC2P4Zx1o4D3VQIjA_MIToQQ",
name: "edits&fun",
avatar: [
@ -311,7 +311,7 @@ Paginator(
text: RichText([
Text("Logremos más de 250M Antes de que se termine el año ♡"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC5cxR3XtdfVR_XT3sfIKdNg",
name: "Black mamba 🐍💜",
avatar: [
@ -352,7 +352,7 @@ Paginator(
text: RichText([
Text("Llevemos está Masterpiece a los 300M!! ಥ‿ಥ♡ Don\'t stop My, 230M soon"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC5cxR3XtdfVR_XT3sfIKdNg",
name: "Black mamba 🐍💜",
avatar: [
@ -393,7 +393,7 @@ Paginator(
text: RichText([
Text("Keep streaming my\'s let\'s reach 300 million views before aespa\'s full album comeback."),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCfQOeizIiPTG3hgKa-6MOeA",
name: "K-POP",
avatar: [
@ -436,7 +436,7 @@ Paginator(
Text("\n"),
Text("Vamos que si se puede"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCgRWbRJqUHCvWv6xOuB4few",
name: "Karina González",
avatar: [
@ -477,7 +477,7 @@ Paginator(
text: RichText([
Text("DENLE LIKE AL MV Q FALTA POCO PARA LOS 4M DE LIKES ¡!¡!¡"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCBqR9kJhtiHLE6dP-Oo_DMQ",
name: "yujiminemo",
avatar: [
@ -518,7 +518,7 @@ Paginator(
text: RichText([
Text("146 millones vamos por 147 millones si se puede vamos a por mas GO"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCjbUNOs6PAAAAo3_feDwLQA",
name: "OLIVER79K",
avatar: [
@ -559,7 +559,7 @@ Paginator(
text: RichText([
Text("Best MV debut for this gen!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCjXq-4-e-OKn1S3SB52wHRQ",
name: "viclusiv",
avatar: [
@ -600,7 +600,7 @@ Paginator(
text: RichText([
Text("Ya es 2022 y aún no superó este M/V, stream mys para los 300M!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCwan9APGANDUfYdYBbU6OeQ",
name: "mynlemus",
avatar: [
@ -641,7 +641,7 @@ Paginator(
text: RichText([
Text("I get goosebump every single time it comes to NingNings high note. Baby youre amazingggg"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC3IEDx0AQiUOP8FtC_MlyFQ",
name: "Yến Anh",
avatar: [
@ -682,7 +682,7 @@ Paginator(
text: RichText([
Text("This is still the best K-pop debut <3 MYS LETS STREAM HARD FOR GIRLS"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UC2vbH7mtFRTiPGLRt9l_OSw",
name: "Flavia",
avatar: [
@ -723,7 +723,7 @@ Paginator(
text: RichText([
Text("Don\'t be shy SM Entertainment! Give the girls another legendary comeback!"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCWgL2cewcYnsIqwN1tMikJg",
name: "⇮ æluvieyou ⇮",
avatar: [
@ -764,7 +764,7 @@ Paginator(
text: RichText([
Text("aespa\'s debut song is really powerful. I\'ve been listening to this song many times since its release. But, the energy the song is sending me is just as powerful"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCN4tkZuSBXlZ5b9E8CETBUw",
name: "MYSoneluvie",
avatar: [
@ -807,7 +807,7 @@ Paginator(
Text("🔥"),
Text("💎"),
]),
author: Some(Channel(
author: Some(ChannelTag(
id: "UCoU9ZmBOV-CB2Mjl_JM3-ZA",
name: "Melodies_Memory of exy",
avatar: [

View file

@ -21,7 +21,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -55,7 +55,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCYDmx2Sfpnaxg488yBpZIGg",
name: "starshipTV",
avatar: [
@ -89,7 +89,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC_pwIXKXNm5KGhdEVzmY60A",
name: "Stone Music Entertainment",
avatar: [
@ -123,7 +123,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCS_hnpJLQTvBkqALgapi_4g",
name: "스브스케이팝 X INKIGAYO",
avatar: [
@ -157,7 +157,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa",
avatar: [
@ -191,7 +191,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -225,7 +225,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -259,7 +259,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK",
avatar: [
@ -293,7 +293,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa",
avatar: [
@ -327,7 +327,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCritGVo7pLJLUS8wEu32vow",
name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)",
avatar: [
@ -361,7 +361,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -395,7 +395,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -429,7 +429,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -463,7 +463,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -497,7 +497,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -531,7 +531,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa",
avatar: [
@ -565,7 +565,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK",
avatar: [
@ -599,7 +599,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCuhAUMLzJxlP1W7mEk0_6lA",
name: "MAMAMOO",
avatar: [
@ -633,7 +633,7 @@ Paginator(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [

View file

@ -6,7 +6,7 @@ VideoDetails(
id: "HRKu0cvrr_o",
title: "AlphaOmegaSin Fanboy Logic: Likes/Dislikes Disabled = Point Invalid Lol wtf?",
description: RichText([]),
channel: Channel(
channel: ChannelTag(
id: "UCQT2yul0lr6Ie9qNQNmw-sg",
name: "PrinceOfFALLEN",
avatar: [

View file

@ -18,7 +18,7 @@ VideoDetails(
Text("\n\n"),
Text("#36C3"),
]),
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -67,7 +67,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -101,7 +101,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCBWSgdr27NcLig0XzWLq2gQ",
name: "MISS-VERSTEHEN SIE MICH RICHTIG",
avatar: [
@ -135,7 +135,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -169,7 +169,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -203,7 +203,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -237,7 +237,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -271,7 +271,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -305,7 +305,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -339,7 +339,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCvZLsBb-8Og4FvBUom9zPHQ",
name: "Universität Bayreuth",
avatar: [
@ -373,7 +373,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -407,7 +407,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -441,7 +441,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -475,7 +475,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCLLibJTCy3sXjHLVaDimnpQ",
name: "ARTEde",
avatar: [
@ -509,7 +509,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -543,7 +543,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -577,7 +577,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -611,7 +611,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [
@ -645,7 +645,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCeO-zvUfuEdPMDoNST6hy1A",
name: "Killuminati ∆",
avatar: [
@ -679,7 +679,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2TXq_t06Hjdr2g_KdKpHQg",
name: "media.ccc.de",
avatar: [

View file

@ -229,7 +229,7 @@ VideoDetails(
),
Text(" Conclusion"),
]),
channel: Channel(
channel: ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips",
avatar: [
@ -503,7 +503,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips",
avatar: [
@ -537,7 +537,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips",
avatar: [
@ -571,7 +571,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCdBK94H6oZT2Q7l0-b0xmMg",
name: "ShortCircuit",
avatar: [
@ -605,7 +605,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC7Jwj9fkrf1adN4fMmTkpug",
name: "DankPods",
avatar: [
@ -639,7 +639,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips",
avatar: [
@ -673,7 +673,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCKd49wwdEdIoM-7Fumhwmog",
name: "Quint BUILDs",
avatar: [
@ -707,7 +707,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEIwxahdLz7bap-VDs9h35A",
name: "Steve Mould",
avatar: [
@ -741,7 +741,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCkWQ0gDrqOCarmUKmppD7GQ",
name: "JayzTwoCents",
avatar: [
@ -775,7 +775,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UChIZGfcnjHI0DG4nweWEduw",
name: "TechSource",
avatar: [
@ -809,7 +809,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVveEFTOd6khhSXXnRhxJmg",
name: "Fireball Tool",
avatar: [
@ -843,7 +843,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCq1Oqk1I7zeYlDiJTFWLoFA",
name: "Electric Classic Cars",
avatar: [
@ -877,7 +877,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCvJJ_dzjViJCoLf5uKUTwoA",
name: "CNBC",
avatar: [
@ -911,7 +911,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCMiJRAwDNSNzuYeN2uWa0pA",
name: "Mrwhosetheboss",
avatar: [
@ -945,7 +945,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC_SLthyNX_ivd-dmsFgmJVg",
name: "Jeremy Fielding",
avatar: [
@ -979,7 +979,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips",
avatar: [
@ -1013,7 +1013,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCupQghOyPai8Hxg4RqMERvA",
name: "incT",
avatar: [
@ -1047,7 +1047,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips",
avatar: [
@ -1081,7 +1081,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCXuqSBlHAE6Xw-yeJA0Tunw",
name: "Linus Tech Tips",
avatar: [
@ -1115,7 +1115,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCYmna5rFHIesFteksAvFOfg",
name: "Dr. Plants",
avatar: [

View file

@ -38,7 +38,7 @@ VideoDetails(
url: "http://incompetech.com/music/royalty-free/",
),
]),
channel: Channel(
channel: ChannelTag(
id: "UCakgsb0w7QB0VHdnCc-OVEA",
name: "Space Videos",
avatar: [
@ -87,7 +87,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC_sXrcURB-Dh4az_FveeQ0Q",
name: "DOCUMENTARY TUBE",
avatar: [
@ -121,7 +121,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCakgsb0w7QB0VHdnCc-OVEA",
name: "Space Videos",
avatar: [
@ -155,7 +155,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCZepiiyNNbD2XL5sWnJBC_A",
name: "Videotizer",
avatar: [
@ -189,7 +189,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCNrGOnduIS9BXIRmDcHasZA",
name: "WorldCam",
avatar: [
@ -223,7 +223,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCelk6aHijZq-GJBBB9YpReA",
name: "BBC News عربي",
avatar: [
@ -257,7 +257,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC_sXrcURB-Dh4az_FveeQ0Q",
name: "DOCUMENTARY TUBE",
avatar: [
@ -291,7 +291,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCj-Xm8j6WBgKY8OG7s9r2vQ",
name: "RailCowGirl",
avatar: [
@ -325,7 +325,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCR9sFzaG9Ia_kXJhfxtFMBA",
name: "melodysheep",
avatar: [
@ -359,7 +359,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCakgsb0w7QB0VHdnCc-OVEA",
name: "Space Videos",
avatar: [
@ -393,7 +393,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCRI_rCIV69l-PmT3oyD64kw",
name: "Afraz Explores",
avatar: [
@ -427,7 +427,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCZvxw99l3xDC6BIHb8nJKGg",
name: "ElderFox Documentaries",
avatar: [
@ -461,7 +461,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC2ccm1GajfSujz7T18d7cKA",
name: "BBC Studios",
avatar: [
@ -495,7 +495,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCyrM5blUZAQoX9UvObdjtig",
name: "Valdemar Gomes",
avatar: [
@ -529,7 +529,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCgP30k64HHZ0OY1QkEgS6Pw",
name: "Waa Sop",
avatar: [
@ -563,7 +563,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCBuDzfvztEJvNll_w1E9xFw",
name: "The Random Theorizer",
avatar: [
@ -597,7 +597,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCIBaDdAbGlFDeS33shmlD0A",
name: "European Space Agency, ESA",
avatar: [
@ -631,7 +631,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCakgsb0w7QB0VHdnCc-OVEA",
name: "Space Videos",
avatar: [
@ -665,7 +665,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC1znqKFL3jeR0eoA0pHpzvw",
name: "SpaceRip",
avatar: [
@ -699,7 +699,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC28l88GMXXqZYfY0Ru9h50w",
name: "Seán Doran",
avatar: [
@ -733,7 +733,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCDyeuRnxf_hxEyH1B7aoDQQ",
name: "thebhp",
avatar: [

View file

@ -8,7 +8,7 @@ VideoDetails(
description: RichText([
Text("Provided to YouTube by Universal Music Group\n\nGäa · Oonagh\n\nBest Of\n\n℗ An Airforce1 Records / We Love Music recording; ℗ 2014 Universal Music GmbH\n\nReleased on: 2020-08-07\n\nProducer, Associated Performer, Background Vocalist: Hardy Krech\nProducer: Mark Nissen\nAssociated Performer, Background Vocalist: Andreas Fahnert\nAssociated Performer, Background Vocalist: Velile Mchunu\nAssociated Performer, Background Vocalist: Billy King\nAssociated Performer, Background Vocalist: Alex Prince\nAssociated Performer, Flute: Sandro Friedrich\nProgrammer: Hartmut Krech\nEditor: Severin Zahler\nComposer Lyricist: Hartmut Krech\nComposer Lyricist: Mark Nissen\nAuthor: Lukas Hainer\nAuthor: Michael Boden\n\nAuto-generated by YouTube."),
]),
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -57,7 +57,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -91,7 +91,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -125,7 +125,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -159,7 +159,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -193,7 +193,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -227,7 +227,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -261,7 +261,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -295,7 +295,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -329,7 +329,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -363,7 +363,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -397,7 +397,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC8mcGChRS6Zm7pCSYbHeoVw",
name: "princessZelda",
avatar: [
@ -431,7 +431,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -465,7 +465,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [
@ -499,7 +499,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCVGvnqB-5znqPSbMGlhF4Pw",
name: "Sentamusic",
avatar: [

View file

@ -69,7 +69,7 @@ VideoDetails(
Text("#에스파"),
Text("\naespa 에스파 \'Black Mamba\' MV ℗ SM Entertainment"),
]),
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -118,7 +118,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -152,7 +152,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -186,7 +186,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC_pwIXKXNm5KGhdEVzmY60A",
name: "Stone Music Entertainment",
avatar: [
@ -220,7 +220,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCuhAUMLzJxlP1W7mEk0_6lA",
name: "MAMAMOO",
avatar: [
@ -254,7 +254,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCritGVo7pLJLUS8wEu32vow",
name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)",
avatar: [
@ -288,7 +288,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -322,7 +322,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -356,7 +356,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -390,7 +390,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -424,7 +424,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -458,7 +458,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -492,7 +492,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK",
avatar: [
@ -526,7 +526,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -560,7 +560,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK",
avatar: [
@ -594,7 +594,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -628,7 +628,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCYDmx2Sfpnaxg488yBpZIGg",
name: "starshipTV",
avatar: [
@ -662,7 +662,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCK8S6QMrTk1G8TYQwIyDo-w",
name: "𝙇𝙌 𝙆𝙋𝙊𝙋",
avatar: [
@ -696,7 +696,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa",
avatar: [

View file

@ -69,7 +69,7 @@ VideoDetails(
Text("#에스파"),
Text("\naespa 에스파 \'Black Mamba\' MV ℗ SM Entertainment"),
]),
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -118,7 +118,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCQYl87Oi9aWzz-CLhTw3Rzg",
name: "Allan Nascimento",
avatar: [
@ -152,7 +152,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCgqMjKxRWAKUvgYqgomighw",
name: "KBS충북",
avatar: [
@ -186,7 +186,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCweOkPb1wVVH0Q0Tlj4a5Pw",
name: "1theK (원더케이)",
avatar: [
@ -220,7 +220,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCqECaJ8Gagnn7YCbPEzWH6g",
name: "Taylor Swift",
avatar: [
@ -254,7 +254,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCweOkPb1wVVH0Q0Tlj4a5Pw",
name: "1theK (원더케이)",
avatar: [
@ -288,7 +288,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -322,7 +322,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -356,7 +356,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -390,7 +390,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCK8S6QMrTk1G8TYQwIyDo-w",
name: "LQ K-POP",
avatar: [
@ -424,7 +424,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCYvmuw-JtVrTZQ-7Y4kd63Q",
name: "Katy Perry",
avatar: [
@ -458,7 +458,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK",
avatar: [
@ -492,7 +492,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCaO6TYtlC8U5ttz62hTrZgg",
name: "JYP Entertainment",
avatar: [
@ -526,7 +526,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCOmHUn--16B90oW2L6FRR3A",
name: "BLACKPINK",
avatar: [
@ -560,7 +560,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UC9GtSLeksfK4yuJ_g1lgQbg",
name: "aespa",
avatar: [
@ -594,7 +594,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCritGVo7pLJLUS8wEu32vow",
name: "(G)I-DLE (여자)아이들 (Official YouTube Channel)",
avatar: [
@ -628,7 +628,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCEf_Bc-KVd7onSeifS3py9g",
name: "SMTOWN",
avatar: [
@ -662,7 +662,7 @@ VideoDetails(
height: 188,
),
],
channel: Channel(
channel: ChannelTag(
id: "UCk9GmdlDTBfgGRb7vXeRMoQ",
name: "Red Velvet",
avatar: [

View file

@ -6,7 +6,8 @@ use serde::Serialize;
use crate::{
model::{
Channel, ChannelId, Chapter, Comment, Language, Paginator, RecommendedVideo, VideoDetails,
ChannelId, ChannelTag, Chapter, Comment, Language, Paginator, RecommendedVideo,
VideoDetails,
},
serializer::MapResult,
timeago,
@ -302,7 +303,7 @@ impl MapResponse<VideoDetails> for response::VideoDetails {
id: video_id,
title,
description,
channel: Channel {
channel: ChannelTag {
id: channel_id,
name: channel_name,
avatar: owner.thumbnail.into(),
@ -432,7 +433,7 @@ fn map_recommendations(
util::parse_video_length_or_warn(&txt, &mut warnings)
}),
thumbnail: video.thumbnail.into(),
channel: Channel {
channel: ChannelTag {
id: channel.id,
name: channel.name,
avatar: video.channel_thumbnail.into(),
@ -511,7 +512,7 @@ fn map_comment(
id: c.comment_id,
text: c.content_text.into(),
author: match (c.author_endpoint, c.author_text) {
(Some(aep), Some(name)) => Some(Channel {
(Some(aep), Some(name)) => Some(ChannelTag {
id: aep.browse_endpoint.browse_id,
name,
avatar: c.author_thumbnail.into(),

View file

@ -1,11 +1,13 @@
pub mod locale;
mod ordering;
mod paginator;
mod param;
pub mod richtext;
pub mod stream_filter;
pub use locale::{Country, Language};
pub use paginator::Paginator;
pub use param::ChannelOrder;
use std::ops::Range;
@ -233,7 +235,7 @@ pub struct VideoDetails {
/// Video description
pub description: RichText,
/// Channel of the video
pub channel: Channel,
pub channel: ChannelTag,
/// Number of views / current viewers in case of a livestream.
pub view_count: u64,
/// Number of likes
@ -299,7 +301,7 @@ pub struct RecommendedVideo {
/// Video thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Channel of the video
pub channel: Channel,
pub channel: ChannelTag,
/// Video publishing date.
///
/// `None` if the date could not be parsed.
@ -318,7 +320,7 @@ pub struct RecommendedVideo {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct Channel {
pub struct ChannelTag {
/// Unique YouTube channel ID
pub id: String,
/// Channel name
@ -368,7 +370,7 @@ pub struct Comment {
/// Comment author
///
/// There may be comments with missing authors (possibly deleted users?).
pub author: Option<Channel>,
pub author: Option<ChannelTag>,
/// Comment publishing date.
///
/// `None` if the date could not be parsed.
@ -395,7 +397,7 @@ pub struct Comment {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChannelVideos {
pub struct Channel<T> {
/// Unique YouTube Channel-ID (e.g. `UC-lHJZR3Gqxm24_Vd_AJ5Yw`)
pub id: String,
/// Channel name
@ -405,8 +407,23 @@ pub struct ChannelVideos {
/// `None` if the subscriber count was hidden by the owner
/// or could not be parsed.
pub subscriber_count: Option<u64>,
/// Videos fetched from the channel
pub videos: Paginator<ChannelVideo>,
/// Channel avatar / profile picture
pub avatar: Vec<Thumbnail>,
/// Channel description text
pub description: String,
/// List of words to describe the topic of the channel
pub tags: Vec<String>,
/// Custom URL set by the channel owner
/// (e.g. <https://www.youtube.com/c/EevblogDave>)
pub vanity_url: Option<String>,
/// Banner image shown above the channel
pub banner: Vec<Thumbnail>,
/// Banner image shown above the channel (small format for mobile)
pub mobile_banner: Vec<Thumbnail>,
/// Banner image shown above the channel (16:9 fullscreen format for TV)
pub tv_banner: Vec<Thumbnail>,
/// Content fetched from the channel
pub content: T,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
@ -439,3 +456,27 @@ pub struct ChannelVideo {
/// Is the video a YouTube Short video (vertical and <60s)?
pub is_short: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChannelPlaylist {
/// Unique YouTube Playlist-ID (e.g. `PL5dDx681T4bR7ZF1IuWzOv1omlRbE7PiJ`)
pub id: String,
/// Playlist name
pub name: String,
/// Playlist thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Number of playlist videos
pub video_count: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct ChannelInfo {
/// Channel creation date
pub create_date: Option<DateTime<Local>>,
/// Channel view count
pub view_count: Option<u64>,
/// Links to other websites or social media profiles
pub links: Vec<(String, String)>,
}

11
src/model/param.rs Normal file
View file

@ -0,0 +1,11 @@
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ChannelOrder {
/// Output the latest videos first
#[default]
Latest,
/// Output the oldest videos first
Oldest,
/// Output the most viewed videos first
Popular,
}

View file

@ -41,6 +41,25 @@ where
}
}
impl<T> MapResult<T>
where
T: Default,
{
pub fn error(msg: String) -> Self {
Self {
c: T::default(),
warnings: vec![msg],
}
}
pub fn ok(c: T) -> Self {
Self {
c,
warnings: Vec::new(),
}
}
}
/// Deserialization method that consumes anything and returns an empty value.
/// Intended to be used for a wildcard enum option.
///

View file

@ -225,8 +225,10 @@ pub enum PageType {
Playlist,
}
fn map_richtext_run(run: RichTextRun) -> TextComponent {
map_text_component(run.text, run.navigation_endpoint)
impl From<RichTextRun> for TextComponent {
fn from(run: RichTextRun) -> Self {
map_text_component(run.text, run.navigation_endpoint)
}
}
/// Map a single component of a rich text
@ -270,7 +272,7 @@ impl<'de> Deserialize<'de> for TextComponent {
));
}
Ok(map_richtext_run(text.runs.swap_remove(0)))
Ok(text.runs.swap_remove(0).into())
}
}
@ -280,7 +282,9 @@ impl<'de> Deserialize<'de> for TextComponents {
D: Deserializer<'de>,
{
let text = RichTextInternal::deserialize(deserializer)?;
Ok(Self(text.runs.into_iter().map(map_richtext_run).collect()))
Ok(Self(
text.runs.into_iter().map(TextComponent::from).collect(),
))
}
}
@ -295,7 +299,7 @@ impl<'de> DeserializeAs<'de, TextComponents> for AttributedText {
let mut chars = text.content.chars();
// Take a string from the char iterator until the given
// UTF-16 index. This mimicks the Javascript substring behavior.
// UTF-16 index. This mimics the Javascript substring behavior.
let mut take_chars = |until: usize| {
if until <= i_utf16 {
return String::new();
@ -338,7 +342,7 @@ impl<'de> DeserializeAs<'de, TextComponents> for AttributedText {
let txt_link = txt_link.trim();
let txt_link = txt_link.replace("\u{a0}", " ");
static LINK_PREFIX: Lazy<Regex> = Lazy::new(|| Regex::new(r#"^(?:\/|•) *"#).unwrap());
static LINK_PREFIX: Lazy<Regex> = Lazy::new(|| Regex::new("^[/•] *").unwrap());
let txt_link = LINK_PREFIX.replace(&txt_link, "");
if !txt_before.is_empty() {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff