Compare commits

..

3 commits

Author SHA1 Message Date
fe5468313a fix: remove dead code 2022-09-27 21:43:12 +02:00
57e13d15a6 fix: allow concurrent cache access 2022-09-27 21:34:38 +02:00
9866006690 fix: add is_short to recommended video 2022-09-27 20:33:37 +02:00
15 changed files with 215 additions and 131 deletions

View file

@ -44,6 +44,10 @@ impl CacheStorage for FileStorage {
}
fn read(&self) -> Option<String> {
if !self.path.exists() {
return None;
}
match fs::read_to_string(&self.path) {
Ok(data) => Some(data),
Err(e) => {

View file

@ -17,12 +17,12 @@ use std::sync::Arc;
use anyhow::{anyhow, bail, Context, Result};
use chrono::{DateTime, Duration, Utc};
use fancy_regex::Regex;
use log::{error, warn};
use log::{debug, error, warn};
use once_cell::sync::Lazy;
use rand::Rng;
use reqwest::{header, Client, ClientBuilder, Request, RequestBuilder, Response};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use tokio::sync::Mutex;
use tokio::sync::RwLock;
use crate::{
cache::{CacheStorage, FileStorage},
@ -54,14 +54,6 @@ pub enum ClientType {
Ios,
}
const CLIENT_TYPES: [ClientType; 5] = [
ClientType::Desktop,
ClientType::DesktopMusic,
ClientType::TvHtml5Embed,
ClientType::Android,
ClientType::Ios,
];
impl ClientType {
fn is_web(&self) -> bool {
match self {
@ -177,9 +169,8 @@ struct RustyPipeRef {
storage: Option<Box<dyn CacheStorage + Sync + Send>>,
reporter: Option<Box<dyn Reporter + Sync + Send>>,
n_retries: u32,
user_agent: String,
consent_cookie: String,
cache: Mutex<CacheData>,
cache: CacheHolder,
default_opts: RustyPipeOpts,
}
@ -216,6 +207,13 @@ impl Default for RustyPipeOpts {
}
}
#[derive(Default, Debug)]
struct CacheHolder {
desktop_client: RwLock<CacheEntry<ClientData>>,
music_client: RwLock<CacheEntry<ClientData>>,
deobf: RwLock<CacheEntry<DeobfData>>,
}
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
struct CacheData {
desktop_client: CacheEntry<ClientData>,
@ -224,6 +222,7 @@ struct CacheData {
}
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
enum CacheEntry<T> {
#[default]
None,
@ -285,13 +284,13 @@ impl RustyPipeBuilder {
/// Returns a new, configured RustyPipe instance.
pub fn build(self) -> RustyPipe {
let http = ClientBuilder::new()
.user_agent(self.user_agent.to_owned())
.user_agent(self.user_agent)
.gzip(true)
.brotli(true)
.build()
.unwrap();
let cache = if let Some(storage) = &self.storage {
let cdata = if let Some(storage) = &self.storage {
if let Some(data) = storage.read() {
match serde_json::from_str::<CacheData>(&data) {
Ok(data) => data,
@ -313,14 +312,17 @@ impl RustyPipeBuilder {
storage: self.storage,
reporter: self.reporter,
n_retries: self.n_retries,
user_agent: self.user_agent,
consent_cookie: format!(
"{}={}{}",
CONSENT_COOKIE,
CONSENT_COOKIE_YES,
rand::thread_rng().gen_range(100..1000)
),
cache: Mutex::new(cache),
cache: CacheHolder {
desktop_client: RwLock::new(cdata.desktop_client),
music_client: RwLock::new(cdata.music_client),
deobf: RwLock::new(cdata.deobf),
},
default_opts: self.default_opts,
}),
}
@ -586,23 +588,28 @@ impl RustyPipe {
/// 3. from the YouTube website
/// 4. fall back to the hardcoded version
async fn get_desktop_client_version(&self) -> String {
let mut cache = self.inner.cache.lock().await;
// Write lock here to prevent concurrent tasks from fetching the same data
let mut desktop_client = self.inner.cache.desktop_client.write().await;
match cache.desktop_client.get() {
match desktop_client.get() {
Some(cdata) => cdata.version.to_owned(),
None => match self.extract_desktop_client_version().await {
None => {
debug!("getting desktop client version");
match self.extract_desktop_client_version().await {
Ok(version) => {
cache.desktop_client = CacheEntry::from(ClientData {
*desktop_client = CacheEntry::from(ClientData {
version: version.to_owned(),
});
self.store_cache(&cache);
drop(desktop_client);
self.store_cache().await;
version
}
Err(e) => {
warn!("{}, falling back to hardcoded version", e);
DESKTOP_CLIENT_VERSION.to_owned()
}
},
}
}
}
}
@ -613,45 +620,59 @@ impl RustyPipe {
/// 3. from the YouTube Music website
/// 4. fall back to the hardcoded version
async fn get_music_client_version(&self) -> String {
let mut cache = self.inner.cache.lock().await;
// Write lock here to prevent concurrent tasks from fetching the same data
let mut music_client = self.inner.cache.music_client.write().await;
match cache.music_client.get() {
match music_client.get() {
Some(cdata) => cdata.version.to_owned(),
None => match self.extract_music_client_version().await {
None => {
debug!("getting music client version");
match self.extract_music_client_version().await {
Ok(version) => {
cache.music_client = CacheEntry::from(ClientData {
*music_client = CacheEntry::from(ClientData {
version: version.to_owned(),
});
self.store_cache(&cache);
drop(music_client);
self.store_cache().await;
version
}
Err(e) => {
warn!("{}, falling back to hardcoded version", e);
DESKTOP_MUSIC_CLIENT_VERSION.to_owned()
}
},
}
}
}
}
/// Instantiate a new deobfuscator from either cached or extracted YouTube JavaScript code.
async fn get_deobf(&self) -> Result<Deobfuscator> {
let mut cache = self.inner.cache.lock().await;
// Write lock here to prevent concurrent tasks from fetching the same data
let mut deobf = self.inner.cache.deobf.write().await;
match cache.deobf.get() {
match deobf.get() {
Some(deobf) => Ok(Deobfuscator::from(deobf.to_owned())),
None => {
let deobf = Deobfuscator::new(self.inner.http.clone()).await?;
cache.deobf = CacheEntry::from(deobf.get_data());
self.store_cache(&cache);
Ok(deobf)
debug!("getting deobfuscator");
let new_deobf = Deobfuscator::new(self.inner.http.clone()).await?;
*deobf = CacheEntry::from(new_deobf.get_data());
drop(deobf);
self.store_cache().await;
Ok(new_deobf)
}
}
}
/// Write the given cache data to the storage backend.
fn store_cache(&self, cache: &CacheData) {
async fn store_cache(&self) {
if let Some(storage) = &self.inner.storage {
match serde_json::to_string(cache) {
let cdata = CacheData {
desktop_client: self.inner.cache.desktop_client.read().await.clone(),
music_client: self.inner.cache.music_client.read().await.clone(),
deobf: self.inner.cache.deobf.read().await.clone(),
};
match serde_json::to_string(&cdata) {
Ok(data) => storage.write(&data),
Err(e) => error!("Could not serialize cache. Error: {}", e),
}

View file

@ -102,7 +102,7 @@ pub struct GridVideoRenderer {
/// Contains `No views` if the view count is zero
#[serde_as(as = "Option<Text>")]
pub view_count_text: Option<String>,
/// Contains video length
/// Contains video length and Short/Live tag
#[serde_as(as = "VecSkipError<_>")]
pub thumbnail_overlays: Vec<TimeOverlay>,
/// Release date for upcoming videos
@ -138,6 +138,9 @@ pub struct CompactVideoRenderer {
#[serde(default)]
#[serde_as(as = "VecSkipError<_>")]
pub badges: Vec<VideoBadge>,
/// Contains Short/Live tag
#[serde_as(as = "VecSkipError<_>")]
pub thumbnail_overlays: Vec<TimeOverlay>,
}
/// Video displayed in a playlist

View file

@ -38,6 +38,7 @@ Paginator(
publish_date_txt: Some("11 months ago"),
view_count: Some(216222873),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Y8JFxS1HlDo",
@ -72,6 +73,7 @@ Paginator(
publish_date_txt: Some("5 months ago"),
view_count: Some(155106313),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "NoYKBAajoyo",
@ -106,6 +108,7 @@ Paginator(
publish_date_txt: Some("2 years ago"),
view_count: Some(265238677),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "yQUU29NwNF4",
@ -140,6 +143,7 @@ Paginator(
publish_date_txt: Some("1 year ago"),
view_count: Some(9989591),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "NU611fxGyPU",
@ -174,6 +178,7 @@ Paginator(
publish_date_txt: Some("1 year ago"),
view_count: Some(34588526),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "EaswWiwMVs8",
@ -208,6 +213,7 @@ Paginator(
publish_date_txt: Some("1 year ago"),
view_count: Some(242737870),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Ujb-gvqsoi0",
@ -242,6 +248,7 @@ Paginator(
publish_date_txt: Some("2 years ago"),
view_count: Some(126677200),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "gQlMMD8auMs",
@ -276,6 +283,7 @@ Paginator(
publish_date_txt: Some("1 month ago"),
view_count: Some(335903776),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "BL-aIpCLWnU",
@ -310,6 +318,7 @@ Paginator(
publish_date_txt: Some("1 year ago"),
view_count: Some(86125645),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Jh4QFaPmdss",
@ -344,6 +353,7 @@ Paginator(
publish_date_txt: Some("6 months ago"),
view_count: Some(170016610),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Fc-fa6cAe2c",
@ -378,6 +388,7 @@ Paginator(
publish_date_txt: Some("1 year ago"),
view_count: Some(123861096),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "dYRITmpFbJ4",
@ -412,6 +423,7 @@ Paginator(
publish_date_txt: Some("2 months ago"),
view_count: Some(101968219),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "mH0_XpSHkZo",
@ -446,6 +458,7 @@ Paginator(
publish_date_txt: Some("2 years ago"),
view_count: Some(322510403),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "uR8Mrt1IpXg",
@ -480,6 +493,7 @@ Paginator(
publish_date_txt: Some("2 years ago"),
view_count: Some(345491789),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "f5_wn8mexmM",
@ -514,6 +528,7 @@ Paginator(
publish_date_txt: Some("11 months ago"),
view_count: Some(314744776),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Ky5RT5oGg0w",
@ -548,6 +563,7 @@ Paginator(
publish_date_txt: Some("1 year ago"),
view_count: Some(18830758),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "gU2HqP4NxUs",
@ -582,6 +598,7 @@ Paginator(
publish_date_txt: Some("1 year ago"),
view_count: Some(282957370),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "KhTeiaCezwM",
@ -616,6 +633,7 @@ Paginator(
publish_date_txt: Some("2 years ago"),
view_count: Some(355203298),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "uxmP4b2a0uY",
@ -650,6 +668,7 @@ Paginator(
publish_date_txt: Some("2 years ago"),
view_count: Some(157400947),
is_live: false,
is_short: false,
),
],
ctoken: Some("CCgSExILWmVlcnJudUxpNUXAAQHIAQEYACrLDDJzNkw2d3l4Q1FxdUNRb0Q4ajRBQ2czQ1Bnb0l4LUM1djltdnBwZ3lDZ1B5UGdBS0RjSS1DZ2pxM0xYRXpkNk00VUVLQV9JLUFBb093ajRMQ1Bqc19JLUVsWTI5MWdFS0FfSS1BQW93MGo0dENpdFNSRU5NUVVzMWRYbGZhekkzZFhVdFJYUlJYMkkxVlRKeU1qWkVUa1JhVDIxT2NVZGtZMk5WU1VkUkNnUHlQZ0FLRHNJLUN3amZ2czJMbjRUcG5iUUJDZ1B5UGdBS0V0SS1Ed29OVWtSYVpXVnljbTUxVEdrMVJRb0Q4ajRBQ2c3Q1Bnc0kzYmJTdThMRy1wS1VBUW9EOGo0QUNnN0NQZ3NJX2JYd2lmQzJ0WlczQVFvRDhqNEFDZzdDUGdzSXpZckE3b0RHbzlMUUFRb0Q4ajRBQ2czQ1Bnb0l0N212dk9fUjVJUnZDZ1B5UGdBS0RjSS1DZ2lBcDdMWDBlYWxyaW9LQV9JLUFBb053ajRLQ0luanlmalZ0dUwxWHdvRDhqNEFDZzNDUGdvSXBKZmozYVR5X2MwZkNnUHlQZ0FLRGNJLUNnamJtNW1MbGRLQTV3Z0tBX0ktQUFvT3dqNExDTFRhOF9UNjE3U3UyQUVLQV9JLUFBb053ajRLQ05xMHBhdXZzS1BDZEFvRDhqNEFDZzdDUGdzSTVQR3E5WTIybWNXZ0FRb0Q4ajRBQ2c3Q1Bnc0lnNkdPN3JidzJjR0tBUW9EOGo0QUNnN0NQZ3NJenEtbWxQUy01SnJoQVFvRDhqNEFDZzdDUGdzSXZNbnBqSUtUeXBYX0FRb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0g5SS1IQW9hVWtSRlRWUnVTbmxSZDJsamFHMW5lbm96VGxKSlVIVmxWMUVLQV9JLUFBb053ajRLQ0xxb251clN1SkhoWXdvRDhqNEFDZzNDUGdvSXFzYU90Y0RBZ3NNMkNnUHlQZ0FLRHNJLUN3amU2TUNidlp2Rmdza0JDZ1B5UGdBS0RjSS1DZ2oxa1p2aTM3cXRwelVLQV9JLUFBb053ajRLQ00tdHNlQ2lpOHpWRVFvRDhqNEFDZzNDUGdvSXJjU3kxYV9RdjV0U0NnUHlQZ0FLRHNJLUN3akw4ZXI0ZzRiVGhJRUJDZ1B5UGdBS0RjSS1DZ2oxdEsyRXFjVG0zd1FLQV9JLUFBb053ajRLQ012dG1aX2Fnb1NQSmdvRDhqNEFDZzNDUGdvSTVfYUJ1THJ0NS1jVkNnUHlQZ0FLRGNJLUNnaWUyWlhTNW9tU3duVUtBX0ktQUFvT3dqNExDSnFqbnFUcDY4LS1tQUVLQV9JLUFBb093ajRMQ1BqS291cnRsY09QdVFFS0FfSS1BQW9Od2o0S0NPT00tOHo4a196UGZ3b0Q4ajRBQ2czQ1Bnb0l6SWFhMFBtcGxKY3JDZ1B5UGdBS0RzSS1Dd2pMaXJmd2pfWGhwb0VCQ2dQeVBnQUtEY0ktQ2dpRG52dUVtdEczaWlvS0FfSS1BQW9Pd2o0TENPYWw2LXliX09PTXV3RVNLQUFDQkFZSUNnd09FQklVRmhnYUhCNGdJaVFtS0Nvc0xqQXlORFk0T2p3LVFFSkVSa2hLVEU0YUJBZ0FFQUVhQkFnQ0VBTWFCQWdFRUFVYUJBZ0dFQWNhQkFnSUVBa2FCQWdLRUFzYUJBZ01FQTBhQkFnT0VBOGFCQWdRRUJFYUJBZ1NFQk1hQkFnVUVCVWFCQWdXRUJjYUJBZ1lFQmthQkFnYUVCc2FCQWdjRUIwYUJBZ2VFQjhhQkFnZ0VDRWFCQWdpRUNNYUJBZ2tFQ1VhQkFnbUVDY2FCQWdvRUNrYUJBZ3FFQ3NhQkFnc0VDMGFCQWd1RUM4YUJBZ3dFREVhQkFneUVETWFCQWcwRURVYUJBZzJFRGNhQkFnNEVEa2FCQWc2RURzYUJBZzhFRDBhQkFnLUVEOGFCQWhBRUVFYUJBaENFRU1hQkFoRUVFVWFCQWhHRUVjYUJBaElFRWthQkFoS0VFc2FCQWhNRUUwYUJBaE9FRThxS0FBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbUtDb3NMakF5TkRZNE9qdy1RRUpFUmtoS1RFNGoPd2F0Y2gtbmV4dC1mZWVkcgA%3D"),

View file

@ -84,6 +84,7 @@ VideoDetails(
publish_date_txt: Some("5 years ago"),
view_count: Some(2749364),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "4z3mu63yxII",
@ -118,6 +119,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(2266658),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "WhgRRpA3b2c",
@ -152,6 +154,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(260941),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "5qNHtdN07FM",
@ -186,6 +189,7 @@ VideoDetails(
publish_date_txt: Some("6 years ago"),
view_count: Some(1229987),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "7FeqF1-Z1g0",
@ -220,6 +224,7 @@ VideoDetails(
publish_date_txt: Some("7 years ago"),
view_count: Some(6095028),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "1vcP9UWrWBI",
@ -254,6 +259,7 @@ VideoDetails(
publish_date_txt: Some("3 years ago"),
view_count: Some(46470),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "jnp1veXQf7U",
@ -288,6 +294,7 @@ VideoDetails(
publish_date_txt: Some("3 years ago"),
view_count: Some(25136),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "77OlKRkaixo",
@ -322,6 +329,7 @@ VideoDetails(
publish_date_txt: Some("6 years ago"),
view_count: Some(44410),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "u29--YNGMyg",
@ -356,6 +364,7 @@ VideoDetails(
publish_date_txt: Some("11 years ago"),
view_count: Some(4184357),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "urt2_ACal9A",
@ -390,6 +399,7 @@ VideoDetails(
publish_date_txt: Some("5 years ago"),
view_count: Some(36111),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "PnBs9oH2Lx8",
@ -424,6 +434,7 @@ VideoDetails(
publish_date_txt: Some("3 years ago"),
view_count: Some(20322),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "yaCiVvBD-xc",
@ -458,6 +469,7 @@ VideoDetails(
publish_date_txt: Some("6 years ago"),
view_count: Some(482258),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "1PJnEwoFSXo",
@ -492,6 +504,7 @@ VideoDetails(
publish_date_txt: Some("12 days ago"),
view_count: Some(427756),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "iIDZ8pJKLZA",
@ -526,6 +539,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(26926),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "PhUQN6fd5O4",
@ -560,6 +574,7 @@ VideoDetails(
publish_date_txt: Some("3 years ago"),
view_count: Some(126093),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "bzr0c8qzQoc",
@ -594,6 +609,7 @@ VideoDetails(
publish_date_txt: Some("3 years ago"),
view_count: Some(13243),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "IeX1F-Jjq9E",
@ -628,6 +644,7 @@ VideoDetails(
publish_date_txt: Some("6 years ago"),
view_count: Some(80624),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "gsnL4m57MCM",
@ -662,6 +679,7 @@ VideoDetails(
publish_date_txt: Some("5 years ago"),
view_count: Some(29009),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "uEEHq6f8RsM",
@ -696,6 +714,7 @@ VideoDetails(
publish_date_txt: Some("3 months ago"),
view_count: Some(67538),
is_live: false,
is_short: false,
),
],
ctoken: Some("CBQSExILMHJiOUNmT3ZvamvAAQHIAQEYACqrBjJzNkw2d3paQkFyV0JBb0Q4ajRBQ2c3Q1Bnc0l4Ty1xb3AyV25NWDVBUW9EOGo0QUNnN0NQZ3NJZ29uTDc3clgtWjdqQVFvRDhqNEFDZzNDUGdvSTU5N2RnZW1vaEl4YUNnUHlQZ0FLSWRJLUhnb2NVa1JEVFZWRE1sUlljVjkwTURaSWFtUnlNbWRmUzJSTGNFaFJad29EOGo0QUNnN0NQZ3NJMDlqVG05MzIwZEhtQVFvRDhqNEFDZzdDUGdzSWphem5fUFhDNnF2c0FRb0Q4ajRBQ2c3Q1Bnc0lrckN0cmRULXdfdldBUW9EOGo0QUNnN0NQZ3NJdGZfQnJ0NjNuYjJPQVFvRDhqNEFDZzdDUGdzSW1wYnF5SkdsNmRudkFRb0Q4ajRBQ2c3Q1Bnc0lxT2FZbXBqZjM3ZTdBUW9EOGo0QUNnN0NQZ3NJMEtfcWhNRGYzZDI2QVFvRDhqNEFDZzNDUGdvSW45N1lqLWllbTdnLUNnUHlQZ0FLRHNJLUN3aVg5by1DNzhxbzBNa0JDZ1B5UGdBS0RzSS1Dd2o2a3BYUXNPS1otZFFCQ2dQeVBnQUtEc0ktQ3dpUTI2aVNxYjYyd0lnQkNnUHlQZ0FLRGNJLUNnanV5ZmUtLW9iRWlqNEtBX0ktQUFvTndqNEtDSWVGemRXOGpyMmRid29EOGo0QUNnM0NQZ29JMGRlT2tfNmlfZkloQ2dQeVBnQUtEc0ktQ3dpajRPenpwdnp5NUlJQkNnUHlQZ0FLRHNJLUN3akRqZkdfdXZYQm9MZ0JFaFFBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmhvRUNBQVFBUm9FQ0FJUUF4b0VDQVFRQlJvRUNBWVFCeG9FQ0FnUUNSb0VDQW9RQ3hvRUNBd1FEUm9FQ0E0UUR4b0VDQkFRRVJvRUNCSVFFeG9FQ0JRUUZSb0VDQllRRnhvRUNCZ1FHUm9FQ0JvUUd4b0VDQndRSFJvRUNCNFFIeG9FQ0NBUUlSb0VDQ0lRSXhvRUNDUVFKUm9FQ0NZUUp5b1VBQUlFQmdnS0RBNFFFaFFXR0JvY0hpQWlKQ1lqD3dhdGNoLW5leHQtZmVlZA%3D%3D"),

View file

@ -520,6 +520,7 @@ VideoDetails(
publish_date_txt: Some("2 days ago"),
view_count: Some(1862544),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "CY3OQh-7wIk",
@ -554,6 +555,7 @@ VideoDetails(
publish_date_txt: Some("Streamed 8 days ago"),
view_count: Some(946996),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "LQ95XJAwaoc",
@ -588,6 +590,7 @@ VideoDetails(
publish_date_txt: Some("1 day ago"),
view_count: Some(349251),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "mhMQeJ5Qmp0",
@ -622,6 +625,7 @@ VideoDetails(
publish_date_txt: Some("1 day ago"),
view_count: Some(375458),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "1ctXiZsN6ac",
@ -656,6 +660,7 @@ VideoDetails(
publish_date_txt: Some("Streamed 6 days ago"),
view_count: Some(734463),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "CMR9z9Xr8GM",
@ -690,6 +695,7 @@ VideoDetails(
publish_date_txt: Some("11 months ago"),
view_count: Some(2773698),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "fT2KhJ8W-Kg",
@ -724,6 +730,7 @@ VideoDetails(
publish_date_txt: Some("8 hours ago"),
view_count: Some(219605),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "12Hcbx33Rb4",
@ -758,6 +765,7 @@ VideoDetails(
publish_date_txt: Some("4 hours ago"),
view_count: Some(145345),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "QW1SsqmaIuE",
@ -792,6 +800,7 @@ VideoDetails(
publish_date_txt: Some("6 hours ago"),
view_count: Some(50033),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "JAcSNL1T3OA",
@ -826,6 +835,7 @@ VideoDetails(
publish_date_txt: Some("1 month ago"),
view_count: Some(1163652),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "ZVtOss1U7_s",
@ -860,6 +870,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(3266169),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "2kJDTzFtUr4",
@ -894,6 +905,7 @@ VideoDetails(
publish_date_txt: Some("2 weeks ago"),
view_count: Some(678935),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "0rCbfsuKdYw",
@ -928,6 +940,7 @@ VideoDetails(
publish_date_txt: Some("3 weeks ago"),
view_count: Some(7569956),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "sbdU7AkH6QM",
@ -962,6 +975,7 @@ VideoDetails(
publish_date_txt: Some("5 months ago"),
view_count: Some(3374461),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "zcchDu7KoYs",
@ -996,6 +1010,7 @@ VideoDetails(
publish_date_txt: Some("5 days ago"),
view_count: Some(1322625),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "pd6DsSjqhFE",
@ -1030,6 +1045,7 @@ VideoDetails(
publish_date_txt: Some("3 weeks ago"),
view_count: Some(255945),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "2K5Gqp1cEcM",
@ -1064,6 +1080,7 @@ VideoDetails(
publish_date_txt: Some("2 weeks ago"),
view_count: Some(2930532),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "t03rmc-prJo",
@ -1098,6 +1115,7 @@ VideoDetails(
publish_date_txt: Some("12 days ago"),
view_count: Some(2743664),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "QTH9m6MDIfc",
@ -1132,6 +1150,7 @@ VideoDetails(
publish_date_txt: Some("3 weeks ago"),
view_count: Some(7958495),
is_live: false,
is_short: false,
),
],
ctoken: Some("CBQSExILbkZEQnhCVWZFNzTAAQHIAQEYACqkBjJzNkw2d3pVQkFyUkJBb0Q4ajRBQ2d6Q1Bna0lwNGppcEwyNjJuTUtBX0ktQUFvTndqNEtDSW1CN18yaHlQUEdDUW9EOGo0QUNnM0NQZ29JaDlYQmdjbXIzb2N0Q2dQeVBnQUtEc0ktQ3dpZHRjTHlpWV9FaVpvQkNnUHlQZ0FLRHNJLUN3aW4wN2ZZbWZIVjVkVUJDZ1B5UGdBS0RjSS1DZ2pqNEstdl9ibWY0Z2dLQV9JLUFBb053ajRLQ0tqeDJfakowT0tlZlFvRDhqNEFDZzdDUGdzSXZvdmQ3X0dOOTdEWEFRb0Q4ajRBQ2czQ1Bnb0k0Y1hvektyVzFMWkJDZ1B5UGdBS0RjSS1DZ2pndWNfcXk4YkVneVFLQV9JLUFBb053ajRLQ1B2ZjAtcXMxdE90WlFvRDhqNEFDaUhTUGg0S0hGSkVRMDFWUTFoMWNWTkNiRWhCUlRaWWR5MTVaVXBCTUZSMWJuY0tBX0ktQUFvT3dqNExDTDZsdFl2ejZaQ2gyZ0VLQV9JLUFBb093ajRMQ0l6cnFkenM3NmJZMGdFS0FfSS1BQW9Pd2o0TENJUFNuOGpBbmRYYnNRRUtBX0ktQUFvT3dqNExDSXZEcXZidW9jamp6UUVLQV9JLUFBb093ajRMQ05HSXFzZVM5cUR2cFFFS0FfSS1BQW9Pd2o0TENNT2o4T3FwMVpIWDJBRUtBX0ktQUFvT3dqNExDSnJacHYyYzhfcW10d0VLQV9JLUFBb053ajRLQ1BmRGpKaTZzXy1ZUVJJVUFBSUVCZ2dLREE0UUVoUVdHQm9jSGlBaUpDWWFCQWdBRUFFYUJBZ0NFQU1hQkFnRUVBVWFCQWdHRUFjYUJBZ0lFQWthQkFnS0VBc2FCQWdNRUEwYUJBZ09FQThhQkFnUUVCRWFCQWdTRUJNYUJBZ1VFQlVhQkFnV0VCY2FCQWdZRUJrYUJBZ2FFQnNhQkFnY0VCMGFCQWdlRUI4YUJBZ2dFQ0VhQkFnaUVDTWFCQWdrRUNVYUJBZ21FQ2NxRkFBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbWoPd2F0Y2gtbmV4dC1mZWVk"),

View file

@ -104,6 +104,7 @@ VideoDetails(
publish_date_txt: Some("7 years ago"),
view_count: Some(90280310),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "ddZu_1Z3BAc",
@ -138,6 +139,7 @@ VideoDetails(
publish_date_txt: None,
view_count: Some(80),
is_live: true,
is_short: false,
),
RecommendedVideo(
id: "oDXBMjg9HKU",
@ -172,6 +174,7 @@ VideoDetails(
publish_date_txt: Some("10 hours ago"),
view_count: Some(13),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "aU0vNvVHXa8",
@ -206,6 +209,7 @@ VideoDetails(
publish_date_txt: None,
view_count: Some(23),
is_live: true,
is_short: false,
),
RecommendedVideo(
id: "6scCF_8YN70",
@ -240,6 +244,7 @@ VideoDetails(
publish_date_txt: Some("11 years ago"),
view_count: Some(118635723),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "n4IhCSMkADc",
@ -274,6 +279,7 @@ VideoDetails(
publish_date_txt: Some("7 years ago"),
view_count: Some(11226061),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "bgbH4FAmAA0",
@ -308,6 +314,7 @@ VideoDetails(
publish_date_txt: None,
view_count: Some(108),
is_live: true,
is_short: false,
),
RecommendedVideo(
id: "uD4izuDMUQA",
@ -342,6 +349,7 @@ VideoDetails(
publish_date_txt: Some("3 years ago"),
view_count: Some(85240979),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Z6DpPQ8QdLg",
@ -376,6 +384,7 @@ VideoDetails(
publish_date_txt: Some("4 years ago"),
view_count: Some(5405668),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "1hNF3Wuw0LI",
@ -410,6 +419,7 @@ VideoDetails(
publish_date_txt: None,
view_count: Some(10),
is_live: true,
is_short: false,
),
RecommendedVideo(
id: "ZEyAs3NWH4A",
@ -444,6 +454,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(61247221),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "NF4LQaWJRDg",
@ -478,6 +489,7 @@ VideoDetails(
publish_date_txt: Some("15 years ago"),
view_count: Some(36276575),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "qhOe_PxiNo8",
@ -512,6 +524,7 @@ VideoDetails(
publish_date_txt: Some("5 years ago"),
view_count: Some(12004917),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "zf3bDpdhUNc",
@ -546,6 +559,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(22901662),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "mJxsj51d-Pk",
@ -580,6 +594,7 @@ VideoDetails(
publish_date_txt: Some("4 years ago"),
view_count: Some(42814880),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "fr_hXLDLc38",
@ -614,6 +629,7 @@ VideoDetails(
publish_date_txt: Some("4 years ago"),
view_count: Some(9592134),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Jh-qzwdiAGY",
@ -648,6 +664,7 @@ VideoDetails(
publish_date_txt: Some("5 years ago"),
view_count: Some(4463605),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "EPyl1LgNtoQ",
@ -682,6 +699,7 @@ VideoDetails(
publish_date_txt: Some("10 years ago"),
view_count: Some(14094460),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "7KXGZAEWzn0",
@ -716,6 +734,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(9901163),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "KTUa9rG08go",
@ -750,6 +769,7 @@ VideoDetails(
publish_date_txt: None,
view_count: Some(15),
is_live: true,
is_short: false,
),
],
ctoken: Some("CBQSExILODZZTEZPb2c0R03AAQHIAQEYACrgBzJzNkw2d3poQlFyZUJRb0Q4ajRBQ2czQ1Bnb0k3b3VlbjdUTV9yRklDZ1B5UGdBS0RjSS1DZ2lIaU55ejlkLWI2M1VLQV9JLUFBb093ajRMQ0tXNTlNR2pwdkNhb0FFS0FfSS1BQW9Od2o0S0NLLTduYXJ2NXN1bWFRb0Q4ajRBQ2c3Q1Bnc0l2ZV9nLVBfQ3dPUHFBUW9EOGo0QUNnN0NQZ3NJdDRDUW1aS2hpTUdmQVFvRDhqNEFDZzNDUGdvSWpZQ1lnWVg4c1lOdUNnUHlQZ0FLRHNJLUN3aUFvckdHN3RtSW43Z0JDZ1B5UGdBS0RjSS1DZ2k0NmNINDBLZTYwR2NLQV9JLUFBb093ajRMQ0xLaHc5M1d1OUdKMWdFS0FfSS1BQW9Od2o0S0NJQ18ySnEzbHFDbVpBb0Q4ajRBQ2czQ1Bnb0l1SWlsckpyb2dxODBDZ1B5UGdBS0RzSS1Dd2lQN1lqano5X25pYW9CQ2dQeVBnQUtEc0ktQ3dqWG9ZVzc2ZUgyX3MwQkNnUHlQZ0FLRHNJLUN3ajU4ZmZxLVpHYnpwZ0JDZ1B5UGdBS0RjSS1DZ2pfNXEyR3k2djQzMzRLQV9JLUFBb053ajRLQ09hQWlMdncyZXFQSmdvRDhqNEFDZzNDUGdvSWhPMjJ3TXU2cWY0UUNnUHlQZ0FLRHNJLUN3ajluTnVJd016eDB1d0JDZ1B5UGdBS0RjSS1DZ2lLNU5PTjY5N0dtaWtLQV9JLUFBb2FtajhYQ2hWUGZEazRNek0xTXpjMU5ERTJOVGMzT0RnMk1UY0tHNW9fR0FvV1Qzd3hNekF5TXpnek9UY3hPREk0TXpVMU9EUTFNd29ibWo4WUNoWlBmREUxT0RVek5Ua3dPRGczTURVeE1qVTBOemcwQ2dQeVBnQUtBX0ktQUJJWEFBSUVCZ2dLREE0UUVoUVdHQm9jSGlBaUpDWW9MQzBhQkFnQUVBRWFCQWdDRUFNYUJBZ0VFQVVhQkFnR0VBY2FCQWdJRUFrYUJBZ0tFQXNhQkFnTUVBMGFCQWdPRUE4YUJBZ1FFQkVhQkFnU0VCTWFCQWdVRUJVYUJBZ1dFQmNhQkFnWUVCa2FCQWdhRUJzYUJBZ2NFQjBhQkFnZUVCOGFCQWdnRUNFYUJBZ2lFQ01hQkFna0VDVWFCQWdtRUNjYUJBZ29FQ2thQkFnb0VDb2FCQWdvRUNzYUJBZ3NFQ2thQkFnc0VDb2FCQWdzRUNzYUJBZ3RFQ2thQkFndEVDb2FCQWd0RUNzcUZ3QUNCQVlJQ2d3T0VCSVVGaGdhSEI0Z0lpUW1LQ3d0ag93YXRjaC1uZXh0LWZlZWQ%3D"),

View file

@ -74,6 +74,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(30966),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "BcqM8Qshx7U",
@ -108,6 +109,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(15269),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "IUFUIgZOcow",
@ -142,6 +144,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(29035),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "UtP9J88Jzg0",
@ -176,6 +179,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(46009),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "sg6j-zfUF_A",
@ -210,6 +214,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(7405),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "u2XCC1rKxV0",
@ -244,6 +249,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(19383),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "oOBBBl3fywU",
@ -278,6 +284,7 @@ VideoDetails(
publish_date_txt: Some("4 years ago"),
view_count: Some(132472),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "pI0Rancanz0",
@ -312,6 +319,7 @@ VideoDetails(
publish_date_txt: Some("4 years ago"),
view_count: Some(367684),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "DsviLYh1CB0",
@ -346,6 +354,7 @@ VideoDetails(
publish_date_txt: Some("4 years ago"),
view_count: Some(195958),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Ctpe9kafn78",
@ -380,6 +389,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(37702),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "y252630WbIk",
@ -414,6 +424,7 @@ VideoDetails(
publish_date_txt: Some("8 years ago"),
view_count: Some(103494),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "YgUZtELr_jw",
@ -448,6 +459,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(19342),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "ABKSs0aU4C0",
@ -482,6 +494,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(9392),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "O0I3rJsHikA",
@ -516,6 +529,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(22994),
is_live: false,
is_short: false,
),
],
ctoken: Some("CBQSExILWHVNMm9uTUd2VEnAAQHIAQEYACqsBzJzNkw2d3k2QlFxM0JRb0Q4ajRBQ2czQ1Bnb0lvSmVsMDhiajMtcGVDZ1B5UGdBS0o5SS1KQW9pVUV4aGFGSktXRWczV0ZCSWJWZE9TemMwVm5wM1NVWXljWFZYY1dSR1NWZDJjZ29EOGo0QUNpZlNQaVFLSWxCTU5pMTRZV3hIWVZaRmRYQjJlVGxHUVVoZlJYZ3pTRlYxWHpGaFVrRXlialFLQV9JLUFBb1MwajRQQ2cxU1JGaDFUVEp2YmsxSGRsUkpDZ1B5UGdBS0RjSS1DZ2kxajRmWmtKNmo1UVVLQV9JLUFBb053ajRLQ0l6bHViS2doTldnSVFvRDhqNEFDZzNDUGdvSWpaeW4tUHlrXy1sU0NnUHlQZ0FLRHNJLUN3andyOUMtc18tb2g3SUJDZ1B5UGdBS0o5SS1KQW9pVUV3d1dqSlNSVFZsY1dGWlRWRXhiRnBaZGtWalRrOW1UVmx3VFVvelkyTktRd29EOGo0QUNnN0NQZ3NJM1lxcjFyWEI4TEs3QVFvRDhqNEFDZzdDUGdzSWhaYl83dVdna1BDZ0FRb0Q4ajRBQ2c3Q1Bnc0l2YjdxdUtldHhNYWtBUW9EOGo0QUNnM0NQZ29JblpEVXc5akYtT1VPQ2dQeVBnQUtIOUktSEFvYVVrUkZUV1E0VUZwSmRqbERVSE4yZGtWRVltOWZjRlZFTkhjS0FfSS1BQW9Od2o0S0NMLV9fclRrM3BmdENnb0Q4ajRBQ2c3Q1Bnc0lpZG5aNkxmZG5iZkxBUW9EOGo0QUNnM0NQZ29JdlB5dmw4UzJ4b0ppQ2dQeVBnQUtETUktQ1FpdHdOTzB0TmFrQ1FvRDhqNEFDaWZTUGlRS0lsQk1NazR6TjFoVWQxaG5jRlZpYWxSemNXVjFNbEZFZVRCTGIyRnpkMDlZTVZvS0FfSS1BQW9Od2o0S0NNQ1VudGpKOVkyaE94SVVBQUlFQmdnS0RBNFFFaFFXR0JvY0hpQWlKQ1lhQkFnQUVBRWFCQWdDRUFNYUJBZ0VFQVVhQkFnR0VBY2FCQWdJRUFrYUJBZ0tFQXNhQkFnTUVBMGFCQWdPRUE4YUJBZ1FFQkVhQkFnU0VCTWFCQWdVRUJVYUJBZ1dFQmNhQkFnWUVCa2FCQWdhRUJzYUJBZ2NFQjBhQkFnZUVCOGFCQWdnRUNFYUJBZ2lFQ01hQkFna0VDVWFCQWdtRUNjcUZBQUNCQVlJQ2d3T0VCSVVGaGdhSEI0Z0lpUW1qD3dhdGNoLW5leHQtZmVlZA%3D%3D"),

View file

@ -135,6 +135,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(245412217),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "WPdWvnAAurg",
@ -169,6 +170,7 @@ VideoDetails(
publish_date_txt: Some("11 months ago"),
view_count: Some(215292736),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "NoYKBAajoyo",
@ -203,6 +205,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(264670229),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "KhTeiaCezwM",
@ -237,6 +240,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(354281319),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Jh4QFaPmdss",
@ -271,6 +275,7 @@ VideoDetails(
publish_date_txt: Some("6 months ago"),
view_count: Some(167648677),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "CM4CkVFmTds",
@ -305,6 +310,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(455437333),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "uR8Mrt1IpXg",
@ -339,6 +345,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(344730852),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "QslJYDX3o8s",
@ -373,6 +380,7 @@ VideoDetails(
publish_date_txt: Some("6 years ago"),
view_count: Some(238321583),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "EaswWiwMVs8",
@ -407,6 +415,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(240527435),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "pNfTK39k55U",
@ -441,6 +450,7 @@ VideoDetails(
publish_date_txt: Some("3 years ago"),
view_count: Some(306144594),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "dYRITmpFbJ4",
@ -475,6 +485,7 @@ VideoDetails(
publish_date_txt: Some("2 months ago"),
view_count: Some(100128895),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "ioNng23DkIM",
@ -509,6 +520,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(1146631077),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Ujb-gvqsoi0",
@ -543,6 +555,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(126406160),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "bwmSjveL3Lc",
@ -577,6 +590,7 @@ VideoDetails(
publish_date_txt: Some("6 years ago"),
view_count: Some(1476093662),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "6uJf2IT2Zh8",
@ -611,6 +625,7 @@ VideoDetails(
publish_date_txt: Some("4 years ago"),
view_count: Some(228968545),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Y8JFxS1HlDo",
@ -645,6 +660,7 @@ VideoDetails(
publish_date_txt: Some("5 months ago"),
view_count: Some(152292435),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "2FzSv66c7TQ",
@ -679,6 +695,7 @@ VideoDetails(
publish_date_txt: Some("2 months ago"),
view_count: Some(504562),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "NU611fxGyPU",
@ -713,6 +730,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(34445393),
is_live: false,
is_short: false,
),
],
ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACq7BjJzNkw2d3psQkFyaUJBb0Q4ajRBQ2c3Q1Bnc0l6cS1tbFBTLTVKcmhBUW9EOGo0QUNoTFNQZzhLRFZKRVdtVmxjbkp1ZFV4cE5VVUtBX0ktQUFvdzBqNHRDaXRTUkVOTVFVczFkWGxmYXpJM2RYVXRSWFJSWDJJMVZUSnlNalpFVGtSYVQyMU9jVWRrWTJOVlNVZFJDZ1B5UGdBS0RjSS1DZ2k0OVlLQTU5ZlYtMWdLQV9JLUFBb053ajRLQ0tyR2pyWEF3SUxETmdvRDhqNEFDZzNDUGdvSWc1NzdoSnJSdDRvcUNnUHlQZ0FLRGNJLUNnakw3Wm1mMm9LRWp5WUtBX0ktQUFvTndqNEtDTnVibVl1VjBvRG5DQW9EOGo0QUNnN0NQZ3NJLU1xaTZ1MlZ3NC01QVFvRDhqNEFDZzNDUGdvSXk4ZmVyNE9zMHVSQ0NnUHlQZ0FLRGNJLUNnalByYkhnb292TTFSRUtBX0ktQUFvT3dqNExDSlhQa191MzVmVHJwQUVLQV9JLUFBb053ajRLQ0o3WmxkTG1pWkxDZFFvRDhqNEFDZzdDUGdzSWc2R083cmJ3MmNHS0FRb0Q4ajRBQ2czQ1Bnb0lyY1N5MWFfUXY1dFNDZ1B5UGdBS0RjSS1DZ2kzdWEtODc5SGtoRzhLQV9JLUFBb093ajRMQ0pfTTJhZUktNWZ4NmdFS0FfSS1BQW9Od2o0S0NMcW9udXJTdUpIaFl3b0Q4ajRBQ2c3Q1Bnc0l0TnJ6OVByWHRLN1lBUW9EOGo0QUNnM0NQZ29JOVpHYjR0LTZyYWMxRWhRQUFnUUdDQW9NRGhBU0ZCWVlHaHdlSUNJa0pob0VDQUFRQVJvRUNBSVFBeG9FQ0FRUUJSb0VDQVlRQnhvRUNBZ1FDUm9FQ0FvUUN4b0VDQXdRRFJvRUNBNFFEeG9FQ0JBUUVSb0VDQklRRXhvRUNCUVFGUm9FQ0JZUUZ4b0VDQmdRR1JvRUNCb1FHeG9FQ0J3UUhSb0VDQjRRSHhvRUNDQVFJUm9FQ0NJUUl4b0VDQ1FRSlJvRUNDWVFKeW9VQUFJRUJnZ0tEQTRRRWhRV0dCb2NIaUFpSkNZag93YXRjaC1uZXh0LWZlZWQ%3D"),

View file

@ -135,6 +135,7 @@ VideoDetails(
publish_date_txt: Some("5 days ago"),
view_count: Some(996),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "lCXqNCd0m10",
@ -169,6 +170,7 @@ VideoDetails(
publish_date_txt: Some("7 months ago"),
view_count: Some(7684395),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "tDukIfFzX18",
@ -203,6 +205,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(260984648),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "e-ORhEE9VVg",
@ -237,6 +240,7 @@ VideoDetails(
publish_date_txt: Some("7 years ago"),
view_count: Some(3035220118),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "qfVuRQX0ydQ",
@ -271,6 +275,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(138451832),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "tyrVtwE8Gv0",
@ -305,6 +310,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(255458628),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "X-uJtV8ScYk",
@ -339,6 +345,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(274719671),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "MjCZfZfucEc",
@ -373,6 +380,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(203129706),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "2FzSv66c7TQ",
@ -407,6 +415,7 @@ VideoDetails(
publish_date_txt: Some("2 months ago"),
view_count: Some(531757),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "CevxZvSJLk8",
@ -441,6 +450,7 @@ VideoDetails(
publish_date_txt: Some("9 years ago"),
view_count: Some(3656394146),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "bwmSjveL3Lc",
@ -475,6 +485,7 @@ VideoDetails(
publish_date_txt: Some("6 years ago"),
view_count: Some(1479871637),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "CM4CkVFmTds",
@ -509,6 +520,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(456763969),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "ioNng23DkIM",
@ -543,6 +555,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(1149727787),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "BL-aIpCLWnU",
@ -577,6 +590,7 @@ VideoDetails(
publish_date_txt: Some("1 year ago"),
view_count: Some(86080254),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Jh4QFaPmdss",
@ -611,6 +625,7 @@ VideoDetails(
publish_date_txt: Some("6 months ago"),
view_count: Some(169858302),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "WPdWvnAAurg",
@ -645,6 +660,7 @@ VideoDetails(
publish_date_txt: Some("11 months ago"),
view_count: Some(216164610),
is_live: false,
is_short: false,
),
RecommendedVideo(
id: "Z7yNvMzz2zg",
@ -679,6 +695,7 @@ VideoDetails(
publish_date_txt: Some("2 years ago"),
view_count: Some(135093083),
is_live: false,
is_short: false,
),
],
ctoken: Some("CBQSExILWmVlcnJudUxpNUXAAQHIAQEYACreBjJzNkw2d3pfQkFyOEJBb0Q4ajRBQ2czQ1Bnb0l5dFdIekt5Tm1ZMXBDZ1B5UGdBS0o5SS1KQW9pVUV4eU1UUldiR05sYkRKVE16UlpSMmw1WlZkRU1rOW9jbU4wVGt4Q1psVk9PUW9EOGo0QUNoTFNQZzhLRFZKRVdtVmxjbkp1ZFV4cE5VVUtBX0ktQUFvT3dqNExDTjIyMHJ2Q3h2cVNsQUVLQV9JLUFBb3cwajR0Q2l0U1JFTk1RVXMxZFhsZmF6STNkWFV0UlhSUlgySTFWVEp5TWpaRVRrUmFUMjFPY1Vka1kyTlZTVWRSQ2dQeVBnQUtEc0ktQ3dqZnZzMkxuNFRwbmJRQkNnUHlQZ0FLRGNJLUNnallxdldKeExEazhYc0tBX0ktQUFvT3dqNExDTlNUMDZfUXlOdjZxUUVLQV9JLUFBb093ajRMQ1AyMThJbnd0cldWdHdFS0FfSS1BQW9Od2o0S0NJbmp5ZmpWdHVMMVh3b0Q4ajRBQ2czQ1Bnb0l4LUM1djltdnBwZ3lDZ1B5UGdBS0RzSS1Dd2kwMnZQMC10ZTBydGdCQ2dQeVBnQUtEY0ktQ2dqUDNLU2s3Nno4OVFrS0FfSS1BQW9Od2o0S0NMZTVyN3p2MGVTRWJ3b0Q4ajRBQ2czQ1Bnb0kyNXVaaTVYU2dPY0lDZ1B5UGdBS0RzSS1Dd2lEb1k3dXR2RFp3WW9CQ2dQeVBnQUtEY0ktQ2dqMXRLMkVxY1RtM3dRS0FfSS1BQW9Od2o0S0NNdnRtWl9hZ29TUEpnb0Q4ajRBQ2czQ1Bnb0l1UFdDZ09mWDFmdFlDZ1B5UGdBS0RjSS1DZ2k0dHNfbnpMZWozbWNTRkFBQ0JBWUlDZ3dPRUJJVUZoZ2FIQjRnSWlRbUdnUUlBQkFCR2dRSUFoQURHZ1FJQkJBRkdnUUlCaEFIR2dRSUNCQUpHZ1FJQ2hBTEdnUUlEQkFOR2dRSURoQVBHZ1FJRUJBUkdnUUlFaEFUR2dRSUZCQVZHZ1FJRmhBWEdnUUlHQkFaR2dRSUdoQWJHZ1FJSEJBZEdnUUlIaEFmR2dRSUlCQWhHZ1FJSWhBakdnUUlKQkFsR2dRSUpoQW5LaFFBQWdRR0NBb01EaEFTRkJZWUdod2VJQ0lrSmdqD3dhdGNoLW5leHQtZmVlZA%3D%3D"),

View file

@ -14,7 +14,7 @@ use crate::{
};
use super::{
response::{self, IconType, IsLive},
response::{self, IconType, IsLive, IsShort},
ClientType, MapResponse, QContinuation, RustyPipeQuery, YTContext,
};
@ -438,6 +438,7 @@ fn map_recommendations(
.view_count_text
.map(|txt| util::parse_numeric(&txt).unwrap_or_default()),
is_live: video.badges.is_live(),
is_short: video.thumbnail_overlays.is_short(),
}),
Err(e) => {
warnings.push(e.to_string());

View file

@ -193,58 +193,6 @@ fn get_nsig_fn_name(player_js: &str) -> Result<String> {
Ok(name.to_owned())
}
fn match_to_closing_parenthesis(string: &str, start: &str) -> Option<String> {
let mut start_index = string.find(start)?;
start_index += start.len();
let mut visited_par = false;
let mut nesting = 0;
let mut last_escaped = false;
let mut quote = ' ';
let mut res = String::new();
for c in string[start_index..].chars() {
res.push(c);
let mut this_escaped = false;
match c {
'{' => {
if quote == ' ' {
visited_par = true;
nesting += 1;
}
}
'}' => {
if quote == ' ' {
nesting -= 1;
}
}
'\\' => {
if !last_escaped {
this_escaped = true;
}
}
'\'' | '"' | '`' => {
if !last_escaped {
if quote == ' ' {
quote = c;
} else if quote == c {
quote = ' ';
}
}
}
_ => {}
};
if visited_par && nesting == 0 {
break;
}
last_escaped = this_escaped;
}
Some(res)
}
fn extract_js_fn(js: &str, name: &str) -> Result<String> {
let scan = ress::Scanner::new(js);
let mut state = 0;
@ -416,21 +364,6 @@ c[36](c[8],c[32]),c[20](c[25],c[10]),c[2](c[22],c[8]),c[32](c[20],c[16]),c[32](c
assert_eq!(name, "Vo");
}
#[test]
fn t_match_to_closing_parenthesis() {
let res =
match_to_closing_parenthesis("Kx Hello { Thx { Bye } } Wut {Tst {}}", "Hello").unwrap();
assert_eq!(res, " { Thx { Bye } }")
}
#[test]
fn t_match_to_closing_parenthesis2() {
let res =
match_to_closing_parenthesis("function(d){return \",}\\\"/\"}abcdef", "function(d)")
.unwrap();
assert_eq!(res, "{return \",}\\\"/\"}")
}
#[test]
fn t_extract_js_fn() {
let base_js = "Wka = function(d){let x=10/2;return /,,[/,913,/](,)}/}let a = 42;";

View file

@ -534,6 +534,8 @@ pub struct RecommendedVideo {
pub view_count: Option<u64>,
/// Is the video an active livestream?
pub is_live: bool,
/// Is the video a YouTube Short video (vertical and <60s)?
pub is_short: bool,
}
/// Channel information attached to a video or comment

View file

@ -1,3 +1,4 @@
/// Channel video sort order
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ChannelOrder {

View file

@ -37,13 +37,6 @@ impl FilterResult {
}
fn soft(val: bool) -> Self {
match val {
true => Self::Match,
false => Self::Allow,
}
}
fn soft_lowest(val: bool) -> Self {
match val {
true => Self::Match,
false => Self::AllowLowest,
@ -77,7 +70,7 @@ impl Filter {
fn apply_audio_max_bitrate(&self, stream: &AudioStream) -> FilterResult {
match self.audio_max_bitrate {
Some(max_bitrate) => FilterResult::soft_lowest(stream.average_bitrate <= max_bitrate),
Some(max_bitrate) => FilterResult::soft(stream.average_bitrate <= max_bitrate),
None => FilterResult::Match,
}
}
@ -147,7 +140,7 @@ impl Filter {
fn apply_video_max_res(&self, stream: &VideoStream) -> FilterResult {
match self.video_max_res {
Some(max_res) => FilterResult::soft_lowest(stream.height.min(stream.width) <= max_res),
Some(max_res) => FilterResult::soft(stream.height.min(stream.width) <= max_res),
None => FilterResult::Match,
}
}
@ -163,7 +156,7 @@ impl Filter {
fn apply_video_max_fps(&self, stream: &VideoStream) -> FilterResult {
match self.video_max_fps {
Some(max_fps) => FilterResult::soft_lowest(stream.fps <= max_fps),
Some(max_fps) => FilterResult::soft(stream.fps <= max_fps),
None => FilterResult::Match,
}
}