diff --git a/cli/src/main.rs b/cli/src/main.rs index 67d36fb..b48bca3 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -272,7 +272,6 @@ enum ClientTypeArg { Desktop, Mobile, Tv, - TvEmbed, Android, Ios, } @@ -324,7 +323,6 @@ impl From for ClientType { match value { ClientTypeArg::Desktop => Self::Desktop, ClientTypeArg::Mobile => Self::Mobile, - ClientTypeArg::TvEmbed => Self::TvHtml5Embed, ClientTypeArg::Tv => Self::Tv, ClientTypeArg::Android => Self::Android, ClientTypeArg::Ios => Self::Ios, diff --git a/codegen/src/download_testfiles.rs b/codegen/src/download_testfiles.rs index 1a580d2..22e4c8c 100644 --- a/codegen/src/download_testfiles.rs +++ b/codegen/src/download_testfiles.rs @@ -64,11 +64,10 @@ pub async fn download_testfiles() { music_genre().await; } -const CLIENT_TYPES: [ClientType; 6] = [ +const CLIENT_TYPES: [ClientType; 5] = [ ClientType::Desktop, ClientType::DesktopMusic, ClientType::Tv, - ClientType::TvHtml5Embed, ClientType::Android, ClientType::Ios, ]; diff --git a/src/client/mod.rs b/src/client/mod.rs index 14eade2..cc4aa7b 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -65,11 +65,6 @@ pub enum ClientType { /// - includes lower resolution audio streams /// - does not return audio tracks in different languages Mobile, - /// Client used by the embedded player for Smart TVs - /// - /// - can access age-restricted videos - /// - cannot access non-embeddable videos - TvHtml5Embed, /// Client used by youtube.com/tv /// /// - Does not return video metadata when fetching the player @@ -92,7 +87,6 @@ impl ClientType { ClientType::Desktop | ClientType::DesktopMusic | ClientType::Mobile - | ClientType::TvHtml5Embed | ClientType::Tv => true, ClientType::Android | ClientType::Ios => false, } @@ -223,7 +217,6 @@ const DESKTOP_CLIENT_VERSION: &str = "2.20241010.09.00"; const DESKTOP_MUSIC_CLIENT_VERSION: &str = "1.20241007.00.00"; const MOBILE_CLIENT_VERSION: &str = "2.20241011.01.00"; const TV_CLIENT_VERSION: &str = "7.20241008.14.02"; -const TVHTML5_CLIENT_VERSION: &str = "2.0"; // Mobile app client const APP_CLIENT_VERSION: &str = "18.03.33"; @@ -1109,7 +1102,7 @@ impl RustyPipeQuery { /// This can be used for additional HTTP requests (e.g. downloading/streaming) pub fn user_agent(&self, ctype: ClientType) -> Cow<'_, str> { match ctype { - ClientType::Desktop | ClientType::DesktopMusic | ClientType::TvHtml5Embed => { + ClientType::Desktop | ClientType::DesktopMusic => { Cow::Borrowed(&self.client.inner.user_agent) } ClientType::Mobile => MOBILE_UA.into(), @@ -1192,23 +1185,6 @@ impl RustyPipeQuery { user: User::default(), third_party: None, }, - ClientType::TvHtml5Embed => YTContext { - client: ClientInfo { - client_name: "TVHTML5_SIMPLY_EMBEDDED_PLAYER", - client_version: TVHTML5_CLIENT_VERSION.into(), - client_screen: Some("EMBED"), - platform: "TV", - visitor_data, - hl, - gl, - ..Default::default() - }, - request: Some(RequestYT::default()), - user: User::default(), - third_party: Some(ThirdParty { - embed_url: YOUTUBE_HOME_URL, - }), - }, ClientType::Tv => YTContext { client: ClientInfo { client_name: "TVHTML5", @@ -1319,17 +1295,6 @@ impl RustyPipeQuery { "X-YouTube-Client-Version", self.client.get_client_version(ctype).await.into_owned(), ), - ClientType::TvHtml5Embed => self - .client - .inner - .http - .post(format!( - "{YOUTUBEI_V1_URL}{endpoint}?{DISABLE_PRETTY_PRINT_PARAMETER}" - )) - .header(header::ORIGIN, YOUTUBE_HOME_URL) - .header(header::REFERER, YOUTUBE_HOME_URL) - .header("X-YouTube-Client-Name", "1") - .header("X-YouTube-Client-Version", TVHTML5_CLIENT_VERSION), ClientType::Tv => self .client .inner diff --git a/src/client/player.rs b/src/client/player.rs index 9b48d54..6a6e8a6 100644 --- a/src/client/player.rs +++ b/src/client/player.rs @@ -83,33 +83,30 @@ impl RustyPipeQuery { clients: &[ClientType], ) -> Result { let video_id = video_id.as_ref(); - let mut last_e = Error::Other("no clients".into()); + let last_e = Error::Other("no clients".into()); for client in clients { let res = self.player_from_client(video_id, *client).await; match res { Ok(res) => return Ok(res), Err(Error::Extraction(e)) => { - if e.switch_client() { - if let ExtractionError::Unavailable { - reason: UnavailabilityReason::AgeRestricted, - msg, - } = &e - { - if let Ok(res) = self - .player_from_client(video_id, ClientType::TvHtml5Embed) - .await - { - return Ok(res); - } else { - return Err(Error::Extraction(ExtractionError::Unavailable { - reason: UnavailabilityReason::AgeRestricted, - msg: msg.to_owned(), - })); + // TODO: fetch age-restricted videos with login + /* + if e.use_login() { + tracing::info!("{e}; fetching player with login"); + + match self.player_from_client(video_id, *client).await { + Ok(res) => return Ok(res), + Err(Error::Extraction(e)) => { + if !e.switch_client() { + return Err(Error::Extraction(e)); + } } + Err(e) => return Err(e), } last_e = Error::Extraction(e); - } else { + } else*/ + if !e.switch_client() { return Err(Error::Extraction(e)); } } @@ -747,7 +744,6 @@ mod tests { #[case::desktop(ClientType::Desktop)] #[case::desktop_music(ClientType::DesktopMusic)] #[case::tv(ClientType::Tv)] - #[case::tv_html5_embed(ClientType::TvHtml5Embed)] #[case::android(ClientType::Android)] #[case::ios(ClientType::Ios)] fn map_player_data(#[case] client_type: ClientType) { diff --git a/src/error.rs b/src/error.rs index ae804d8..f585f28 100644 --- a/src/error.rs +++ b/src/error.rs @@ -213,10 +213,20 @@ impl ExtractionError { matches!( self, ExtractionError::Unavailable { - reason: UnavailabilityReason::AgeRestricted - | UnavailabilityReason::UnsupportedClient, + reason: UnavailabilityReason::UnsupportedClient, .. } | ExtractionError::WrongResult(_) ) } + + /// Return true if the video should be fetched as a logged in user + pub(crate) fn use_login(&self) -> bool { + matches!( + self, + ExtractionError::Unavailable { + reason: UnavailabilityReason::AgeRestricted | UnavailabilityReason::IpBan, + .. + } + ) + } } diff --git a/tests/youtube.rs b/tests/youtube.rs index d0b5cb4..dfc1700 100644 --- a/tests/youtube.rs +++ b/tests/youtube.rs @@ -29,7 +29,6 @@ use rustypipe::validate; #[case::desktop(ClientType::Desktop)] #[case::tv(ClientType::Tv)] #[case::mobile(ClientType::Mobile)] -#[case::tv_html5_embed(ClientType::TvHtml5Embed)] #[case::android(ClientType::Android)] #[case::ios(ClientType::Ios)] #[tokio::test] @@ -222,6 +221,8 @@ async fn check_video_stream(s: impl YtStream) { false, true )] +/* +TODO: add login #[case::agelimit( "ZDKQmBWTRnw", "The Rinky Pink Pounder. Hitachi Magic Wand clone teardown.", @@ -233,6 +234,7 @@ async fn check_video_stream(s: impl YtStream) { false, false )] +*/ #[tokio::test] #[allow(clippy::too_many_arguments)] async fn get_player(