Skip to content

Commit 71b9fd0

Browse files
authored
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.
1 parent 4b14786 commit 71b9fd0

2 files changed

Lines changed: 36 additions & 8 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractor.java

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,13 @@ private YoutubeJavaScriptExtractor() {
3939
@Nonnull
4040
public static String extractJavaScriptCode(final String videoId) throws ParsingException {
4141
if (cachedJavaScriptCode == null) {
42-
final String playerJsUrl = YoutubeJavaScriptExtractor.cleanJavaScriptUrl(
43-
YoutubeJavaScriptExtractor.extractJavaScriptUrl(videoId));
42+
String url;
43+
try {
44+
url = YoutubeJavaScriptExtractor.extractJavaScriptUrl();
45+
} catch (final Exception i) {
46+
url = YoutubeJavaScriptExtractor.extractJavaScriptUrl(videoId);
47+
}
48+
final String playerJsUrl = YoutubeJavaScriptExtractor.cleanJavaScriptUrl(url);
4449
cachedJavaScriptCode = YoutubeJavaScriptExtractor.downloadJavaScriptCode(playerJsUrl);
4550
}
4651

@@ -68,7 +73,22 @@ public static void resetJavaScriptCode() {
6873
cachedJavaScriptCode = null;
6974
}
7075

71-
private static String extractJavaScriptUrl(final String videoId) throws ParsingException {
76+
public static String extractJavaScriptUrl() throws ParsingException {
77+
try {
78+
final String iframeUrl = "https://www.youtube.com/iframe_api";
79+
final String iframeContent = NewPipe.getDownloader()
80+
.get(iframeUrl, Localization.DEFAULT).responseBody();
81+
final String hashPattern = "player\\\\\\/([a-z0-9]{8})\\\\\\/";
82+
final String hash = Parser.matchGroup1(hashPattern, iframeContent);
83+
84+
return String.format("https://www.youtube.com/s/player/%s/player_ias.vflset/en_US/base.js", hash);
85+
86+
} catch (final Exception i) { }
87+
88+
throw new ParsingException("Iframe API did not provide YouTube player js url");
89+
}
90+
91+
public static String extractJavaScriptUrl(final String videoId) throws ParsingException {
7292
try {
7393
final String embedUrl = "https://www.youtube.com/embed/" + videoId;
7494
final String embedPageContent = NewPipe.getDownloader()
@@ -90,9 +110,8 @@ private static String extractJavaScriptUrl(final String videoId) throws ParsingE
90110
}
91111
}
92112

93-
} catch (final Exception i) {
94-
throw new ParsingException("Embedded info did not provide YouTube player js url");
95-
}
113+
} catch (final Exception i) { }
114+
96115
throw new ParsingException("Embedded info did not provide YouTube player js url");
97116
}
98117

extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeJavaScriptExtractorTest.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88

99
import java.io.IOException;
1010

11-
import static org.hamcrest.CoreMatchers.allOf;
12-
import static org.hamcrest.CoreMatchers.containsString;
11+
import static org.hamcrest.CoreMatchers.*;
1312
import static org.hamcrest.MatcherAssert.assertThat;
1413

1514
public class YoutubeJavaScriptExtractorTest {
@@ -19,6 +18,16 @@ public void setup() throws IOException {
1918
NewPipe.init(DownloaderTestImpl.getInstance());
2019
}
2120

21+
@Test
22+
public void testExtractJavaScriptUrlIframe() throws ParsingException {
23+
assertThat(YoutubeJavaScriptExtractor.extractJavaScriptUrl(), endsWith("base.js"));
24+
}
25+
26+
@Test
27+
public void testExtractJavaScriptUrlEmbed() throws ParsingException {
28+
assertThat(YoutubeJavaScriptExtractor.extractJavaScriptUrl("d4IGg5dqeO8"), endsWith("base.js"));
29+
}
30+
2231
@Test
2332
public void testExtractJavaScript__success() throws ParsingException {
2433
String playerJsCode = YoutubeJavaScriptExtractor.extractJavaScriptCode("d4IGg5dqeO8");

0 commit comments

Comments
 (0)