88import org .schabi .newpipe .extractor .exceptions .ParsingException ;
99
1010import java .io .IOException ;
11+ import java .util .Arrays ;
12+ import java .util .Collections ;
13+ import java .util .List ;
1114
1215import static org .junit .jupiter .api .Assertions .assertEquals ;
1316import static org .junit .jupiter .api .Assertions .assertNotEquals ;
1417import static org .junit .jupiter .api .Assertions .fail ;
1518
16- public class YoutubeThrottlingDecrypterTest {
19+ class YoutubeThrottlingDecrypterTest {
1720
1821 @ BeforeEach
1922 public void setup () throws IOException {
2023 NewPipe .init (DownloaderTestImpl .getInstance ());
2124 }
2225
2326 @ Test
24- public void testExtractFunction__success () throws ParsingException {
27+ void testExtractFunction__success () throws ParsingException {
2528 final String [] videoIds = {"jE1USQrs1rw" , "CqxjzfudGAc" , "goH-9MfQI7w" , "KYIdr_7H5Yw" , "J1WeqmGbYeI" };
2629
27- final String encryptedUrl = "https://r6---sn-4g5ednek.googlevideo.com/videoplayback?expire=1626562120&ei=6AnzYO_YBpql1gLGkb_IBQ&ip=127.0.0.1&id=o-ANhBEf36Z5h-8U9DDddtPDqtS0ZNwf0XJAAigudKI2uI&itag=278&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&vprv=1&mime=video%2Fwebm&ns=TvecOReN0vPuXb3j_zq157IG&gir=yes&clen=2915100&dur=270.203&lmt=1608157174907785&keepalive=yes&fexp=24001373,24007246&c=WEB&txp=5535432&n=N9BWSTFT7vvBJrvQ&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&alr=yes&sig=AOq0QJ8wRQIgW6XnUDKPDSxiT0_KE_tDDMpcaCJl2Un5p0Fu9qZNQGkCIQDWxsDHi_s2BEmRqIbd1C5g_gzfihB7RZLsScKWNMwzzA%3D%3D&cpn=9r2yt3BqcYmeb2Yu&cver=2.20210716.00.00&redirect_counter=1&cm2rm=sn-4g5ezy7s&cms_redirect=yes&mh=Y5&mm=34&mn=sn-4g5ednek&ms=ltu&mt=1626540524&mv=m&mvi=6&pl=43&lsparams=mh,mm,mn,ms,mv,mvi,pl&lsig=AG3C_xAwRQIhAIUzxTn9Vw1-vm-_7OQ5-0h1M6AZsY9Bx1FlCCTeMICzAiADtGggbn4Znsrh2EnvyOsGnYdRGcbxn4mW9JMOQiInDQ%3D%3D&range=259165-480735&rn=11&rbuf=20190" ;
30+ final String encryptedUrl = "https://rr5---sn-hgn7rn7r.googlevideo.com/videoplayback?expire=1660678160&ei=sJv7YqeZF--ox_APxbGmoAY&ip=127.0.0.1&id=o-AFaQeZ3jvQeyHQxPus8HGjIx0GQY7NuEuhTV8rXN0ZNY&itag=278&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&mh=_u&mm=31%2C29&mn=sn-hgn7rn7r%2Csn-hgn7ynek&ms=au%2Crdu&mv=m&mvi=5&pl=17&pcm2=no&initcwndbps=1090000&spc=lT-KhhZX76Y3nDFlQltXy5FjBYCL_zo&vprv=1&mime=video%2Fwebm&ns=nj09IAwNAwEzbcs0uiVg_qMH&gir=yes&clen=9528620&dur=1010.040&lmt=1606701000638528&mt=1660656071&fvip=4&keepalive=yes&fexp=24001373%2C24007246&c=WEB&rbqsm=fr&txp=5535434&n=Sz9T011qvlkRgU_o3&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cpcm2%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgTNZiDfTFYHcNnQKUkOruoXVERstmzsZYoQkECNDih4gCIFlsP-P3S40YgIFHs913ag6QRJ1R8FTASwFlmJj6Tvsl&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgE6TSXoD44zmCzHzadyU9X2SPW_njlHi6OUFBEqgAWnYCIFn_bpS-qvA1UfziuG4G3KEGQP_Itj9lm-eTWOKHnTRG" ;
2831
2932 for (final String videoId : videoIds ) {
3033 try {
3134 final String decryptedUrl = YoutubeThrottlingDecrypter .apply (encryptedUrl , videoId );
3235 assertNotEquals (encryptedUrl , decryptedUrl );
33- } catch (EvaluatorException e ) {
36+ } catch (final EvaluatorException e ) {
3437 fail ("Failed to extract n param decrypt function for video " + videoId + "\n " + e );
3538 }
3639 }
3740 }
3841
3942 @ Test
40- public void testDecode__success () throws ParsingException {
41- // URL extracted from browser with the dev tools
42- final String encryptedUrl = "https://r6---sn-4g5ednek.googlevideo.com/videoplayback?expire=1626562120&ei=6AnzYO_YBpql1gLGkb_IBQ&ip=127.0.0.1&id=o-ANhBEf36Z5h-8U9DDddtPDqtS0ZNwf0XJAAigudKI2uI&itag=278&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278&source=youtube&requiressl=yes&vprv=1&mime=video%2Fwebm&ns=TvecOReN0vPuXb3j_zq157IG&gir=yes&clen=2915100&dur=270.203&lmt=1608157174907785&keepalive=yes&fexp=24001373,24007246&c=WEB&txp=5535432&n=N9BWSTFT7vvBJrvQ&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&alr=yes&sig=AOq0QJ8wRQIgW6XnUDKPDSxiT0_KE_tDDMpcaCJl2Un5p0Fu9qZNQGkCIQDWxsDHi_s2BEmRqIbd1C5g_gzfihB7RZLsScKWNMwzzA%3D%3D&cpn=9r2yt3BqcYmeb2Yu&cver=2.20210716.00.00&redirect_counter=1&cm2rm=sn-4g5ezy7s&cms_redirect=yes&mh=Y5&mm=34&mn=sn-4g5ednek&ms=ltu&mt=1626540524&mv=m&mvi=6&pl=43&lsparams=mh,mm,mn,ms,mv,mvi,pl&lsig=AG3C_xAwRQIhAIUzxTn9Vw1-vm-_7OQ5-0h1M6AZsY9Bx1FlCCTeMICzAiADtGggbn4Znsrh2EnvyOsGnYdRGcbxn4mW9JMOQiInDQ%3D%3D&range=259165-480735&rn=11&rbuf=20190" ;
43- final String decryptedUrl = YoutubeThrottlingDecrypter .apply (encryptedUrl , "jE1USQrs1rw" );
44- // The cipher function changes over time, so we just check if the n param changed.
45- assertNotEquals (encryptedUrl , decryptedUrl );
43+ void testDecode__success () throws ParsingException {
44+ final List <String > encryptedUrls = Collections .unmodifiableList (
45+ Arrays .asList ("https://rr1---sn-hgn7rn7r.googlevideo.com/videoplayback?expire=1660677969&ei=8Zr7YrnBIZvHx_APyvyTkAg&ip=127.0.0.1&id=o-ABVbsAjFjWsHlku7MjrQdz2LfpRQEeWjn0B4EpW_FIe7&itag=22&source=youtube&requiressl=yes&mh=T_&mm=31%2C26&mn=sn-hgn7rn7r%2Csn-4g5ednse&ms=au%2Conr&mv=m&mvi=1&pl=17&pcm2=yes&initcwndbps=1090000&spc=lT-KhmgLjVD8yS6LT4K_om80Ge5lG78&vprv=1&mime=video%2Fmp4&ns=VlRzbfguywob-opNNWJQKCEH&cnr=14&ratebypass=yes&dur=433.748&lmt=1575216052966635&mt=1660656071&fvip=3&fexp=24001373%2C24007246&c=WEB&rbqsm=fr&txp=5532432&n=ocK9xP_u33P_dvAYc&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cpcm2%2Cspc%2Cvprv%2Cmime%2Cns%2Ccnr%2Cratebypass%2Cdur%2Clmt&sig=AOq0QJ8wRgIhAMeeq_G3pOacpNC8BmFsL98L--YBlyEm8pg53c-2J362AiEAgwnzJC-tM6NWJ9wQAVr1P9ELq75SGGV80uZGHfiC_hM%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgApP35DArhdv4ZxxaqbA2yeZ7DRKOs1XJxNr2680aZ0oCIGLJ9-2ZmOVr7mltKtIxWenc0bFuICUnQbb9KDfcRsRj" ,
46+ "https://rr2---sn-hgn7rn7k.googlevideo.com/videoplayback?expire=1660677461&ei=9Zj7YvGfEMfvgQex5YK4AQ&ip=127.0.0.1&id=o-AGmlHQdvHb9JeupgQnaDMWPMTxxyzl8khxNY9y7VvrCO&itag=398&aitags=133%2C134%2C135%2C136%2C137%2C160%2C242%2C243%2C244%2C247%2C248%2C278%2C394%2C395%2C396%2C397%2C398%2C399&source=youtube&requiressl=yes&mh=o5&mm=31%2C26&mn=sn-hgn7rn7k%2Csn-4g5e6nsy&ms=au%2Conr&mv=m&mvi=2&pl=17&initcwndbps=1076250&spc=lT-KhoYsyB3Qe5PQuew86lRglM5vM8g&vprv=1&mime=video%2Fmp4&ns=Hg9Snd1EzOBPO8B2cVkq89YH&gir=yes&clen=24058051&dur=176.042&lmt=1647697732093628&mt=1660655595&fvip=2&keepalive=yes&fexp=24001373%2C24007246&c=WEB&rbqsm=fr&txp=4432434&n=6wNAuWZe1XiYTdKUc&sparams=expire%2Cei%2Cip%2Cid%2Caitags%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIhAPH1T_hFTTOcfpHQv_z5a379W40hZviCbqqOOpqu-J3DAiAbIw5DGjNEmYxreLCUEUWB4dEy2FnzTNf9K_Wq8Ty0wA%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRQIhAOG7tRpl2qeNB8-0x1PG1QHzpJ5xKSeV6Xdj5DHFgh96AiBCGiDacyqY-t9hcvPLZ-qFKWWKTXYF1tEWjR0ywI2tOw%3D%3D" ,
47+ "https://rr2---sn-hgn7rn7r.googlevideo.com/videoplayback?expire=1660677590&ei=dpn7YoGYLMaDgAfKhpmAAQ&ip=127.0.0.1&id=o-AIeHsbxBhX7IIzwB63kB7zJNAsH-GGrsZckumpfALkKh&itag=251&source=youtube&requiressl=yes&mh=aM&mm=31%2C26&mn=sn-hgn7rn7r%2Csn-4g5lzney&ms=au%2Conr&mv=m&mvi=2&pl=17&initcwndbps=1066250&spc=lT-Khvw59cxNiJThxMws39dGjbcP7iw&vprv=1&mime=audio%2Fwebm&ns=X9E01CmLpvgOgKeOs4utnzsH&gir=yes&clen=2356264&dur=133.281&lmt=1497160520245113&mt=1660655595&fvip=4&keepalive=yes&fexp=24001373%2C24007246&c=WEB&rbqsm=fr&n=LNeCSGRimaBmK2C6p&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc%2Cvprv%2Cmime%2Cns%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRAIgBThdqF9XIGdaUy2cKh2YPY6CjUPkxVuIs1Ji7LVr1X0CICENxs13JGCRH71TqLG8o3gZEawF2D5OOOjdyjkksQPC&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRQIgXqnU8H8iFprRTM7MjEMztlktLBIOs2M4yipZmfH2gPoCIQDDhHPKDxBZjiPQnODiBqT4G9p4yzkkPSVmlfdi7IwwzA%3D%3D" ));
48+ for (final String encryptedUrl : encryptedUrls ) {
49+ final String decryptedUrl = YoutubeThrottlingDecrypter .apply (encryptedUrl ,
50+ "jE1USQrs1rw" );
51+ // The cipher function changes over time, so we just check if the n param changed.
52+ assertNotEquals (encryptedUrl , decryptedUrl );
53+ }
4654 }
4755
4856 @ Test
49- public void testDecode__noNParam__success () throws ParsingException {
50- final String noNParamUrl = "https://r5 ---sn-4g5ednsz .googlevideo.com/videoplayback?expire=1626553257 &ei=SefyYPmIFoKT1wLtqbjgCQ &ip=127.0.0.1&id=o-AIT5xGifsaEAdEOAb5vd06J9VNtm-KHHolnaZRGPjHZi &itag=140 &source=youtube&requiressl=yes&mh=xO &mm=31%2C29 &mn=sn-4g5ednsz %2Csn-4g5e6nsr &ms=au%2Crdu &mv=m&mvi=5&pl=24 &initcwndbps=1322500& vprv=1&mime=audio %2Fmp4&ns=cA2SS5atEe0mH8tMwGTO4RIG& gir=yes&clen=3009275 &dur=185.898 &lmt=1626356984653961 &mt=1626531173 &fvip=5 &keepalive=yes&fexp=24001373%2C24007246&beids=23886212&c=WEB &txp=6411222 &sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cvprv%2Cmime%2Cns% 2Cgir%2Cclen%2Cdur%2Clmt&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRgIhAPueRlTutSlzPafxrqBmgZz5m7-Zfbw3QweDp3j4XO9SAiEA5tF7_ZCJFKmS-D6I1jlUURjpjoiTbsYyKuarV4u6E8Y%3D&sig=AOq0QJ8wRQIgRD_4WwkPeTEKGVSQqPsznMJGqq4nVJ8o1ChGBCgi4Y0CIQCZT3tI40YLKBWJCh2Q7AlvuUIpN0ficzdSElLeQpJdrw== " ;
57+ void testDecode__noNParam__success () throws ParsingException {
58+ final String noNParamUrl = "https://rr5 ---sn-hgn7rn7r .googlevideo.com/videoplayback?expire=1660678263 &ei=F5z7YtiqKKjkx_AP1qSFuAg &ip=127.0.0.1&id=o-AG-ATci4w870PV5NXT2n_qeXKNL7O7kIHcRb1kiQSPfZ &itag=597 &source=youtube&requiressl=yes&mh=_u &mm=31%2C26 &mn=sn-hgn7rn7r %2Csn-4g5edn6r &ms=au%2Conr &mv=m&mvi=5&pl=17 &initcwndbps=1091250&spc=lT-KhvhRm_zaHWUnpn3dKQEpkBdYuEs& vprv=1&svpuc=1& mime=video %2Fmp4&gir=yes&clen=3837282 &dur=1010.080 &lmt=1606602836536371 &mt=1660656311 &fvip=1 &keepalive=yes&fexp=24001373%2C24007246&c=ANDROID&rbqsm=fr &txp=5532434 &sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cspc% 2Cvprv%2Csvpuc% 2Cmime%2Cgir%2Cclen%2Cdur%2Clmt&sig=AOq0QJ8wRQIgRt7PGHGTgzK_GNzjaujZY0p9_0nLpmXOD_4xChR7Ve8CIQCcIzjnAyjbiNDMd7-nx3dNC5K-qxQyHIvakWjoQfRtew%3D%3D& lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=AG3C_xAwRAIgI7Ewc_vB43w_3gNIlV3eU_AXnNwFqjMJQVzi3DDYCJkCIGXo54Urb37uUnt502tLOlJ7jZXo-enGe2a_LZDX2T8D " ;
5159 final String decrypted = YoutubeThrottlingDecrypter .apply (noNParamUrl , "jE1USQrs1rw" );
5260
5361 assertEquals (noNParamUrl , decrypted );
5462 }
5563
64+ @ Test
65+ void testCacheCountAndClearCache__success () throws ParsingException {
66+ // Test if the cache works
67+ testDecode__success ();
68+ assertEquals (3 , YoutubeThrottlingDecrypter .getCacheSize ());
69+
70+ // Test if streaming URLs which do not contain the throttling parameter are not decrypted,
71+ // and so do not influence on the cache size
72+ testDecode__noNParam__success ();
73+ assertEquals (3 , YoutubeThrottlingDecrypter .getCacheSize ());
74+
75+ // Test if the cache is really cleared with the corresponding method
76+ YoutubeThrottlingDecrypter .clearCache ();
77+ assertEquals (0 , YoutubeThrottlingDecrypter .getCacheSize ());
78+ }
5679}
0 commit comments