From 9c512c3c4dbec0fc3b973536733d61ba61125a92 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Thu, 16 Jan 2025 04:16:40 +0100 Subject: [PATCH] fix: player_from_clients method not send/sync --- src/client/player.rs | 26 ++++++------ tests/youtube.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 12 deletions(-) diff --git a/src/client/player.rs b/src/client/player.rs index b1e808c..c41404f 100644 --- a/src/client/player.rs +++ b/src/client/player.rs @@ -11,7 +11,7 @@ use url::Url; use crate::{ deobfuscate::{DeobfData, Deobfuscator}, - error::{internal::DeobfError, Error, ExtractionError, UnavailabilityReason}, + error::{internal::DeobfError, AuthError, Error, ExtractionError, UnavailabilityReason}, model::{ traits::QualityOrd, AudioCodec, AudioFormat, AudioStream, AudioTrack, DrmLicense, DrmSystem, Frameset, Subtitle, VideoCodec, VideoFormat, VideoPlayer, VideoPlayerDetails, @@ -87,16 +87,18 @@ impl RustyPipeQuery { clients: &[ClientType], ) -> Result { let video_id = video_id.as_ref(); - let mut last_e = Error::Other("no clients".into()); + let mut last_e = None; - let clients_iter: Box> = if self.opts.auth == Some(true) { - Box::new(self.auth_enabled_clients(clients)) - } else { - Box::new(clients.iter().cloned()) - }; + for client in clients { + if self.opts.auth == Some(true) && !self.auth_enabled(*client) { + // If no client has auth enabled, return NoLogin error instead of "no clients" + if last_e.is_none() { + last_e = Some(Error::Auth(AuthError::NoLogin)); + } + continue; + } - for client in clients_iter { - let res = self.player_from_client(video_id, client).await; + let res = self.player_from_client(video_id, *client).await; match res { Ok(res) => return Ok(res), Err(Error::Extraction(e)) => { @@ -118,7 +120,7 @@ impl RustyPipeQuery { } Err(e) => return Err(e), } - last_e = Error::Extraction(e); + last_e = Some(Error::Extraction(e)); } else { return Err(Error::Extraction(e)); } @@ -129,7 +131,7 @@ impl RustyPipeQuery { Err(e) => return Err(e), } } - Err(last_e) + Err(last_e.unwrap_or(Error::Other("no clients".into()))) } /// Get YouTube player data (video/audio streams + basic metadata) using the specified client @@ -193,7 +195,7 @@ impl RustyPipeQuery { ) -> Result { let client_type = self .auth_enabled_client(&[ClientType::Desktop, ClientType::Tv]) - .ok_or(Error::Auth(crate::error::AuthError::NoLogin))?; + .ok_or(Error::Auth(AuthError::NoLogin))?; let request_body = QDrmLicense { drm_system: drm_system.req_param(), video_id, diff --git a/tests/youtube.rs b/tests/youtube.rs index 84ded87..3b41490 100644 --- a/tests/youtube.rs +++ b/tests/youtube.rs @@ -2990,3 +2990,100 @@ fn check_duplicates>(items: &[T]) { .collect::>(); assert_eq!(ids.len(), items.len(), "duplicate items"); } + +/// This is just a static check to make sure all RustyPipe futures can be sent +/// between threads safely. +/// Otherwise this may cause issues when integrating RustyPipe into async projects. +#[allow(unused)] +async fn all_send_and_sync() { + fn send_and_sync(t: T) {} + + let rp = RustyPipe::new(); + send_and_sync(&rp); + send_and_sync(rp.query()); + send_and_sync(rp.user_auth_access_token()); + send_and_sync(rp.user_auth_check_cookie()); + send_and_sync(rp.user_auth_check_login()); + let dc = rp.user_auth_get_code().await.unwrap(); + send_and_sync(rp.user_auth_get_code()); + send_and_sync(rp.user_auth_login(&dc)); + send_and_sync(rp.user_auth_logout()); + send_and_sync(rp.user_auth_remove_cookie()); + send_and_sync(rp.user_auth_set_cookie("")); + send_and_sync(rp.user_auth_set_cookie_txt("")); + send_and_sync(rp.user_auth_wait_for_login(&dc)); + + send_and_sync(rp.query().channel_info("")); + send_and_sync(rp.query().channel_playlists("")); + #[cfg(feature = "rss")] + send_and_sync(rp.query().channel_rss("")); + send_and_sync(rp.query().channel_search("", "")); + send_and_sync(rp.query().channel_videos("")); + send_and_sync(rp.query().channel_videos_order("", ChannelOrder::Latest)); + send_and_sync(rp.query().channel_videos_tab("", ChannelVideoTab::Live)); + send_and_sync(rp.query().channel_videos_tab_order( + "", + ChannelVideoTab::Live, + ChannelOrder::Latest, + )); + send_and_sync( + rp.query() + .drm_license("", rustypipe::model::DrmSystem::Widevine, "", "", &[]), + ); + send_and_sync(rp.query().history()); + send_and_sync(rp.query().history_continuation("", None)); + send_and_sync(rp.query().history_search("")); + send_and_sync(rp.query().liked_videos()); + send_and_sync(rp.query().music_album("")); + send_and_sync(rp.query().music_artist("", false)); + send_and_sync(rp.query().music_artist_albums("", None, None)); + send_and_sync(rp.query().music_new_albums()); + send_and_sync(rp.query().music_charts(None)); + send_and_sync(rp.query().music_details("")); + send_and_sync(rp.query().music_genre("")); + send_and_sync(rp.query().music_genres()); + send_and_sync(rp.query().music_history()); + send_and_sync(rp.query().music_history_continuation("", None)); + send_and_sync(rp.query().music_liked_tracks()); + send_and_sync(rp.query().music_lyrics("")); + send_and_sync(rp.query().music_new_albums()); + send_and_sync(rp.query().music_new_videos()); + send_and_sync(rp.query().music_playlist("")); + send_and_sync(rp.query().music_radio("")); + send_and_sync(rp.query().music_radio_playlist("")); + send_and_sync(rp.query().music_radio_track("")); + send_and_sync(rp.query().music_related("")); + send_and_sync(rp.query().music_saved_albums()); + send_and_sync(rp.query().music_saved_artists()); + send_and_sync(rp.query().music_saved_playlists()); + send_and_sync(rp.query().music_saved_tracks()); + send_and_sync(rp.query().music_search::("", None)); + send_and_sync(rp.query().music_search_albums("")); + send_and_sync(rp.query().music_search_artists("")); + send_and_sync(rp.query().music_search_albums("")); + send_and_sync(rp.query().music_search_main("")); + send_and_sync(rp.query().music_search_playlists("", false)); + send_and_sync(rp.query().music_search_suggestion("")); + send_and_sync(rp.query().music_search_tracks("")); + send_and_sync(rp.query().music_search_users("")); + send_and_sync(rp.query().music_search_videos("")); + send_and_sync(rp.query().player("")); + send_and_sync(rp.query().player_from_client("", ClientType::Desktop)); + send_and_sync(rp.query().player_from_clients("", &[])); + send_and_sync(rp.query().raw(ClientType::Desktop, "", "")); + send_and_sync(rp.query().resolve_string("", false)); + send_and_sync(rp.query().resolve_url("", false)); + send_and_sync(rp.query().saved_playlists()); + send_and_sync(rp.query().search::("")); + send_and_sync( + rp.query() + .search_filter::("", &SearchFilter::default()), + ); + send_and_sync(rp.query().search_suggestion("")); + send_and_sync(rp.query().subscription_feed()); + send_and_sync(rp.query().subscriptions()); + send_and_sync(rp.query().trending()); + send_and_sync(rp.query().video_comments("", None)); + send_and_sync(rp.query().video_details("")); + send_and_sync(rp.query().watch_later()); +}