diff --git a/src/crunchyroll.rs b/src/crunchyroll.rs index 1578a23..765c066 100644 --- a/src/crunchyroll.rs +++ b/src/crunchyroll.rs @@ -383,7 +383,7 @@ mod auth { let endpoint = "https://www.crunchyroll.com/auth/v1/token"; let resp = client .post(endpoint) - .header(header::AUTHORIZATION, "Basic YWNmYWZtNTE3aGtpZWt4Yl93bWU6MDluclZfejBUNWxVdjRyRHp5ZlJYZk0wVmlIRHQyQV8=") + .header(header::AUTHORIZATION, "Basic dC1rZGdwMmg4YzNqdWI4Zm4wZnE6eWZMRGZNZnJZdktYaDRKWFMxTEVJMmNDcXUxdjVXYW4=") .header(header::CONTENT_TYPE, "application/x-www-form-urlencoded") .header("ETP-Anonymous-ID", uuid::Uuid::new_v4().to_string()) .body( @@ -411,7 +411,7 @@ mod auth { ("username", email.as_ref()), ("password", password.as_ref()), ("grant_type", "password"), - ("scope", "offline_access mp"), + ("scope", "offline_access"), ]; if let Some(d_id) = &device_id { body.extend_from_slice(&[("device_id", d_id)]) @@ -420,7 +420,7 @@ mod auth { body.extend_from_slice(&[("device_type", d_type)]) } let resp = client.post(endpoint) - .header(header::AUTHORIZATION, "Basic YWNmYWZtNTE3aGtpZWt4Yl93bWU6MDluclZfejBUNWxVdjRyRHp5ZlJYZk0wVmlIRHQyQV8=") + .header(header::AUTHORIZATION, "Basic dC1rZGdwMmg4YzNqdWI4Zm4wZnE6eWZMRGZNZnJZdktYaDRKWFMxTEVJMmNDcXUxdjVXYW4=") .header(header::CONTENT_TYPE, "application/x-www-form-urlencoded") .body(serde_urlencoded::to_string(body).unwrap()) .send() @@ -448,7 +448,7 @@ mod auth { body.extend_from_slice(&[("device_type", d_type)]) } let resp = client.post(endpoint) - .header(header::AUTHORIZATION, "Basic YWNmYWZtNTE3aGtpZWt4Yl93bWU6MDluclZfejBUNWxVdjRyRHp5ZlJYZk0wVmlIRHQyQV8=") + .header(header::AUTHORIZATION, "Basic dC1rZGdwMmg4YzNqdWI4Zm4wZnE6eWZMRGZNZnJZdktYaDRKWFMxTEVJMmNDcXUxdjVXYW4=") .header(header::CONTENT_TYPE, "application/x-www-form-urlencoded") .body(serde_urlencoded::to_string(body).unwrap()) .send() @@ -478,7 +478,7 @@ mod auth { body.extend_from_slice(&[("device_type", d_type)]) } let resp = client.post(endpoint) - .header(header::AUTHORIZATION, "Basic YWNmYWZtNTE3aGtpZWt4Yl93bWU6MDluclZfejBUNWxVdjRyRHp5ZlJYZk0wVmlIRHQyQV8=") + .header(header::AUTHORIZATION, "Basic dC1rZGdwMmg4YzNqdWI4Zm4wZnE6eWZMRGZNZnJZdktYaDRKWFMxTEVJMmNDcXUxdjVXYW4=") .header(header::CONTENT_TYPE, "application/x-www-form-urlencoded") .body(serde_urlencoded::to_string(body).unwrap()) .send() @@ -859,10 +859,6 @@ mod auth { /// [`CrunchyrollBuilder::login_with_refresh_token`] are having the same syntax, Crunchyroll /// internal they're different. I had issues when I tried to log in with the `etp_rt` /// cookie on [`CrunchyrollBuilder::login_with_refresh_token`] and vice versa. - /// - /// *Note*: When using this method to login, any request to - /// [`crate::Episode::stream_maybe_without_drm`] / [`crate::Movie::stream_maybe_without_drm`] - /// will fail. pub async fn login_with_etp_rt>(self, etp_rt: S) -> Result { self.pre_login().await?; diff --git a/src/lib.rs b/src/lib.rs index d0be32c..2027ef0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,10 +56,10 @@ //! //! ## Streaming //! -//! This crate allows you to get the actual video streams behind episodes and movies. With -//! [`Episode::stream_maybe_without_drm`] and [`Movie::stream_maybe_without_drm`] you get access to -//! the streams. At the time of writing these streams are DRM free but this might change at any time. -//! The returning struct [`media::Stream`] has all required information to access the streams. +//! _All streams are DRM protected. The library does not contain logic to decrypt it, so if you want +//! to do this, you have to implement it yourself._ +//! +//! This crate allows you to get the actual video streams behind episodes and movies. //! //! ``` //! let stream = episode diff --git a/src/media/anime/impl.rs b/src/media/anime/impl.rs index d956266..2fdc3f2 100644 --- a/src/media/anime/impl.rs +++ b/src/media/anime/impl.rs @@ -330,14 +330,7 @@ macro_rules! impl_media_video { /// All streams are drm encrypted, decryption is not handled in this crate, so you /// must do this yourself. pub async fn stream(&self) -> Result<$crate::media::Stream> { - $crate::media::Stream::from_id_drm(&$crate::Crunchyroll { executor: self.executor.clone() }, &self.id, None).await - } - - /// Streams for this episode / movie. - /// Unlike [`Self::stream`] the streams may not be DRM encrypted (at least at the - /// time of writing they aren't but this might change at any time). - pub async fn stream_maybe_without_drm(&self) -> Result<$crate::media::Stream> { - $crate::media::Stream::from_id_maybe_without_drm(&$crate::Crunchyroll { executor: self.executor.clone() }, &self.id, None).await + $crate::media::Stream::from_id_web_chrome(&$crate::Crunchyroll { executor: self.executor.clone() }, &self.id, None).await } /// Check if the episode / movie can be watched. diff --git a/src/media/music/impl.rs b/src/media/music/impl.rs index b20a42f..854f39e 100644 --- a/src/media/music/impl.rs +++ b/src/media/music/impl.rs @@ -28,14 +28,7 @@ macro_rules! impl_media_music { /// All streams are drm encrypted, decryption is not handled in this crate, so you /// must do this yourself. pub async fn stream(&self) -> Result<$crate::media::Stream> { - $crate::media::Stream::from_id_drm(&$crate::Crunchyroll { executor: self.executor.clone() }, &self.id, Some("music".to_string())).await - } - - /// Streams for this episode / movie. - /// Unlike [`Self::stream`] the streams may not be DRM encrypted (at least at the - /// time of writing they aren't but this might change at any time). - pub async fn stream_maybe_without_drm(&self) -> Result<$crate::media::Stream> { - $crate::media::Stream::from_id_maybe_without_drm(&$crate::Crunchyroll { executor: self.executor.clone() }, &self.id, None).await + $crate::media::Stream::from_id_web_chrome(&$crate::Crunchyroll { executor: self.executor.clone() }, &self.id, Some("music".to_string())).await } /// Check if the music video / concert can be watched. diff --git a/src/media/stream.rs b/src/media/stream.rs index b424b76..e01b2cd 100644 --- a/src/media/stream.rs +++ b/src/media/stream.rs @@ -127,8 +127,8 @@ pub struct Stream { } impl Stream { - /// Requests a stream from an id with is always DRM encrypted. - pub async fn from_id_drm( + /// Requests a stream from an id via the chrome endpoint. + pub async fn from_id_web_chrome( crunchyroll: &Crunchyroll, id: impl AsRef, optional_media_type: Option, @@ -136,17 +136,6 @@ impl Stream { Self::from_id(crunchyroll, id, "web", "chrome", optional_media_type).await } - /// Requests a stream from an id with is maybe DRM free. Check - /// [`Stream::session::uses_stream_limits`], if its `true`, the stream is DRM encrypted, if - /// `false` not. - pub async fn from_id_maybe_without_drm( - crunchyroll: &Crunchyroll, - id: impl AsRef, - optional_media_type: Option, - ) -> Result { - Self::from_id(crunchyroll, id, "console", "switch", optional_media_type).await - } - async fn from_id( crunchyroll: &Crunchyroll, id: impl AsRef, diff --git a/tests/test_stream.rs b/tests/test_stream.rs index 1de8c57..a55e472 100644 --- a/tests/test_stream.rs +++ b/tests/test_stream.rs @@ -7,7 +7,7 @@ use std::io::Write; mod utils; -static STREAM_DRM: Store = Store::new(|| { +static STREAM: Store = Store::new(|| { Box::pin(async { let crunchy = SESSION.get().await?; let stream = Episode::from_id(crunchy, "GRDKJZ81Y") @@ -18,63 +18,38 @@ static STREAM_DRM: Store = Store::new(|| { }) }); -static STREAM_DATA_DRM: Store = Store::new(|| { +static STREAM_DATA: Store = Store::new(|| { Box::pin(async { - let stream = STREAM_DRM.get().await?; + let stream = STREAM.get().await?; Ok(stream.stream_data(None).await?.unwrap().0.remove(0)) }) }); -static STREAM_SEGMENTS_DRM: Store> = Store::new(|| { +static STREAM_SEGMENTS: Store> = Store::new(|| { Box::pin(async { - let stream_data = STREAM_DATA_DRM.get().await?; - Ok(stream_data.segments()) - }) -}); - -static STREAM_MAYBE_WITHOUT_DRM: Store = Store::new(|| { - Box::pin(async { - let crunchy = SESSION.get().await?; - let stream = Episode::from_id(crunchy, "GRDKJZ81Y") - .await? - .stream_maybe_without_drm() - .await?; - Ok(stream) - }) -}); - -static STREAM_DATA_MAYBE_WITHOUT_DRM: Store = Store::new(|| { - Box::pin(async { - let stream = STREAM_MAYBE_WITHOUT_DRM.get().await?; - Ok(stream.stream_data(None).await?.unwrap().0.remove(0)) - }) -}); - -static STREAM_SEGMENTS_MAYBE_WITHOUT_DRM: Store> = Store::new(|| { - Box::pin(async { - let stream_data = STREAM_DATA_MAYBE_WITHOUT_DRM.get().await?; + let stream_data = STREAM_DATA.get().await?; Ok(stream_data.segments()) }) }); #[tokio::test] -async fn stream_from_id_drm() { - assert_result!(STREAM_DRM.get().await) +async fn stream_from_id() { + assert_result!(STREAM.get().await) } #[tokio::test] -async fn stream_data_drm() { - assert_result!(STREAM_DATA_DRM.get().await) +async fn stream_data() { + assert_result!(STREAM_DATA.get().await) } #[tokio::test] -async fn stream_segments_drm() { - assert_result!(STREAM_SEGMENTS_DRM.get().await) +async fn stream_segments() { + assert_result!(STREAM_SEGMENTS.get().await) } #[tokio::test] -async fn process_segments_drm() { - let segments = STREAM_SEGMENTS_DRM.get().await.unwrap(); +async fn process_segments() { + let segments = STREAM_SEGMENTS.get().await.unwrap(); let sink = &mut std::io::sink(); @@ -99,63 +74,3 @@ async fn process_segments_drm() { async fn stream_versions_drm() { assert_result!(STREAM_DRM.get().await.unwrap().versions().await) }*/ - -#[tokio::test] -async fn stream_from_id_maybe_without_drm() { - assert_result!(STREAM_MAYBE_WITHOUT_DRM.get().await) -} - -#[tokio::test] -async fn stream_data_maybe_without_drm() { - assert_result!(STREAM_DATA_MAYBE_WITHOUT_DRM.get().await) -} - -#[tokio::test] -async fn stream_segments_maybe_without_drm() { - assert_result!(STREAM_SEGMENTS_MAYBE_WITHOUT_DRM.get().await) -} - -#[tokio::test] -async fn process_segments_maybe_without_drm() { - let segments = STREAM_SEGMENTS_MAYBE_WITHOUT_DRM.get().await.unwrap(); - - let sink = &mut std::io::sink(); - - // stream 10 random segments. - // if the test passes, it's unlikely that some error will occur when streaming all segments ( - // and if it does, hopefully someone using this in production will report it) - for _ in 0..10 { - sink.write( - &segments - .choose(&mut rand::thread_rng()) - .unwrap() - .data() - .await - .unwrap(), - ) - .unwrap(); - } -} - -// will throw a too many active streams error -/*#[tokio::test] -async fn stream_versions_maybe_without_drm() { - assert_result!( - STREAM_MAYBE_WITHOUT_DRM - .get() - .await - .unwrap() - .versions() - .await - ) -}*/ - -#[tokio::test] -async fn stream_maybe_without_drm_is_really_drm_free() { - assert!(STREAM_DATA_MAYBE_WITHOUT_DRM - .get() - .await - .unwrap() - .drm - .is_none()) -}