From 85cac83070972f10f20357da15bfcd400eb213cc Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 30 Nov 2022 11:58:48 +0100 Subject: [PATCH 1/2] fix!: use arrays instead of HashSets for stream filter --- Cargo.toml | 1 - src/download.rs | 2 +- src/param/stream_filter.rs | 51 +++++++++++++++++++------------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a02243d..ea67285 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,4 +61,3 @@ rstest = "0.16.0" temp_testdir = "0.2.3" insta = { version = "1.17.1", features = ["ron", "redactions"] } path_macro = "1.0.0" -velcro = "0.5.3" diff --git a/src/download.rs b/src/download.rs index 00738c9..238e9ab 100644 --- a/src/download.rs +++ b/src/download.rs @@ -292,7 +292,7 @@ pub async fn download_video( output_dir: &str, output_fname: Option, output_format: Option, - filter: &StreamFilter, + filter: &StreamFilter<'_>, ffmpeg: &str, http: Client, pb: ProgressBar, diff --git a/src/param/stream_filter.rs b/src/param/stream_filter.rs index c33420e..5067757 100644 --- a/src/param/stream_filter.rs +++ b/src/param/stream_filter.rs @@ -1,6 +1,6 @@ //! Filters for selecting audio/video streams -use std::{cmp::Ordering, collections::HashSet}; +use std::cmp::Ordering; use crate::model::{ AudioCodec, AudioFormat, AudioStream, QualityOrd, VideoCodec, VideoFormat, VideoPlayer, @@ -8,15 +8,15 @@ use crate::model::{ }; #[derive(Debug, Default, Clone)] -pub struct StreamFilter { +pub struct StreamFilter<'a> { audio_max_bitrate: Option, - audio_formats: Option>, - audio_codecs: Option>, - audio_language: Option, + audio_formats: Option<&'a [AudioFormat]>, + audio_codecs: Option<&'a [AudioCodec]>, + audio_language: Option<&'a str>, video_max_res: Option, video_max_fps: Option, - video_formats: Option>, - video_codecs: Option>, + video_formats: Option<&'a [VideoFormat]>, + video_codecs: Option<&'a [VideoCodec]>, video_hdr: bool, video_none: bool, } @@ -59,7 +59,7 @@ impl FilterResult { } } -impl StreamFilter { +impl<'a> StreamFilter<'a> { /// Set the maximum audio bitrate in bits per second. /// /// This is a soft filter, so if there is no stream with a bitrate @@ -77,7 +77,7 @@ impl StreamFilter { } /// Set the supported audio container formats - pub fn audio_formats(&mut self, formats: HashSet) -> &mut Self { + pub fn audio_formats(&mut self, formats: &'a [AudioFormat]) -> &mut Self { self.audio_formats = Some(formats); self } @@ -90,7 +90,7 @@ impl StreamFilter { } /// Set the supported audio codecs - pub fn audio_codecs(&mut self, codecs: HashSet) -> &mut Self { + pub fn audio_codecs(&mut self, codecs: &'a [AudioCodec]) -> &mut Self { self.audio_codecs = Some(codecs); self } @@ -108,8 +108,8 @@ impl StreamFilter { /// /// 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()); + pub fn audio_language(&mut self, language: &'a str) -> &mut Self { + self.audio_language = Some(language); self } @@ -163,7 +163,7 @@ impl StreamFilter { } /// Set the supported video container formats - pub fn video_formats(&mut self, formats: HashSet) -> &mut Self { + pub fn video_formats(&mut self, formats: &'a [VideoFormat]) -> &mut Self { self.video_formats = Some(formats); self } @@ -176,7 +176,7 @@ impl StreamFilter { } /// Set the supported video codecs - pub fn video_codecs(&mut self, codecs: HashSet) -> &mut Self { + pub fn video_codecs(&mut self, codecs: &'a [VideoCodec]) -> &mut Self { self.video_codecs = Some(codecs); self } @@ -324,7 +324,6 @@ mod tests { use once_cell::sync::Lazy; use path_macro::path; use rstest::rstest; - use velcro::hash_set; static PLAYER_ML: Lazy = Lazy::new(|| { let json_path = path!("testfiles" / "player_model" / "multilanguage.json"); @@ -343,13 +342,13 @@ mod tests { #[rstest] #[case::default(StreamFilter::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(StreamFilter::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(StreamFilter::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(StreamFilter::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::m4a_format(StreamFilter::default().audio_formats(&[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(StreamFilter::default().audio_codecs(&[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(StreamFilter::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(StreamFilter::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(StreamFilter::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(StreamFilter::default().audio_formats(hash_set!()).to_owned(), None)] - #[case::nocodec(StreamFilter::default().audio_codecs(hash_set!()).to_owned(), None)] + #[case::noformat(StreamFilter::default().audio_formats(&[]).to_owned(), None)] + #[case::nocodec(StreamFilter::default().audio_codecs(&[]).to_owned(), None)] fn t_select_audio_stream(#[case] filter: StreamFilter, #[case] expect_url: Option<&str>) { let selection = PLAYER_ML.select_audio_stream(&filter); @@ -365,10 +364,10 @@ mod tests { #[case::resolution(StreamFilter::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(StreamFilter::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(StreamFilter::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(StreamFilter::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(StreamFilter::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(StreamFilter::default().video_formats(hash_set!()).to_owned(), None)] - #[case::nocodec(StreamFilter::default().video_codecs(hash_set!()).to_owned(), None)] + #[case::webm_format(StreamFilter::default().video_formats(&[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(StreamFilter::default().video_codecs(&[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(StreamFilter::default().video_formats(&[]).to_owned(), None)] + #[case::nocodec(StreamFilter::default().video_codecs(&[]).to_owned(), None)] fn t_select_video_only_stream(#[case] filter: StreamFilter, #[case] expect_url: Option<&str>) { let selection = PLAYER_HDR.select_video_only_stream(&filter); @@ -385,12 +384,12 @@ mod tests { 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( - StreamFilter::default().video_formats(hash_set!(VideoFormat::Webm)).to_owned(), + StreamFilter::default().video_formats(&[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( - StreamFilter::default().audio_formats(hash_set!()).to_owned(), + StreamFilter::default().audio_formats(&[]).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 )] @@ -399,7 +398,7 @@ mod tests { 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(StreamFilter::default().audio_formats(hash_set!()).video_formats(hash_set!()).to_owned(), None, None)] + #[case::noformat(StreamFilter::default().audio_formats(&[]).video_formats(&[]).to_owned(), None, None)] fn t_select_video_audio_stream( #[case] filter: StreamFilter, #[case] expect_video_url: Option<&str>, From 94b55711cbaa289d6ba4aa4b7f0cc8d2ad3e5506 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 30 Nov 2022 12:42:06 +0100 Subject: [PATCH 2/2] fix: use AsRef generics for pagination --- codegen/src/download_testfiles.rs | 24 ++++++------ src/client/mod.rs | 6 +++ src/client/pagination.rs | 37 ++++++++++++------- tests/youtube.rs | 61 ++++++++++++++----------------- 4 files changed, 68 insertions(+), 60 deletions(-) diff --git a/codegen/src/download_testfiles.rs b/codegen/src/download_testfiles.rs index d3a1493..18df8ef 100644 --- a/codegen/src/download_testfiles.rs +++ b/codegen/src/download_testfiles.rs @@ -208,7 +208,7 @@ async fn playlist_cont(testfiles: &Path) { .unwrap(); let rp = rp_testfile(&json_path); - playlist.videos.next(&rp.query()).await.unwrap().unwrap(); + playlist.videos.next(rp.query()).await.unwrap().unwrap(); } async fn video_details(testfiles: &Path) { @@ -246,7 +246,7 @@ async fn comments_top(testfiles: &Path) { let rp = rp_testfile(&json_path); details .top_comments - .next(&rp.query()) + .next(rp.query()) .await .unwrap() .unwrap(); @@ -266,7 +266,7 @@ async fn comments_latest(testfiles: &Path) { let rp = rp_testfile(&json_path); details .latest_comments - .next(&rp.query()) + .next(rp.query()) .await .unwrap() .unwrap(); @@ -284,7 +284,7 @@ async fn recommendations(testfiles: &Path) { let details = rp.query().video_details("ZeerrnuLi5E").await.unwrap(); let rp = rp_testfile(&json_path); - details.recommended.next(&rp.query()).await.unwrap(); + details.recommended.next(rp.query()).await.unwrap(); } async fn channel_videos(testfiles: &Path) { @@ -384,7 +384,7 @@ async fn channel_videos_cont(testfiles: &Path) { .unwrap(); let rp = rp_testfile(&json_path); - videos.content.next(&rp.query()).await.unwrap().unwrap(); + videos.content.next(rp.query()).await.unwrap().unwrap(); } async fn channel_playlists_cont(testfiles: &Path) { @@ -403,7 +403,7 @@ async fn channel_playlists_cont(testfiles: &Path) { .unwrap(); let rp = rp_testfile(&json_path); - playlists.content.next(&rp.query()).await.unwrap().unwrap(); + playlists.content.next(rp.query()).await.unwrap().unwrap(); } async fn search(testfiles: &Path) { @@ -430,7 +430,7 @@ async fn search_cont(testfiles: &Path) { let search = rp.query().search("doobydoobap").await.unwrap(); let rp = rp_testfile(&json_path); - search.items.next(&rp.query()).await.unwrap().unwrap(); + search.items.next(rp.query()).await.unwrap().unwrap(); } async fn search_playlists(testfiles: &Path) { @@ -492,7 +492,7 @@ async fn startpage_cont(testfiles: &Path) { let startpage = rp.query().startpage().await.unwrap(); let rp = rp_testfile(&json_path); - startpage.next(&rp.query()).await.unwrap(); + startpage.next(rp.query()).await.unwrap(); } async fn trending(testfiles: &Path) { @@ -541,7 +541,7 @@ async fn music_playlist_cont(testfiles: &Path) { .unwrap(); let rp = rp_testfile(&json_path); - playlist.tracks.next(&rp.query()).await.unwrap().unwrap(); + playlist.tracks.next(rp.query()).await.unwrap().unwrap(); } async fn music_playlist_related(testfiles: &Path) { @@ -562,7 +562,7 @@ async fn music_playlist_related(testfiles: &Path) { let rp = rp_testfile(&json_path); playlist .related_playlists - .next(&rp.query()) + .next(rp.query()) .await .unwrap() .unwrap(); @@ -688,7 +688,7 @@ async fn music_search_cont(testfiles: &Path) { let res = rp.query().music_search_tracks("black mamba").await.unwrap(); let rp = rp_testfile(&json_path); - res.items.next(&rp.query()).await.unwrap().unwrap(); + res.items.next(rp.query()).await.unwrap().unwrap(); } async fn music_search_suggestion(testfiles: &Path) { @@ -801,7 +801,7 @@ async fn music_radio_cont(testfiles: &Path) { let res = rp.query().music_radio("RDAMVM7nigXQS1Xb0").await.unwrap(); let rp = rp_testfile(&json_path); - res.next(&rp.query()).await.unwrap().unwrap(); + res.next(rp.query()).await.unwrap().unwrap(); } async fn music_new_albums(testfiles: &Path) { diff --git a/src/client/mod.rs b/src/client/mod.rs index 5b26b44..3b82f4f 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -1164,6 +1164,12 @@ impl RustyPipeQuery { } } +impl AsRef for RustyPipeQuery { + fn as_ref(&self) -> &RustyPipeQuery { + self + } +} + /// Implement this for YouTube API response structs that need to be mapped to /// RustyPipe models. trait MapResponse { diff --git a/src/client/pagination.rs b/src/client/pagination.rs index 5ec9e7e..702b7a6 100644 --- a/src/client/pagination.rs +++ b/src/client/pagination.rs @@ -176,10 +176,11 @@ impl MapResponse> for response::MusicContinuation { } impl Paginator { - pub async fn next(&self, query: &RustyPipeQuery) -> Result, Error> { + pub async fn next>(&self, query: Q) -> Result, Error> { Ok(match &self.ctoken { Some(ctoken) => Some( query + .as_ref() .continuation(ctoken, self.endpoint, self.visitor_data.as_deref()) .await?, ), @@ -187,7 +188,7 @@ impl Paginator { }) } - pub async fn extend(&mut self, query: &RustyPipeQuery) -> Result { + pub async fn extend>(&mut self, query: Q) -> Result { match self.next(query).await { Ok(Some(paginator)) => { let mut items = paginator.items; @@ -200,11 +201,12 @@ impl Paginator { } } - pub async fn extend_pages( + pub async fn extend_pages>( &mut self, - query: &RustyPipeQuery, + query: Q, n_pages: usize, ) -> Result<(), Error> { + let query = query.as_ref(); for _ in 0..n_pages { match self.extend(query).await { Ok(false) => break, @@ -215,11 +217,12 @@ impl Paginator { Ok(()) } - pub async fn extend_limit( + pub async fn extend_limit>( &mut self, - query: &RustyPipeQuery, + query: Q, n_items: usize, ) -> Result<(), Error> { + let query = query.as_ref(); while self.items.len() < n_items { match self.extend(query).await { Ok(false) => break, @@ -232,10 +235,11 @@ impl Paginator { } impl Paginator { - pub async fn next(&self, query: &RustyPipeQuery) -> Result, Error> { + pub async fn next>(&self, query: Q) -> Result, Error> { Ok(match &self.ctoken { Some(ctoken) => Some( query + .as_ref() .video_comments(ctoken, self.visitor_data.as_deref()) .await?, ), @@ -245,9 +249,9 @@ impl Paginator { } impl Paginator { - pub async fn next(&self, query: &RustyPipeQuery) -> Result, Error> { + pub async fn next>(&self, query: Q) -> Result, Error> { Ok(match &self.ctoken { - Some(ctoken) => Some(query.playlist_continuation(ctoken).await?), + Some(ctoken) => Some(query.as_ref().playlist_continuation(ctoken).await?), None => None, }) } @@ -256,7 +260,10 @@ impl Paginator { macro_rules! paginator { ($entity_type:ty) => { impl Paginator<$entity_type> { - pub async fn extend(&mut self, query: &RustyPipeQuery) -> Result { + pub async fn extend>( + &mut self, + query: Q, + ) -> Result { match self.next(query).await { Ok(Some(paginator)) => { let mut items = paginator.items; @@ -269,11 +276,12 @@ macro_rules! paginator { } } - pub async fn extend_pages( + pub async fn extend_pages>( &mut self, - query: &RustyPipeQuery, + query: Q, n_pages: usize, ) -> Result<(), Error> { + let query = query.as_ref(); for _ in 0..n_pages { match self.extend(query).await { Ok(false) => break, @@ -284,11 +292,12 @@ macro_rules! paginator { Ok(()) } - pub async fn extend_limit( + pub async fn extend_limit>( &mut self, - query: &RustyPipeQuery, + query: Q, n_items: usize, ) -> Result<(), Error> { + let query = query.as_ref(); while self.items.len() < n_items { match self.extend(query).await { Ok(false) => break, diff --git a/tests/youtube.rs b/tests/youtube.rs index c662453..9052c7e 100644 --- a/tests/youtube.rs +++ b/tests/youtube.rs @@ -380,7 +380,7 @@ async fn playlist_cont() { playlist .videos - .extend_pages(&rp.query(), usize::MAX) + .extend_pages(rp.query(), usize::MAX) .await .unwrap(); assert!(playlist.videos.items.len() > 100); @@ -396,11 +396,7 @@ async fn playlist_cont2() { .await .unwrap(); - playlist - .videos - .extend_limit(&rp.query(), 101) - .await - .unwrap(); + playlist.videos.extend_limit(rp.query(), 101).await.unwrap(); assert!(playlist.videos.items.len() > 100); assert!(playlist.videos.count.unwrap() > 100); } @@ -461,7 +457,7 @@ async fn get_video_details() { assert!(!details.is_ccommons); assert!(details.recommended.visitor_data.is_some()); - assert_next(details.recommended, &rp.query(), 10, 2).await; + assert_next(details.recommended, rp.query(), 10, 2).await; assert_gte(details.top_comments.count.unwrap(), 700_000, "comments"); assert!(!details.top_comments.is_exhausted()); @@ -499,7 +495,7 @@ async fn get_video_details_music() { assert!(!details.is_ccommons); assert!(details.recommended.visitor_data.is_some()); - assert_next(details.recommended, &rp.query(), 10, 2).await; + assert_next(details.recommended, rp.query(), 10, 2).await; // Update(01.11.2022): comments are sometimes enabled /* @@ -548,7 +544,7 @@ async fn get_video_details_ccommons() { assert!(details.is_ccommons); assert!(details.recommended.visitor_data.is_some()); - assert_next(details.recommended, &rp.query(), 10, 2).await; + assert_next(details.recommended, rp.query(), 10, 2).await; assert_gte(details.top_comments.count.unwrap(), 2199, "comments"); assert!(!details.top_comments.is_exhausted()); @@ -673,7 +669,7 @@ async fn get_video_details_chapters() { } assert!(details.recommended.visitor_data.is_some()); - assert_next(details.recommended, &rp.query(), 10, 2).await; + assert_next(details.recommended, rp.query(), 10, 2).await; assert_gte(details.top_comments.count.unwrap(), 3200, "comments"); assert!(!details.top_comments.is_exhausted()); @@ -718,7 +714,7 @@ async fn get_video_details_live() { assert!(!details.is_ccommons); assert!(details.recommended.visitor_data.is_some()); - assert_next(details.recommended, &rp.query(), 10, 2).await; + assert_next(details.recommended, rp.query(), 10, 2).await; // No comments because livestream assert_eq!(details.top_comments.count, Some(0)); @@ -786,7 +782,7 @@ async fn get_video_comments() { let top_comments = details .top_comments - .next(&rp.query()) + .next(rp.query()) .await .unwrap() .unwrap(); @@ -805,7 +801,7 @@ async fn get_video_comments() { let latest_comments = details .latest_comments - .next(&rp.query()) + .next(rp.query()) .await .unwrap() .unwrap(); @@ -839,7 +835,7 @@ async fn channel_videos() { assert!(age_days < 60, "latest video older than 60 days"); - assert_next(channel.content, &rp.query(), 15, 2).await; + assert_next(channel.content, rp.query(), 15, 2).await; } #[tokio::test] @@ -873,7 +869,7 @@ async fn channel_shorts() { "got no shorts" ); - assert_next(channel.content, &rp.query(), 15, 1).await; + assert_next(channel.content, rp.query(), 15, 1).await; } #[tokio::test] @@ -893,7 +889,7 @@ async fn channel_livestreams() { "got no streams" ); - assert_next(channel.content, &rp.query(), 5, 1).await; + assert_next(channel.content, rp.query(), 5, 1).await; } #[tokio::test] @@ -912,7 +908,7 @@ async fn channel_playlists() { "got no playlists" ); - assert_next(channel.content, &rp.query(), 15, 1).await; + assert_next(channel.content, rp.query(), 15, 1).await; } #[tokio::test] @@ -1099,7 +1095,7 @@ async fn search() { ); assert_eq!(result.corrected_query.unwrap(), "doobydobap"); - assert_next(result.items, &rp.query(), 10, 2).await; + assert_next(result.items, rp.query(), 10, 2).await; } #[rstest] @@ -1115,7 +1111,7 @@ async fn search_filter_entity(#[case] entity: search_filter::Entity) { .await .unwrap(); - result.items.extend(&rp.query()).await.unwrap(); + result.items.extend(rp.query()).await.unwrap(); assert_gte(result.items.items.len(), 20, "items"); result.items.items.iter().for_each(|item| match item { @@ -1243,7 +1239,7 @@ async fn startpage() { // The startpage requires visitor data to fetch continuations assert!(startpage.visitor_data.is_some()); - assert_next(startpage, &rp.query(), 20, 2).await; + assert_next(startpage, rp.query(), 20, 2).await; } #[tokio::test] @@ -1321,7 +1317,7 @@ async fn music_playlist_cont() { playlist .tracks - .extend_pages(&rp.query(), usize::MAX) + .extend_pages(rp.query(), usize::MAX) .await .unwrap(); @@ -1338,11 +1334,7 @@ async fn music_playlist_related() { .await .unwrap(); - playlist - .related_playlists - .extend(&rp.query()) - .await - .unwrap(); + playlist.related_playlists.extend(rp.query()).await.unwrap(); assert_gte( playlist.related_playlists.items.len(), @@ -1571,7 +1563,7 @@ async fn music_search_tracks() { assert_eq!(album.id, "MPREb_OpHWHwyNOuY"); assert_eq!(album.name, "Black Mamba"); - assert_next(res.items, &rp.query(), 15, 2).await; + assert_next(res.items, rp.query(), 15, 2).await; } #[tokio::test] @@ -1605,7 +1597,7 @@ async fn music_search_videos() { assert_eq!(track.album, None); assert_gte(track.view_count.unwrap(), 230_000_000, "views"); - assert_next(res.items, &rp.query(), 15, 2).await; + assert_next(res.items, rp.query(), 15, 2).await; } #[tokio::test] @@ -1692,7 +1684,7 @@ async fn music_search_albums( assert_eq!(res.corrected_query, None); - assert_next(res.items, &rp.query(), 15, n_pages).await; + assert_next(res.items, rp.query(), 15, n_pages).await; } #[tokio::test] @@ -1724,7 +1716,7 @@ async fn music_search_artists_cont() { let res = rp.query().music_search_artists("band").await.unwrap(); assert_eq!(res.corrected_query, None); - assert_next(res.items, &rp.query(), 15, 2).await; + assert_next(res.items, rp.query(), 15, 2).await; } #[rstest] @@ -2000,7 +1992,7 @@ async fn music_details_not_found() { async fn music_radio_track() { let rp = RustyPipe::builder().strict().build(); let tracks = rp.query().music_radio_track("ZeerrnuLi5E").await.unwrap(); - assert_next(tracks, &rp.query(), 20, 3).await; + assert_next(tracks, rp.query(), 20, 3).await; } #[tokio::test] @@ -2030,7 +2022,7 @@ async fn music_radio_playlist() { .music_radio_playlist("PL5dDx681T4bR7ZF1IuWzOv1omlRbE7PiJ") .await .unwrap(); - assert_next(tracks, &rp.query(), 10, 1).await; + assert_next(tracks, rp.query(), 10, 1).await; } #[tokio::test] @@ -2121,13 +2113,14 @@ fn assert_gte(a: T, b: T, msg: &str) { assert!(a >= b, "expected {} {}, got {}", b, msg, a); } -async fn assert_next( +async fn assert_next>( paginator: Paginator, - query: &RustyPipeQuery, + query: Q, min_items: usize, n_pages: usize, ) { let mut p = paginator; + let query = query.as_ref(); assert_gte(p.items.len(), min_items, "items on page 0"); for i in 0..n_pages {