From 71b9fd00761b2eb645b6acae23aa7d7159d08f43 Mon Sep 17 00:00:00 2001 From: FireMasterK <20838718+FireMasterK@users.noreply.github.com> Date: Sat, 7 Aug 2021 16:05:48 +0530 Subject: [PATCH] Faster iframe api based player extraction. (#694) * Faster iframe api based player extraction. Uses the IFrame API to reduce the required download to less than 1/50 of the size. * Remove debug code. * Extract to two methods. * Add tests for player URL extraction. * Add assertThat for tests. --- .../youtube/YoutubeJavaScriptExtractor.java | 31 +++++++++++++++---- .../YoutubeJavaScriptExtractorTest.java | 13 ++++++-- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java index 22631b6fe..92cdaec71 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java @@ -39,8 +39,13 @@ public class YoutubeJavaScriptExtractor { @Nonnull public static String extractJavaScriptCode(final String videoId) throws ParsingException { if (cachedJavaScriptCode == null) { - final String playerJsUrl = YoutubeJavaScriptExtractor.cleanJavaScriptUrl( - YoutubeJavaScriptExtractor.extractJavaScriptUrl(videoId)); + String url; + try { + url = YoutubeJavaScriptExtractor.extractJavaScriptUrl(); + } catch (final Exception i) { + url = YoutubeJavaScriptExtractor.extractJavaScriptUrl(videoId); + } + final String playerJsUrl = YoutubeJavaScriptExtractor.cleanJavaScriptUrl(url); cachedJavaScriptCode = YoutubeJavaScriptExtractor.downloadJavaScriptCode(playerJsUrl); } @@ -68,7 +73,22 @@ public class YoutubeJavaScriptExtractor { cachedJavaScriptCode = null; } - private static String extractJavaScriptUrl(final String videoId) throws ParsingException { + public static String extractJavaScriptUrl() throws ParsingException { + try { + final String iframeUrl = "https://www.youtube.com/iframe_api"; + final String iframeContent = NewPipe.getDownloader() + .get(iframeUrl, Localization.DEFAULT).responseBody(); + final String hashPattern = "player\\\\\\/([a-z0-9]{8})\\\\\\/"; + final String hash = Parser.matchGroup1(hashPattern, iframeContent); + + return String.format("https://www.youtube.com/s/player/%s/player_ias.vflset/en_US/base.js", hash); + + } catch (final Exception i) { } + + throw new ParsingException("Iframe API did not provide YouTube player js url"); + } + + public static String extractJavaScriptUrl(final String videoId) throws ParsingException { try { final String embedUrl = "https://www.youtube.com/embed/" + videoId; final String embedPageContent = NewPipe.getDownloader() @@ -90,9 +110,8 @@ public class YoutubeJavaScriptExtractor { } } - } catch (final Exception i) { - throw new ParsingException("Embedded info did not provide YouTube player js url"); - } + } catch (final Exception i) { } + throw new ParsingException("Embedded info did not provide YouTube player js url"); } diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractorTest.java index f86dbf716..2b8989d77 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractorTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractorTest.java @@ -8,8 +8,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import java.io.IOException; -import static org.hamcrest.CoreMatchers.allOf; -import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; public class YoutubeJavaScriptExtractorTest { @@ -19,6 +18,16 @@ public class YoutubeJavaScriptExtractorTest { NewPipe.init(DownloaderTestImpl.getInstance()); } + @Test + public void testExtractJavaScriptUrlIframe() throws ParsingException { + assertThat(YoutubeJavaScriptExtractor.extractJavaScriptUrl(), endsWith("base.js")); + } + + @Test + public void testExtractJavaScriptUrlEmbed() throws ParsingException { + assertThat(YoutubeJavaScriptExtractor.extractJavaScriptUrl("d4IGg5dqeO8"), endsWith("base.js")); + } + @Test public void testExtractJavaScript__success() throws ParsingException { String playerJsCode = YoutubeJavaScriptExtractor.extractJavaScriptCode("d4IGg5dqeO8");