feat: add channel playlists
- add tests for channel videos - small model refactor (rename Channel to ChannelTag)
This commit is contained in:
parent
45707c4d01
commit
6f1a1c4440
30 changed files with 16831 additions and 241 deletions
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
|
|
@ -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, I’m 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 it’s because you’re 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"),
|
||||
),
|
||||
)
|
||||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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 NingNing’s high note. Baby you’re 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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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: [
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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
11
src/model/param.rs
Normal 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,
|
||||
}
|
||||
|
|
@ -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.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
2732
testfiles/channel/channel_info.json
Normal file
2732
testfiles/channel/channel_info.json
Normal file
File diff suppressed because it is too large
Load diff
8584
testfiles/channel/channel_playlists.json
Normal file
8584
testfiles/channel/channel_playlists.json
Normal file
File diff suppressed because it is too large
Load diff
1820
testfiles/channel/channel_videos_empty.json
Normal file
1820
testfiles/channel/channel_videos_empty.json
Normal file
File diff suppressed because it is too large
Load diff
Reference in a new issue