feat: add search filter, refactor params
This commit is contained in:
parent
44e14a4ae0
commit
25de7d678a
24 changed files with 374 additions and 72 deletions
|
|
@ -1,855 +0,0 @@
|
|||
// This file is automatically generated. DO NOT EDIT.
|
||||
|
||||
//! Languages and countries
|
||||
|
||||
use std::{fmt::Display, str::FromStr};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Available languages
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Language {
|
||||
/// Afrikaans
|
||||
Af,
|
||||
/// አማርኛ
|
||||
Am,
|
||||
/// العربية
|
||||
Ar,
|
||||
/// অসমীয়া
|
||||
As,
|
||||
/// Azərbaycan
|
||||
Az,
|
||||
/// Беларуская
|
||||
Be,
|
||||
/// Български
|
||||
Bg,
|
||||
/// বাংলা
|
||||
Bn,
|
||||
/// Bosanski
|
||||
Bs,
|
||||
/// Català
|
||||
Ca,
|
||||
/// Čeština
|
||||
Cs,
|
||||
/// Dansk
|
||||
Da,
|
||||
/// Deutsch
|
||||
De,
|
||||
/// Ελληνικά
|
||||
El,
|
||||
/// English (US)
|
||||
En,
|
||||
/// English (UK)
|
||||
#[serde(rename = "en-GB")]
|
||||
EnGb,
|
||||
/// English (India)
|
||||
#[serde(rename = "en-IN")]
|
||||
EnIn,
|
||||
/// Español (España)
|
||||
Es,
|
||||
/// Español (Latinoamérica)
|
||||
#[serde(rename = "es-419")]
|
||||
Es419,
|
||||
/// Español (US)
|
||||
#[serde(rename = "es-US")]
|
||||
EsUs,
|
||||
/// Eesti
|
||||
Et,
|
||||
/// Euskara
|
||||
Eu,
|
||||
/// فارسی
|
||||
Fa,
|
||||
/// Suomi
|
||||
Fi,
|
||||
/// Filipino
|
||||
Fil,
|
||||
/// Français
|
||||
Fr,
|
||||
/// Français (Canada)
|
||||
#[serde(rename = "fr-CA")]
|
||||
FrCa,
|
||||
/// Galego
|
||||
Gl,
|
||||
/// ગુજરાતી
|
||||
Gu,
|
||||
/// हिन्दी
|
||||
Hi,
|
||||
/// Hrvatski
|
||||
Hr,
|
||||
/// Magyar
|
||||
Hu,
|
||||
/// Հայերեն
|
||||
Hy,
|
||||
/// Bahasa Indonesia
|
||||
Id,
|
||||
/// Íslenska
|
||||
Is,
|
||||
/// Italiano
|
||||
It,
|
||||
/// עברית
|
||||
Iw,
|
||||
/// 日本語
|
||||
Ja,
|
||||
/// ქართული
|
||||
Ka,
|
||||
/// Қазақ Тілі
|
||||
Kk,
|
||||
/// ខ្មែរ
|
||||
Km,
|
||||
/// ಕನ್ನಡ
|
||||
Kn,
|
||||
/// 한국어
|
||||
Ko,
|
||||
/// Кыргызча
|
||||
Ky,
|
||||
/// ລາວ
|
||||
Lo,
|
||||
/// Lietuvių
|
||||
Lt,
|
||||
/// Latviešu valoda
|
||||
Lv,
|
||||
/// Македонски
|
||||
Mk,
|
||||
/// മലയാളം
|
||||
Ml,
|
||||
/// Монгол
|
||||
Mn,
|
||||
/// मराठी
|
||||
Mr,
|
||||
/// Bahasa Malaysia
|
||||
Ms,
|
||||
/// ဗမာ
|
||||
My,
|
||||
/// नेपाली
|
||||
Ne,
|
||||
/// Nederlands
|
||||
Nl,
|
||||
/// Norsk
|
||||
No,
|
||||
/// ଓଡ଼ିଆ
|
||||
Or,
|
||||
/// ਪੰਜਾਬੀ
|
||||
Pa,
|
||||
/// Polski
|
||||
Pl,
|
||||
/// Português (Brasil)
|
||||
Pt,
|
||||
/// Português
|
||||
#[serde(rename = "pt-PT")]
|
||||
PtPt,
|
||||
/// Română
|
||||
Ro,
|
||||
/// Русский
|
||||
Ru,
|
||||
/// සිංහල
|
||||
Si,
|
||||
/// Slovenčina
|
||||
Sk,
|
||||
/// Slovenščina
|
||||
Sl,
|
||||
/// Shqip
|
||||
Sq,
|
||||
/// Српски
|
||||
Sr,
|
||||
/// Srpski
|
||||
#[serde(rename = "sr-Latn")]
|
||||
SrLatn,
|
||||
/// Svenska
|
||||
Sv,
|
||||
/// Kiswahili
|
||||
Sw,
|
||||
/// தமிழ்
|
||||
Ta,
|
||||
/// తెలుగు
|
||||
Te,
|
||||
/// ภาษาไทย
|
||||
Th,
|
||||
/// Türkçe
|
||||
Tr,
|
||||
/// Українська
|
||||
Uk,
|
||||
/// اردو
|
||||
Ur,
|
||||
/// O‘zbek
|
||||
Uz,
|
||||
/// Tiếng Việt
|
||||
Vi,
|
||||
/// 中文 (简体)
|
||||
#[serde(rename = "zh-CN")]
|
||||
ZhCn,
|
||||
/// 中文 (香港)
|
||||
#[serde(rename = "zh-HK")]
|
||||
ZhHk,
|
||||
/// 中文 (繁體)
|
||||
#[serde(rename = "zh-TW")]
|
||||
ZhTw,
|
||||
/// IsiZulu
|
||||
Zu,
|
||||
}
|
||||
|
||||
/// Available countries
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum Country {
|
||||
/// United Arab Emirates
|
||||
Ae,
|
||||
/// Argentina
|
||||
Ar,
|
||||
/// Austria
|
||||
At,
|
||||
/// Australia
|
||||
Au,
|
||||
/// Azerbaijan
|
||||
Az,
|
||||
/// Bosnia and Herzegovina
|
||||
Ba,
|
||||
/// Bangladesh
|
||||
Bd,
|
||||
/// Belgium
|
||||
Be,
|
||||
/// Bulgaria
|
||||
Bg,
|
||||
/// Bahrain
|
||||
Bh,
|
||||
/// Bolivia
|
||||
Bo,
|
||||
/// Brazil
|
||||
Br,
|
||||
/// Belarus
|
||||
By,
|
||||
/// Canada
|
||||
Ca,
|
||||
/// Switzerland
|
||||
Ch,
|
||||
/// Chile
|
||||
Cl,
|
||||
/// Colombia
|
||||
Co,
|
||||
/// Costa Rica
|
||||
Cr,
|
||||
/// Cyprus
|
||||
Cy,
|
||||
/// Czechia
|
||||
Cz,
|
||||
/// Germany
|
||||
De,
|
||||
/// Denmark
|
||||
Dk,
|
||||
/// Dominican Republic
|
||||
Do,
|
||||
/// Algeria
|
||||
Dz,
|
||||
/// Ecuador
|
||||
Ec,
|
||||
/// Estonia
|
||||
Ee,
|
||||
/// Egypt
|
||||
Eg,
|
||||
/// Spain
|
||||
Es,
|
||||
/// Finland
|
||||
Fi,
|
||||
/// France
|
||||
Fr,
|
||||
/// United Kingdom
|
||||
Gb,
|
||||
/// Georgia
|
||||
Ge,
|
||||
/// Ghana
|
||||
Gh,
|
||||
/// Greece
|
||||
Gr,
|
||||
/// Guatemala
|
||||
Gt,
|
||||
/// Hong Kong
|
||||
Hk,
|
||||
/// Honduras
|
||||
Hn,
|
||||
/// Croatia
|
||||
Hr,
|
||||
/// Hungary
|
||||
Hu,
|
||||
/// Indonesia
|
||||
Id,
|
||||
/// Ireland
|
||||
Ie,
|
||||
/// Israel
|
||||
Il,
|
||||
/// India
|
||||
In,
|
||||
/// Iraq
|
||||
Iq,
|
||||
/// Iceland
|
||||
Is,
|
||||
/// Italy
|
||||
It,
|
||||
/// Jamaica
|
||||
Jm,
|
||||
/// Jordan
|
||||
Jo,
|
||||
/// Japan
|
||||
Jp,
|
||||
/// Kenya
|
||||
Ke,
|
||||
/// Cambodia
|
||||
Kh,
|
||||
/// South Korea
|
||||
Kr,
|
||||
/// Kuwait
|
||||
Kw,
|
||||
/// Kazakhstan
|
||||
Kz,
|
||||
/// Laos
|
||||
La,
|
||||
/// Lebanon
|
||||
Lb,
|
||||
/// Liechtenstein
|
||||
Li,
|
||||
/// Sri Lanka
|
||||
Lk,
|
||||
/// Lithuania
|
||||
Lt,
|
||||
/// Luxembourg
|
||||
Lu,
|
||||
/// Latvia
|
||||
Lv,
|
||||
/// Libya
|
||||
Ly,
|
||||
/// Morocco
|
||||
Ma,
|
||||
/// Montenegro
|
||||
Me,
|
||||
/// North Macedonia
|
||||
Mk,
|
||||
/// Malta
|
||||
Mt,
|
||||
/// Mexico
|
||||
Mx,
|
||||
/// Malaysia
|
||||
My,
|
||||
/// Nigeria
|
||||
Ng,
|
||||
/// Nicaragua
|
||||
Ni,
|
||||
/// Netherlands
|
||||
Nl,
|
||||
/// Norway
|
||||
No,
|
||||
/// Nepal
|
||||
Np,
|
||||
/// New Zealand
|
||||
Nz,
|
||||
/// Oman
|
||||
Om,
|
||||
/// Panama
|
||||
Pa,
|
||||
/// Peru
|
||||
Pe,
|
||||
/// Papua New Guinea
|
||||
Pg,
|
||||
/// Philippines
|
||||
Ph,
|
||||
/// Pakistan
|
||||
Pk,
|
||||
/// Poland
|
||||
Pl,
|
||||
/// Puerto Rico
|
||||
Pr,
|
||||
/// Portugal
|
||||
Pt,
|
||||
/// Paraguay
|
||||
Py,
|
||||
/// Qatar
|
||||
Qa,
|
||||
/// Romania
|
||||
Ro,
|
||||
/// Serbia
|
||||
Rs,
|
||||
/// Russia
|
||||
Ru,
|
||||
/// Saudi Arabia
|
||||
Sa,
|
||||
/// Sweden
|
||||
Se,
|
||||
/// Singapore
|
||||
Sg,
|
||||
/// Slovenia
|
||||
Si,
|
||||
/// Slovakia
|
||||
Sk,
|
||||
/// Senegal
|
||||
Sn,
|
||||
/// El Salvador
|
||||
Sv,
|
||||
/// Thailand
|
||||
Th,
|
||||
/// Tunisia
|
||||
Tn,
|
||||
/// Turkey
|
||||
Tr,
|
||||
/// Taiwan
|
||||
Tw,
|
||||
/// Tanzania
|
||||
Tz,
|
||||
/// Ukraine
|
||||
Ua,
|
||||
/// Uganda
|
||||
Ug,
|
||||
/// United States
|
||||
Us,
|
||||
/// Uruguay
|
||||
Uy,
|
||||
/// Venezuela
|
||||
Ve,
|
||||
/// Vietnam
|
||||
Vn,
|
||||
/// Yemen
|
||||
Ye,
|
||||
/// South Africa
|
||||
Za,
|
||||
/// Zimbabwe
|
||||
Zw,
|
||||
}
|
||||
|
||||
/// Array of all available languages
|
||||
pub const LANGUAGES: [Language; 83] = [
|
||||
Language::Af,
|
||||
Language::Am,
|
||||
Language::Ar,
|
||||
Language::As,
|
||||
Language::Az,
|
||||
Language::Be,
|
||||
Language::Bg,
|
||||
Language::Bn,
|
||||
Language::Bs,
|
||||
Language::Ca,
|
||||
Language::Cs,
|
||||
Language::Da,
|
||||
Language::De,
|
||||
Language::El,
|
||||
Language::En,
|
||||
Language::EnGb,
|
||||
Language::EnIn,
|
||||
Language::Es,
|
||||
Language::Es419,
|
||||
Language::EsUs,
|
||||
Language::Et,
|
||||
Language::Eu,
|
||||
Language::Fa,
|
||||
Language::Fi,
|
||||
Language::Fil,
|
||||
Language::Fr,
|
||||
Language::FrCa,
|
||||
Language::Gl,
|
||||
Language::Gu,
|
||||
Language::Hi,
|
||||
Language::Hr,
|
||||
Language::Hu,
|
||||
Language::Hy,
|
||||
Language::Id,
|
||||
Language::Is,
|
||||
Language::It,
|
||||
Language::Iw,
|
||||
Language::Ja,
|
||||
Language::Ka,
|
||||
Language::Kk,
|
||||
Language::Km,
|
||||
Language::Kn,
|
||||
Language::Ko,
|
||||
Language::Ky,
|
||||
Language::Lo,
|
||||
Language::Lt,
|
||||
Language::Lv,
|
||||
Language::Mk,
|
||||
Language::Ml,
|
||||
Language::Mn,
|
||||
Language::Mr,
|
||||
Language::Ms,
|
||||
Language::My,
|
||||
Language::Ne,
|
||||
Language::Nl,
|
||||
Language::No,
|
||||
Language::Or,
|
||||
Language::Pa,
|
||||
Language::Pl,
|
||||
Language::Pt,
|
||||
Language::PtPt,
|
||||
Language::Ro,
|
||||
Language::Ru,
|
||||
Language::Si,
|
||||
Language::Sk,
|
||||
Language::Sl,
|
||||
Language::Sq,
|
||||
Language::Sr,
|
||||
Language::SrLatn,
|
||||
Language::Sv,
|
||||
Language::Sw,
|
||||
Language::Ta,
|
||||
Language::Te,
|
||||
Language::Th,
|
||||
Language::Tr,
|
||||
Language::Uk,
|
||||
Language::Ur,
|
||||
Language::Uz,
|
||||
Language::Vi,
|
||||
Language::ZhCn,
|
||||
Language::ZhHk,
|
||||
Language::ZhTw,
|
||||
Language::Zu,
|
||||
];
|
||||
|
||||
/// Array of all available countries
|
||||
pub const COUNTRIES: [Country; 109] = [
|
||||
Country::Ae,
|
||||
Country::Ar,
|
||||
Country::At,
|
||||
Country::Au,
|
||||
Country::Az,
|
||||
Country::Ba,
|
||||
Country::Bd,
|
||||
Country::Be,
|
||||
Country::Bg,
|
||||
Country::Bh,
|
||||
Country::Bo,
|
||||
Country::Br,
|
||||
Country::By,
|
||||
Country::Ca,
|
||||
Country::Ch,
|
||||
Country::Cl,
|
||||
Country::Co,
|
||||
Country::Cr,
|
||||
Country::Cy,
|
||||
Country::Cz,
|
||||
Country::De,
|
||||
Country::Dk,
|
||||
Country::Do,
|
||||
Country::Dz,
|
||||
Country::Ec,
|
||||
Country::Ee,
|
||||
Country::Eg,
|
||||
Country::Es,
|
||||
Country::Fi,
|
||||
Country::Fr,
|
||||
Country::Gb,
|
||||
Country::Ge,
|
||||
Country::Gh,
|
||||
Country::Gr,
|
||||
Country::Gt,
|
||||
Country::Hk,
|
||||
Country::Hn,
|
||||
Country::Hr,
|
||||
Country::Hu,
|
||||
Country::Id,
|
||||
Country::Ie,
|
||||
Country::Il,
|
||||
Country::In,
|
||||
Country::Iq,
|
||||
Country::Is,
|
||||
Country::It,
|
||||
Country::Jm,
|
||||
Country::Jo,
|
||||
Country::Jp,
|
||||
Country::Ke,
|
||||
Country::Kh,
|
||||
Country::Kr,
|
||||
Country::Kw,
|
||||
Country::Kz,
|
||||
Country::La,
|
||||
Country::Lb,
|
||||
Country::Li,
|
||||
Country::Lk,
|
||||
Country::Lt,
|
||||
Country::Lu,
|
||||
Country::Lv,
|
||||
Country::Ly,
|
||||
Country::Ma,
|
||||
Country::Me,
|
||||
Country::Mk,
|
||||
Country::Mt,
|
||||
Country::Mx,
|
||||
Country::My,
|
||||
Country::Ng,
|
||||
Country::Ni,
|
||||
Country::Nl,
|
||||
Country::No,
|
||||
Country::Np,
|
||||
Country::Nz,
|
||||
Country::Om,
|
||||
Country::Pa,
|
||||
Country::Pe,
|
||||
Country::Pg,
|
||||
Country::Ph,
|
||||
Country::Pk,
|
||||
Country::Pl,
|
||||
Country::Pr,
|
||||
Country::Pt,
|
||||
Country::Py,
|
||||
Country::Qa,
|
||||
Country::Ro,
|
||||
Country::Rs,
|
||||
Country::Ru,
|
||||
Country::Sa,
|
||||
Country::Se,
|
||||
Country::Sg,
|
||||
Country::Si,
|
||||
Country::Sk,
|
||||
Country::Sn,
|
||||
Country::Sv,
|
||||
Country::Th,
|
||||
Country::Tn,
|
||||
Country::Tr,
|
||||
Country::Tw,
|
||||
Country::Tz,
|
||||
Country::Ua,
|
||||
Country::Ug,
|
||||
Country::Us,
|
||||
Country::Uy,
|
||||
Country::Ve,
|
||||
Country::Vn,
|
||||
Country::Ye,
|
||||
Country::Za,
|
||||
Country::Zw,
|
||||
];
|
||||
|
||||
impl Language {
|
||||
/// Get the native name of the language
|
||||
///
|
||||
/// Examples: "English (US)", "Deutsch", "中文 (简体)"
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Language::Af => "Afrikaans",
|
||||
Language::Am => "አማርኛ",
|
||||
Language::Ar => "العربية",
|
||||
Language::As => "অসমীয়া",
|
||||
Language::Az => "Azərbaycan",
|
||||
Language::Be => "Беларуская",
|
||||
Language::Bg => "Български",
|
||||
Language::Bn => "বাংলা",
|
||||
Language::Bs => "Bosanski",
|
||||
Language::Ca => "Català",
|
||||
Language::Cs => "Čeština",
|
||||
Language::Da => "Dansk",
|
||||
Language::De => "Deutsch",
|
||||
Language::El => "Ελληνικά",
|
||||
Language::En => "English (US)",
|
||||
Language::EnGb => "English (UK)",
|
||||
Language::EnIn => "English (India)",
|
||||
Language::Es => "Español (España)",
|
||||
Language::Es419 => "Español (Latinoamérica)",
|
||||
Language::EsUs => "Español (US)",
|
||||
Language::Et => "Eesti",
|
||||
Language::Eu => "Euskara",
|
||||
Language::Fa => "فارسی",
|
||||
Language::Fi => "Suomi",
|
||||
Language::Fil => "Filipino",
|
||||
Language::Fr => "Français",
|
||||
Language::FrCa => "Français (Canada)",
|
||||
Language::Gl => "Galego",
|
||||
Language::Gu => "ગુજરાતી",
|
||||
Language::Hi => "हिन्दी",
|
||||
Language::Hr => "Hrvatski",
|
||||
Language::Hu => "Magyar",
|
||||
Language::Hy => "Հայերեն",
|
||||
Language::Id => "Bahasa Indonesia",
|
||||
Language::Is => "Íslenska",
|
||||
Language::It => "Italiano",
|
||||
Language::Iw => "עברית",
|
||||
Language::Ja => "日本語",
|
||||
Language::Ka => "ქართული",
|
||||
Language::Kk => "Қазақ Тілі",
|
||||
Language::Km => "ខ្មែរ",
|
||||
Language::Kn => "ಕನ್ನಡ",
|
||||
Language::Ko => "한국어",
|
||||
Language::Ky => "Кыргызча",
|
||||
Language::Lo => "ລາວ",
|
||||
Language::Lt => "Lietuvių",
|
||||
Language::Lv => "Latviešu valoda",
|
||||
Language::Mk => "Македонски",
|
||||
Language::Ml => "മലയാളം",
|
||||
Language::Mn => "Монгол",
|
||||
Language::Mr => "मराठी",
|
||||
Language::Ms => "Bahasa Malaysia",
|
||||
Language::My => "ဗမာ",
|
||||
Language::Ne => "नेपाली",
|
||||
Language::Nl => "Nederlands",
|
||||
Language::No => "Norsk",
|
||||
Language::Or => "ଓଡ଼ିଆ",
|
||||
Language::Pa => "ਪੰਜਾਬੀ",
|
||||
Language::Pl => "Polski",
|
||||
Language::Pt => "Português (Brasil)",
|
||||
Language::PtPt => "Português",
|
||||
Language::Ro => "Română",
|
||||
Language::Ru => "Русский",
|
||||
Language::Si => "සිංහල",
|
||||
Language::Sk => "Slovenčina",
|
||||
Language::Sl => "Slovenščina",
|
||||
Language::Sq => "Shqip",
|
||||
Language::Sr => "Српски",
|
||||
Language::SrLatn => "Srpski",
|
||||
Language::Sv => "Svenska",
|
||||
Language::Sw => "Kiswahili",
|
||||
Language::Ta => "தமிழ்",
|
||||
Language::Te => "తెలుగు",
|
||||
Language::Th => "ภาษาไทย",
|
||||
Language::Tr => "Türkçe",
|
||||
Language::Uk => "Українська",
|
||||
Language::Ur => "اردو",
|
||||
Language::Uz => "O‘zbek",
|
||||
Language::Vi => "Tiếng Việt",
|
||||
Language::ZhCn => "中文 (简体)",
|
||||
Language::ZhHk => "中文 (香港)",
|
||||
Language::ZhTw => "中文 (繁體)",
|
||||
Language::Zu => "IsiZulu",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Country {
|
||||
/// Get the English name of the country
|
||||
///
|
||||
/// Examples: "United States", "Germany"
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Country::Ae => "United Arab Emirates",
|
||||
Country::Ar => "Argentina",
|
||||
Country::At => "Austria",
|
||||
Country::Au => "Australia",
|
||||
Country::Az => "Azerbaijan",
|
||||
Country::Ba => "Bosnia and Herzegovina",
|
||||
Country::Bd => "Bangladesh",
|
||||
Country::Be => "Belgium",
|
||||
Country::Bg => "Bulgaria",
|
||||
Country::Bh => "Bahrain",
|
||||
Country::Bo => "Bolivia",
|
||||
Country::Br => "Brazil",
|
||||
Country::By => "Belarus",
|
||||
Country::Ca => "Canada",
|
||||
Country::Ch => "Switzerland",
|
||||
Country::Cl => "Chile",
|
||||
Country::Co => "Colombia",
|
||||
Country::Cr => "Costa Rica",
|
||||
Country::Cy => "Cyprus",
|
||||
Country::Cz => "Czechia",
|
||||
Country::De => "Germany",
|
||||
Country::Dk => "Denmark",
|
||||
Country::Do => "Dominican Republic",
|
||||
Country::Dz => "Algeria",
|
||||
Country::Ec => "Ecuador",
|
||||
Country::Ee => "Estonia",
|
||||
Country::Eg => "Egypt",
|
||||
Country::Es => "Spain",
|
||||
Country::Fi => "Finland",
|
||||
Country::Fr => "France",
|
||||
Country::Gb => "United Kingdom",
|
||||
Country::Ge => "Georgia",
|
||||
Country::Gh => "Ghana",
|
||||
Country::Gr => "Greece",
|
||||
Country::Gt => "Guatemala",
|
||||
Country::Hk => "Hong Kong",
|
||||
Country::Hn => "Honduras",
|
||||
Country::Hr => "Croatia",
|
||||
Country::Hu => "Hungary",
|
||||
Country::Id => "Indonesia",
|
||||
Country::Ie => "Ireland",
|
||||
Country::Il => "Israel",
|
||||
Country::In => "India",
|
||||
Country::Iq => "Iraq",
|
||||
Country::Is => "Iceland",
|
||||
Country::It => "Italy",
|
||||
Country::Jm => "Jamaica",
|
||||
Country::Jo => "Jordan",
|
||||
Country::Jp => "Japan",
|
||||
Country::Ke => "Kenya",
|
||||
Country::Kh => "Cambodia",
|
||||
Country::Kr => "South Korea",
|
||||
Country::Kw => "Kuwait",
|
||||
Country::Kz => "Kazakhstan",
|
||||
Country::La => "Laos",
|
||||
Country::Lb => "Lebanon",
|
||||
Country::Li => "Liechtenstein",
|
||||
Country::Lk => "Sri Lanka",
|
||||
Country::Lt => "Lithuania",
|
||||
Country::Lu => "Luxembourg",
|
||||
Country::Lv => "Latvia",
|
||||
Country::Ly => "Libya",
|
||||
Country::Ma => "Morocco",
|
||||
Country::Me => "Montenegro",
|
||||
Country::Mk => "North Macedonia",
|
||||
Country::Mt => "Malta",
|
||||
Country::Mx => "Mexico",
|
||||
Country::My => "Malaysia",
|
||||
Country::Ng => "Nigeria",
|
||||
Country::Ni => "Nicaragua",
|
||||
Country::Nl => "Netherlands",
|
||||
Country::No => "Norway",
|
||||
Country::Np => "Nepal",
|
||||
Country::Nz => "New Zealand",
|
||||
Country::Om => "Oman",
|
||||
Country::Pa => "Panama",
|
||||
Country::Pe => "Peru",
|
||||
Country::Pg => "Papua New Guinea",
|
||||
Country::Ph => "Philippines",
|
||||
Country::Pk => "Pakistan",
|
||||
Country::Pl => "Poland",
|
||||
Country::Pr => "Puerto Rico",
|
||||
Country::Pt => "Portugal",
|
||||
Country::Py => "Paraguay",
|
||||
Country::Qa => "Qatar",
|
||||
Country::Ro => "Romania",
|
||||
Country::Rs => "Serbia",
|
||||
Country::Ru => "Russia",
|
||||
Country::Sa => "Saudi Arabia",
|
||||
Country::Se => "Sweden",
|
||||
Country::Sg => "Singapore",
|
||||
Country::Si => "Slovenia",
|
||||
Country::Sk => "Slovakia",
|
||||
Country::Sn => "Senegal",
|
||||
Country::Sv => "El Salvador",
|
||||
Country::Th => "Thailand",
|
||||
Country::Tn => "Tunisia",
|
||||
Country::Tr => "Turkey",
|
||||
Country::Tw => "Taiwan",
|
||||
Country::Tz => "Tanzania",
|
||||
Country::Ua => "Ukraine",
|
||||
Country::Ug => "Uganda",
|
||||
Country::Us => "United States",
|
||||
Country::Uy => "Uruguay",
|
||||
Country::Ve => "Venezuela",
|
||||
Country::Vn => "Vietnam",
|
||||
Country::Ye => "Yemen",
|
||||
Country::Za => "South Africa",
|
||||
Country::Zw => "Zimbabwe",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Language {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(
|
||||
&serde_json::to_string(self).map_or("".to_owned(), |s| s[1..s.len() - 1].to_owned()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Country {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(
|
||||
&serde_json::to_string(self).map_or("".to_owned(), |s| s[1..s.len() - 1].to_owned()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Language {
|
||||
type Err = serde_json::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
serde_json::from_str(&format!("\"{}\"", s))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Country {
|
||||
type Err = serde_json::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
serde_json::from_str(&format!("\"{}\"", s))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,10 @@
|
|||
//! YouTube API request and response models
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
/// Channel video sort order
|
||||
#[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,
|
||||
}
|
||||
|
|
@ -1,420 +0,0 @@
|
|||
//! Filters for selecting audio/video streams
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::{
|
||||
AudioCodec, AudioFormat, AudioStream, VideoCodec, VideoFormat, VideoPlayer, VideoStream,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Filter {
|
||||
audio_max_bitrate: Option<u32>,
|
||||
audio_formats: Option<HashSet<AudioFormat>>,
|
||||
audio_codecs: Option<HashSet<AudioCodec>>,
|
||||
audio_language: Option<String>,
|
||||
video_max_res: Option<u32>,
|
||||
video_max_fps: Option<u8>,
|
||||
video_formats: Option<HashSet<VideoFormat>>,
|
||||
video_codecs: Option<HashSet<VideoCodec>>,
|
||||
video_hdr: bool,
|
||||
video_none: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
enum FilterResult {
|
||||
Deny,
|
||||
AllowLowest,
|
||||
Allow,
|
||||
Match,
|
||||
}
|
||||
|
||||
impl FilterResult {
|
||||
fn hard(val: bool) -> Self {
|
||||
match val {
|
||||
true => Self::Match,
|
||||
false => Self::Deny,
|
||||
}
|
||||
}
|
||||
|
||||
fn soft(val: bool) -> Self {
|
||||
match val {
|
||||
true => Self::Match,
|
||||
false => Self::AllowLowest,
|
||||
}
|
||||
}
|
||||
|
||||
fn allow(val: bool) -> Self {
|
||||
match val {
|
||||
true => Self::Allow,
|
||||
false => Self::Deny,
|
||||
}
|
||||
}
|
||||
|
||||
fn join(self, other: Self) -> Self {
|
||||
match self == Self::Deny {
|
||||
true => Self::Deny,
|
||||
false => self.min(other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Filter {
|
||||
/// Set the maximum audio bitrate in bits per second.
|
||||
///
|
||||
/// This is a soft filter, so if there is no stream with a bitrate
|
||||
/// <= the limit, the stream with the next higher bitrate is returned.
|
||||
pub fn audio_max_bitrate(&mut self, max_bitrate: u32) -> &mut Self {
|
||||
self.audio_max_bitrate = Some(max_bitrate);
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_audio_max_bitrate(&self, stream: &AudioStream) -> FilterResult {
|
||||
match self.audio_max_bitrate {
|
||||
Some(max_bitrate) => FilterResult::soft(stream.average_bitrate <= max_bitrate),
|
||||
None => FilterResult::Match,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the supported audio container formats
|
||||
pub fn audio_formats(&mut self, formats: HashSet<AudioFormat>) -> &mut Self {
|
||||
self.audio_formats = Some(formats);
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_audio_formats(&self, stream: &AudioStream) -> FilterResult {
|
||||
match &self.audio_formats {
|
||||
Some(formats) => FilterResult::hard(formats.contains(&stream.format)),
|
||||
None => FilterResult::Match,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the supported audio codecs
|
||||
pub fn audio_codecs(&mut self, codecs: HashSet<AudioCodec>) -> &mut Self {
|
||||
self.audio_codecs = Some(codecs);
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_audio_codecs(&self, stream: &AudioStream) -> FilterResult {
|
||||
match &self.audio_codecs {
|
||||
Some(codecs) => FilterResult::hard(codecs.contains(&stream.codec)),
|
||||
None => FilterResult::Match,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the preferred audio language (2 letter ISO 639-1 code, e.g. `en`, `fr`).
|
||||
/// Some YouTube videos feature multiple audio streams in
|
||||
/// different languages (e.g. <https://www.youtube.com/watch?v=tVWWp1PqDus>).
|
||||
///
|
||||
/// If this filter is unset or no stream matches,
|
||||
/// the filter returns the default audio stream.
|
||||
pub fn audio_language(&mut self, language: &str) -> &mut Self {
|
||||
self.audio_language = Some(language.to_owned());
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_audio_language(&self, stream: &AudioStream) -> FilterResult {
|
||||
match &self.audio_language {
|
||||
Some(language) => match &stream.track {
|
||||
Some(track) => match &track.lang {
|
||||
Some(track_lang) => match track_lang == language {
|
||||
true => FilterResult::Match,
|
||||
false => FilterResult::allow(track.is_default),
|
||||
},
|
||||
None => FilterResult::allow(track.is_default),
|
||||
},
|
||||
None => FilterResult::Match,
|
||||
},
|
||||
None => FilterResult::hard(stream.track.as_ref().map_or(true, |t| t.is_default)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the maximum video resolution. Resolution is determined by the
|
||||
/// pixel count of the shorter edge (e.g. 1080p).
|
||||
///
|
||||
/// This is a soft filter, so if there is no stream with a resolution
|
||||
/// <= the limit, the stream with the next higher resolution is returned.
|
||||
pub fn video_max_res(&mut self, max_res: u32) -> &mut Self {
|
||||
self.video_max_res = Some(max_res);
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_video_max_res(&self, stream: &VideoStream) -> FilterResult {
|
||||
match self.video_max_res {
|
||||
Some(max_res) => FilterResult::soft(stream.height.min(stream.width) <= max_res),
|
||||
None => FilterResult::Match,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the maximum video framerate.
|
||||
///
|
||||
/// This is a soft filter, so if there is no stream with a framerate
|
||||
/// <= the limit, the stream with the next higher framerate is returned.
|
||||
pub fn video_max_fps(&mut self, max_fps: u8) -> &mut Self {
|
||||
self.video_max_fps = Some(max_fps);
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_video_max_fps(&self, stream: &VideoStream) -> FilterResult {
|
||||
match self.video_max_fps {
|
||||
Some(max_fps) => FilterResult::soft(stream.fps <= max_fps),
|
||||
None => FilterResult::Match,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the supported video container formats
|
||||
pub fn video_formats(&mut self, formats: HashSet<VideoFormat>) -> &mut Self {
|
||||
self.video_formats = Some(formats);
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_video_formats(&self, stream: &VideoStream) -> FilterResult {
|
||||
match &self.video_formats {
|
||||
Some(formats) => FilterResult::hard(formats.contains(&stream.format)),
|
||||
None => FilterResult::Match,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the supported video codecs
|
||||
pub fn video_codecs(&mut self, codecs: HashSet<VideoCodec>) -> &mut Self {
|
||||
self.video_codecs = Some(codecs);
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_video_codecs(&self, stream: &VideoStream) -> FilterResult {
|
||||
match &self.video_codecs {
|
||||
Some(codecs) => FilterResult::hard(codecs.contains(&stream.codec)),
|
||||
None => FilterResult::Match,
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow HDR videos
|
||||
pub fn video_hdr(&mut self) -> &mut Self {
|
||||
self.video_hdr = true;
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_video_hdr(&self, stream: &VideoStream) -> FilterResult {
|
||||
match &self.video_hdr {
|
||||
true => FilterResult::Match,
|
||||
false => FilterResult::hard(!&stream.hdr),
|
||||
}
|
||||
}
|
||||
|
||||
/// Output no video stream (audio only)
|
||||
pub fn no_video(&mut self) -> &mut Self {
|
||||
self.video_none = true;
|
||||
self
|
||||
}
|
||||
|
||||
fn apply_audio(&self, stream: &AudioStream) -> FilterResult {
|
||||
self.apply_audio_max_bitrate(stream).join(
|
||||
self.apply_audio_formats(stream).join(
|
||||
self.apply_audio_codecs(stream)
|
||||
.join(self.apply_audio_language(stream)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn apply_video(&self, stream: &VideoStream) -> FilterResult {
|
||||
self.apply_video_max_res(stream).join(
|
||||
self.apply_video_formats(stream).join(
|
||||
self.apply_video_codecs(stream).join(
|
||||
self.apply_video_hdr(stream)
|
||||
.join(self.apply_video_max_fps(stream)),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl VideoPlayer {
|
||||
pub fn select_audio_stream(&self, filter: &Filter) -> Option<&AudioStream> {
|
||||
let mut fallback: Option<&AudioStream> = None;
|
||||
|
||||
self.audio_streams
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|s| match filter.apply_audio(s) {
|
||||
FilterResult::Deny => false,
|
||||
FilterResult::AllowLowest => {
|
||||
fallback = Some(s);
|
||||
false
|
||||
}
|
||||
FilterResult::Allow => {
|
||||
if fallback.is_none() {
|
||||
fallback = Some(s);
|
||||
}
|
||||
false
|
||||
}
|
||||
FilterResult::Match => true,
|
||||
})
|
||||
.or(fallback)
|
||||
}
|
||||
|
||||
fn _select_video_stream<'a>(
|
||||
streams: &'a [VideoStream],
|
||||
filter: &Filter,
|
||||
) -> Option<&'a VideoStream> {
|
||||
if filter.video_none {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut fallback: Option<&VideoStream> = None;
|
||||
|
||||
streams
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|s| match filter.apply_video(s) {
|
||||
FilterResult::Deny => false,
|
||||
FilterResult::AllowLowest => {
|
||||
fallback = Some(s);
|
||||
false
|
||||
}
|
||||
FilterResult::Allow => {
|
||||
if fallback.is_none() {
|
||||
fallback = Some(s);
|
||||
}
|
||||
false
|
||||
}
|
||||
FilterResult::Match => true,
|
||||
})
|
||||
.or(fallback)
|
||||
}
|
||||
|
||||
pub fn select_video_stream(&self, filter: &Filter) -> Option<&VideoStream> {
|
||||
Self::_select_video_stream(&self.video_streams, filter)
|
||||
}
|
||||
|
||||
pub fn select_video_only_stream(&self, filter: &Filter) -> Option<&VideoStream> {
|
||||
Self::_select_video_stream(&self.video_only_streams, filter)
|
||||
}
|
||||
|
||||
pub fn select_video_audio_stream(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
) -> (Option<&VideoStream>, Option<&AudioStream>) {
|
||||
let video_stream = self.select_video_stream(filter);
|
||||
let video_only_stream = self.select_video_only_stream(filter);
|
||||
|
||||
match (video_stream, video_only_stream) {
|
||||
(None, None) => (None, self.select_audio_stream(filter)),
|
||||
(None, Some(video_only_stream)) => {
|
||||
(Some(video_only_stream), self.select_audio_stream(filter))
|
||||
}
|
||||
(Some(video_stream), None) => (Some(video_stream), None),
|
||||
(Some(video_stream), Some(video_only_stream)) => match video_only_stream > video_stream
|
||||
{
|
||||
true => (
|
||||
Some(video_only_stream),
|
||||
Some(some_or_bail!(
|
||||
self.select_audio_stream(filter),
|
||||
(Some(video_stream), None)
|
||||
)),
|
||||
),
|
||||
false => (Some(video_stream), None),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{fs::File, io::BufReader, path::Path};
|
||||
|
||||
use super::*;
|
||||
use once_cell::sync::Lazy;
|
||||
use rstest::rstest;
|
||||
use velcro::hash_set;
|
||||
|
||||
static PLAYER_ML: Lazy<VideoPlayer> = Lazy::new(|| {
|
||||
let json_path = Path::new("testfiles/player_model/multilanguage.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
|
||||
serde_json::from_reader(BufReader::new(json_file)).unwrap()
|
||||
});
|
||||
|
||||
static PLAYER_HDR: Lazy<VideoPlayer> = Lazy::new(|| {
|
||||
let json_path = Path::new("testfiles/player_model/hdr.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
|
||||
serde_json::from_reader(BufReader::new(json_file)).unwrap()
|
||||
});
|
||||
|
||||
#[rstest]
|
||||
#[case::default(Filter::default(), Some("https://rr4---sn-h0jeener.googlevideo.com/videoplayback?c=WEB&clen=16104134&dur=1012.661&ei=498HY6KvArqM6dsPiN6QgAE&expire=1661482051&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AK8GbbQovVxldcBz4pkXu4EA9N2sU-4yPPa5hFT3bXta&initcwndbps=1392500&ip=2003%3Ade%3Aaf1e%3A8a00%3A84c6%3A28f3%3A9de2%3A464&itag=251&keepalive=yes&lmt=1659767097097120&lsig=AG3C_xAwRAIgLFPuLqOoHoNQax15AE9Q2YIZ7pM7-olbGWgYGv1MDccCIADKSc_HeOdmD7CDs4AkY5ZtWF4gdZd4rw99Cqlzakbk&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=wB&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jeener%2Csn-h0jeln7l&ms=au%2Crdu&mt=1661460078&mv=m&mvi=4&n=LwUYrFgbIVPzmA&ns=bBqoZtLH6lsaX8ke0xgRMM8H&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIgW4IxGJJFRAwZefvDdDkJfjhN7y3bPmh96BCFuyFn6pwCIQDW6pVnk_DwMC3FcZy5rXNUULMNWLdadScxwuhFTFR84g%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cxtags%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-Khmjdu08WYG7DxAg_8xq0R2u5a6w&txp=4532434&vprv=1&xtags=lang%3Den"))]
|
||||
#[case::bitrate(Filter::default().audio_max_bitrate(100000).to_owned(), Some("https://rr4---sn-h0jeener.googlevideo.com/videoplayback?c=WEB&clen=8217507&dur=1012.661&ei=498HY6KvArqM6dsPiN6QgAE&expire=1661482051&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AK8GbbQovVxldcBz4pkXu4EA9N2sU-4yPPa5hFT3bXta&initcwndbps=1392500&ip=2003%3Ade%3Aaf1e%3A8a00%3A84c6%3A28f3%3A9de2%3A464&itag=250&keepalive=yes&lmt=1659767073159859&lsig=AG3C_xAwRAIgLFPuLqOoHoNQax15AE9Q2YIZ7pM7-olbGWgYGv1MDccCIADKSc_HeOdmD7CDs4AkY5ZtWF4gdZd4rw99Cqlzakbk&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=wB&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jeener%2Csn-h0jeln7l&ms=au%2Crdu&mt=1661460078&mv=m&mvi=4&n=LwUYrFgbIVPzmA&ns=bBqoZtLH6lsaX8ke0xgRMM8H&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIgM9loLjlUtgwrALqSek4vO8KljcCltFjLw1TGX0d9lZ4CICRiTJ8a_KgdafXVo2vKwgLPuH2B7t0hF-ln2k_MI3ds&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cxtags%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-Khmjdu08WYG7DxAg_8xq0R2u5a6w&txp=4532434&vprv=1&xtags=lang%3Den"))]
|
||||
#[case::m4a_format(Filter::default().audio_formats(hash_set!(AudioFormat::M4a)).to_owned(), Some("https://rr4---sn-h0jeener.googlevideo.com/videoplayback?c=WEB&clen=16390628&dur=1012.691&ei=498HY6KvArqM6dsPiN6QgAE&expire=1661482051&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AK8GbbQovVxldcBz4pkXu4EA9N2sU-4yPPa5hFT3bXta&initcwndbps=1392500&ip=2003%3Ade%3Aaf1e%3A8a00%3A84c6%3A28f3%3A9de2%3A464&itag=140&keepalive=yes&lmt=1659766154827884&lsig=AG3C_xAwRAIgLFPuLqOoHoNQax15AE9Q2YIZ7pM7-olbGWgYGv1MDccCIADKSc_HeOdmD7CDs4AkY5ZtWF4gdZd4rw99Cqlzakbk&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=wB&mime=audio%2Fmp4&mm=31%2C29&mn=sn-h0jeener%2Csn-h0jeln7l&ms=au%2Crdu&mt=1661460078&mv=m&mvi=4&n=LwUYrFgbIVPzmA&ns=bBqoZtLH6lsaX8ke0xgRMM8H&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIgc8oxPEHDO0cgO3ZcbPmv3nrkzfy52WchpV0HcBcUw24CIEFxLKBcM4vVqGeRkt581dFL2tetvHd93SHCTVEUnIn_&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cxtags%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-Khmjdu08WYG7DxAg_8xq0R2u5a6w&txp=4532434&vprv=1&xtags=lang%3Den"))]
|
||||
#[case::m4a_codec(Filter::default().audio_codecs(hash_set!(AudioCodec::Mp4a)).to_owned(), Some("https://rr4---sn-h0jeener.googlevideo.com/videoplayback?c=WEB&clen=16390628&dur=1012.691&ei=498HY6KvArqM6dsPiN6QgAE&expire=1661482051&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AK8GbbQovVxldcBz4pkXu4EA9N2sU-4yPPa5hFT3bXta&initcwndbps=1392500&ip=2003%3Ade%3Aaf1e%3A8a00%3A84c6%3A28f3%3A9de2%3A464&itag=140&keepalive=yes&lmt=1659766154827884&lsig=AG3C_xAwRAIgLFPuLqOoHoNQax15AE9Q2YIZ7pM7-olbGWgYGv1MDccCIADKSc_HeOdmD7CDs4AkY5ZtWF4gdZd4rw99Cqlzakbk&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=wB&mime=audio%2Fmp4&mm=31%2C29&mn=sn-h0jeener%2Csn-h0jeln7l&ms=au%2Crdu&mt=1661460078&mv=m&mvi=4&n=LwUYrFgbIVPzmA&ns=bBqoZtLH6lsaX8ke0xgRMM8H&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIgc8oxPEHDO0cgO3ZcbPmv3nrkzfy52WchpV0HcBcUw24CIEFxLKBcM4vVqGeRkt581dFL2tetvHd93SHCTVEUnIn_&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cxtags%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-Khmjdu08WYG7DxAg_8xq0R2u5a6w&txp=4532434&vprv=1&xtags=lang%3Den"))]
|
||||
#[case::french(Filter::default().audio_language("fr").to_owned(), Some("https://rr4---sn-h0jeener.googlevideo.com/videoplayback?c=WEB&clen=16357630&dur=1012.721&ei=498HY6KvArqM6dsPiN6QgAE&expire=1661482051&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AK8GbbQovVxldcBz4pkXu4EA9N2sU-4yPPa5hFT3bXta&initcwndbps=1392500&ip=2003%3Ade%3Aaf1e%3A8a00%3A84c6%3A28f3%3A9de2%3A464&itag=251&keepalive=yes&lmt=1659767033119964&lsig=AG3C_xAwRAIgLFPuLqOoHoNQax15AE9Q2YIZ7pM7-olbGWgYGv1MDccCIADKSc_HeOdmD7CDs4AkY5ZtWF4gdZd4rw99Cqlzakbk&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=wB&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jeener%2Csn-h0jeln7l&ms=au%2Crdu&mt=1661460078&mv=m&mvi=4&n=LwUYrFgbIVPzmA&ns=bBqoZtLH6lsaX8ke0xgRMM8H&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIhAKtzVVyoS46hkuKX31EyUE6X6Q5wotcToOCnYKswX3x_AiB0G2SUdVoso39bYgewd3zT8Pf77DrVtahXh4kVb46T9g%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cxtags%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-Khmjdu08WYG7DxAg_8xq0R2u5a6w&txp=4532434&vprv=1&xtags=lang%3Dfr"))]
|
||||
#[case::br_fallback(Filter::default().audio_max_bitrate(0).to_owned(), Some("https://rr4---sn-h0jeener.googlevideo.com/videoplayback?c=WEB&clen=6297404&dur=1012.661&ei=498HY6KvArqM6dsPiN6QgAE&expire=1661482051&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AK8GbbQovVxldcBz4pkXu4EA9N2sU-4yPPa5hFT3bXta&initcwndbps=1392500&ip=2003%3Ade%3Aaf1e%3A8a00%3A84c6%3A28f3%3A9de2%3A464&itag=249&keepalive=yes&lmt=1659767062297621&lsig=AG3C_xAwRAIgLFPuLqOoHoNQax15AE9Q2YIZ7pM7-olbGWgYGv1MDccCIADKSc_HeOdmD7CDs4AkY5ZtWF4gdZd4rw99Cqlzakbk&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=wB&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jeener%2Csn-h0jeln7l&ms=au%2Crdu&mt=1661460078&mv=m&mvi=4&n=LwUYrFgbIVPzmA&ns=bBqoZtLH6lsaX8ke0xgRMM8H&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRgIhAPm10DeIvOt5Oc7e36cfhPC0ej2PslQqF3-CFVUl5TNfAiEAlgvwjlQK14e_-6j3W_hMvk9KHax8zd5shSVlYSR1P34%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cxtags%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-Khmjdu08WYG7DxAg_8xq0R2u5a6w&txp=4532434&vprv=1&xtags=lang%3Den"))]
|
||||
#[case::lang_fallback(Filter::default().audio_language("xx").to_owned(), Some("https://rr4---sn-h0jeener.googlevideo.com/videoplayback?c=WEB&clen=16104134&dur=1012.661&ei=498HY6KvArqM6dsPiN6QgAE&expire=1661482051&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AK8GbbQovVxldcBz4pkXu4EA9N2sU-4yPPa5hFT3bXta&initcwndbps=1392500&ip=2003%3Ade%3Aaf1e%3A8a00%3A84c6%3A28f3%3A9de2%3A464&itag=251&keepalive=yes&lmt=1659767097097120&lsig=AG3C_xAwRAIgLFPuLqOoHoNQax15AE9Q2YIZ7pM7-olbGWgYGv1MDccCIADKSc_HeOdmD7CDs4AkY5ZtWF4gdZd4rw99Cqlzakbk&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=wB&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jeener%2Csn-h0jeln7l&ms=au%2Crdu&mt=1661460078&mv=m&mvi=4&n=LwUYrFgbIVPzmA&ns=bBqoZtLH6lsaX8ke0xgRMM8H&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIgW4IxGJJFRAwZefvDdDkJfjhN7y3bPmh96BCFuyFn6pwCIQDW6pVnk_DwMC3FcZy5rXNUULMNWLdadScxwuhFTFR84g%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cxtags%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-Khmjdu08WYG7DxAg_8xq0R2u5a6w&txp=4532434&vprv=1&xtags=lang%3Den"))]
|
||||
#[case::noformat(Filter::default().audio_formats(hash_set!()).to_owned(), None)]
|
||||
#[case::nocodec(Filter::default().audio_codecs(hash_set!()).to_owned(), None)]
|
||||
fn t_select_audio_stream(#[case] filter: Filter, #[case] expect_url: Option<&str>) {
|
||||
let selection = PLAYER_ML.select_audio_stream(&filter);
|
||||
|
||||
match expect_url {
|
||||
Some(expect_url) => assert_eq!(selection.unwrap().url, expect_url),
|
||||
None => assert_eq!(selection, None),
|
||||
}
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case::default(Filter::default(), Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=998696577&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=315&keepalive=yes&lmt=1647476955807851&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIfP4IVSo-00_kq_JIkuh032hcLoJzNEhYjvwgLiDpEzQIhALPVrvDBjRwiFddXiAyADmRtYygte4HvlJ3XOrkOf_TR&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"))]
|
||||
#[case::hdr(Filter::default().video_hdr().to_owned(), Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=976824147&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=701&keepalive=yes&lmt=1647469891607029&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fmp4&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRgIhAOax_lAWCW5ENOYxe3gZfBHgHA5oZJPyMlYQFy73t7-pAiEA46J7dsT-1pv9smuoP3Kx5T7c_IJ6cEZN4U9UkSNuT7o%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"))]
|
||||
#[case::resolution(Filter::default().video_max_res(720).to_owned(), Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=76313586&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=302&keepalive=yes&lmt=1647455155369524&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIgW0H1434eh9Axw6zw95qezJB0D2aVd2bxEIs4T5bcfFACIDOjha9WLycp0L188FZyFGa1RBkLPoGrrJOppsaXqwDR&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"))]
|
||||
#[case::resolution_fps(Filter::default().video_max_res(720).video_max_fps(30).to_owned(), Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=47531179&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=247&keepalive=yes&lmt=1647458657499381&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRgIhAMUsmcl1zgbr3YQranPWNV1kcxT5IdEoLL7FTFEDdHHPAiEAhQnrfYMU0A9xZ69MfBujWA4pXtCOQCg2Jn6ve9J_vBQ%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"))]
|
||||
#[case::res_fallback(Filter::default().video_max_res(100).to_owned(), Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=2763284&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=160&keepalive=yes&lmt=1647456833049253&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fmp4&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIgLPNxzLxppSSpnDEHxVblrQ38890NMbGnLXlmxljprfQCIQDn4Ir_sjYh7S3ms-Rynm-K0nJpHpQGYsz1nv4TiqeELQ%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"))]
|
||||
#[case::webm_format(Filter::default().video_formats(hash_set!(VideoFormat::Webm)).to_owned(), Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=998696577&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=315&keepalive=yes&lmt=1647476955807851&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIfP4IVSo-00_kq_JIkuh032hcLoJzNEhYjvwgLiDpEzQIhALPVrvDBjRwiFddXiAyADmRtYygte4HvlJ3XOrkOf_TR&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"))]
|
||||
#[case::vp9_codec(Filter::default().video_codecs(hash_set!(VideoCodec::Vp9)).to_owned(), Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=998696577&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=315&keepalive=yes&lmt=1647476955807851&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIfP4IVSo-00_kq_JIkuh032hcLoJzNEhYjvwgLiDpEzQIhALPVrvDBjRwiFddXiAyADmRtYygte4HvlJ3XOrkOf_TR&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"))]
|
||||
#[case::noformat(Filter::default().video_formats(hash_set!()).to_owned(), None)]
|
||||
#[case::nocodec(Filter::default().video_codecs(hash_set!()).to_owned(), None)]
|
||||
fn t_select_video_only_stream(#[case] filter: Filter, #[case] expect_url: Option<&str>) {
|
||||
let selection = PLAYER_HDR.select_video_only_stream(&filter);
|
||||
|
||||
match expect_url {
|
||||
Some(expect_url) => assert_eq!(selection.unwrap().url, expect_url),
|
||||
None => assert_eq!(selection, None),
|
||||
}
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case::default(
|
||||
Filter::default(),
|
||||
Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=998696577&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=315&keepalive=yes&lmt=1647476955807851&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIfP4IVSo-00_kq_JIkuh032hcLoJzNEhYjvwgLiDpEzQIhALPVrvDBjRwiFddXiAyADmRtYygte4HvlJ3XOrkOf_TR&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"),
|
||||
Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?c=WEB&clen=5199784&dur=313.801&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=251&keepalive=yes&lmt=1647453650291076&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIhALtI3j8ZChpNb0LcyDZ3yosbWnSpqaO0-jKAe_UM_RQyAiAMwrpdeNbJEnQn3q1eveaAcRcNIwy5iJ4fIjeBW_MUfg%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1")
|
||||
)]
|
||||
#[case::webm(
|
||||
Filter::default().video_formats(hash_set!(VideoFormat::Webm)).to_owned(),
|
||||
Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?aitags=133%2C134%2C135%2C136%2C160%2C242%2C243%2C244%2C247%2C278%2C298%2C299%2C302%2C303%2C308%2C315%2C330%2C331%2C332%2C333%2C334%2C335%2C336%2C337%2C394%2C395%2C396%2C397%2C398%2C399%2C400%2C401%2C694%2C695%2C696%2C697%2C698%2C699%2C700%2C701&c=WEB&clen=998696577&dur=313.780&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=315&keepalive=yes&lmt=1647476955807851&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRAIfP4IVSo-00_kq_JIkuh032hcLoJzNEhYjvwgLiDpEzQIhALPVrvDBjRwiFddXiAyADmRtYygte4HvlJ3XOrkOf_TR&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1"),
|
||||
Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?c=WEB&clen=5199784&dur=313.801&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=251&keepalive=yes&lmt=1647453650291076&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIhALtI3j8ZChpNb0LcyDZ3yosbWnSpqaO0-jKAe_UM_RQyAiAMwrpdeNbJEnQn3q1eveaAcRcNIwy5iJ4fIjeBW_MUfg%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1")
|
||||
)]
|
||||
#[case::noaudio(
|
||||
Filter::default().audio_formats(hash_set!()).to_owned(),
|
||||
Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?c=WEB&clen=23544588&dur=313.834&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=18&lmt=1647456546485912&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=video%2Fmp4&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=HWZNhARNT_nJgg&ns=pLFQxzhiCbZ9F2HJmDLveKoH&pl=37&ratebypass=yes&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIgeCEjusAq6p33rH0NHyTAbPIRaaEkjDE32AXBFzDvR-ICIQD0LI8hQVH8oCMWu6OuADzc1FSQhIqYs5RLkxBmObIdsw%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cratebypass%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4530434&vprv=1"),
|
||||
None
|
||||
)]
|
||||
#[case::novideo(
|
||||
Filter::default().no_video().to_owned(),
|
||||
None,
|
||||
Some("https://rr5---sn-h0jelne7.googlevideo.com/videoplayback?c=WEB&clen=5199784&dur=313.801&ei=eckIY72IKcGZ8gOMt6CwDg&expire=1661541849&fexp=24001373%2C24007246&fvip=2&gir=yes&id=o-AOqXE9lVS424yszv6LN5V_gaevdHxenJl-tYNy3Drs6g&initcwndbps=1428750&ip=2003%3Ade%3Aaf05%3A2500%3A5dad%3A319b%3Aca30%3Ae212&itag=251&keepalive=yes&lmt=1647453650291076&lsig=AG3C_xAwRQIhAMioKyc-dqs-6uvAwLViCcCTXKHn9sIbo0cbSSBXGG4kAiBQNsRBAvQrbWdOjZIsQXYrfPEb1KDpE_AlSEGQZXB9uA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&mh=NH&mime=audio%2Fwebm&mm=31%2C29&mn=sn-h0jelne7%2Csn-h0jeenl6&ms=au%2Crdu&mt=1661519833&mv=m&mvi=5&n=Zd7nrOM1B2C6PA&ns=426LxLap5MonJD_YWdS4lSYH&pl=37&rbqsm=fr&requiressl=yes&sig=AOq0QJ8wRQIhALtI3j8ZChpNb0LcyDZ3yosbWnSpqaO0-jKAe_UM_RQyAiAMwrpdeNbJEnQn3q1eveaAcRcNIwy5iJ4fIjeBW_MUfg%3D%3D&source=youtube&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&spc=lT-KhuPtxVzL5-QbZ7S9zNeOHsWTdms&txp=4532434&vprv=1")
|
||||
)]
|
||||
#[case::noformat(Filter::default().audio_formats(hash_set!()).video_formats(hash_set!()).to_owned(), None, None)]
|
||||
fn t_select_video_audio_stream(
|
||||
#[case] filter: Filter,
|
||||
#[case] expect_video_url: Option<&str>,
|
||||
#[case] expect_audio_url: Option<&str>,
|
||||
) {
|
||||
let (video, audio) = PLAYER_HDR.select_video_audio_stream(&filter);
|
||||
|
||||
match expect_video_url {
|
||||
Some(expect_url) => assert_eq!(video.unwrap().url, expect_url),
|
||||
None => assert_eq!(video, None),
|
||||
}
|
||||
|
||||
match expect_audio_url {
|
||||
Some(expect_url) => assert_eq!(audio.unwrap().url, expect_url),
|
||||
None => assert_eq!(audio, None),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in a new issue