Skip to content

Commit 62912ee

Browse files
committed
Merge branch 'master' into dev
2 parents 943334b + 19c0e87 commit 62912ee

2 files changed

Lines changed: 45 additions & 21 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ allprojects {
55
sourceCompatibility = 1.7
66
targetCompatibility = 1.7
77

8-
version 'v0.20.1'
8+
version 'v0.20.2'
99
group 'com.github.TeamNewPipe'
1010

1111
repositories {

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import com.grack.nanojson.JsonArray;
44
import com.grack.nanojson.JsonObject;
55
import com.grack.nanojson.JsonParser;
6+
import org.jsoup.Jsoup;
7+
import org.jsoup.nodes.Document;
8+
import org.jsoup.nodes.Element;
9+
import org.jsoup.select.Elements;
610
import org.mozilla.javascript.Context;
711
import org.mozilla.javascript.Function;
812
import org.mozilla.javascript.ScriptableObject;
@@ -100,6 +104,7 @@ public class DeobfuscateException extends ParsingException {
100104
private JsonObject videoPrimaryInfoRenderer;
101105
private JsonObject videoSecondaryInfoRenderer;
102106
private int ageLimit;
107+
private boolean newJsonScheme;
103108

104109
@Nonnull
105110
private List<SubtitlesInfo> subtitlesInfos = new ArrayList<>();
@@ -664,27 +669,23 @@ public void onFetchPage(@Nonnull Downloader downloader) throws IOException, Extr
664669
} else {
665670
ageLimit = NO_AGE_LIMIT;
666671
JsonObject playerConfig;
672+
initialData = initialAjaxJson.getObject(3).getObject("response");
667673

668-
// sometimes at random YouTube does not provide the player config,
669-
// so just retry the same request three times
670-
int attempts = 2;
671-
while (true) {
672-
playerConfig = initialAjaxJson.getObject(2).getObject("player", null);
673-
if (playerConfig != null) {
674-
break;
675-
}
674+
// sometimes at random YouTube does not provide the player config
675+
playerConfig = initialAjaxJson.getObject(2).getObject("player", null);
676676

677-
if (attempts <= 0) {
678-
throw new ParsingException(
679-
"YouTube did not provide player config even after three attempts");
680-
}
681-
initialAjaxJson = getJsonResponse(url, getExtractorLocalization());
682-
--attempts;
677+
if (playerConfig == null) {
678+
newJsonScheme = true;
679+
final EmbeddedInfo info = getEmbeddedInfo();
680+
final String videoInfoUrl = getVideoInfoUrl(getId(), info.sts);
681+
final String infoPageResponse = downloader.get(videoInfoUrl, getExtractorLocalization()).responseBody();
682+
videoInfoPage.putAll(Parser.compatParseMap(infoPageResponse));
683+
playerUrl = info.url;
684+
} else {
685+
playerArgs = getPlayerArgs(playerConfig);
686+
playerUrl = getPlayerUrl(playerConfig);
683687
}
684-
initialData = initialAjaxJson.getObject(3).getObject("response");
685688

686-
playerArgs = getPlayerArgs(playerConfig);
687-
playerUrl = getPlayerUrl(playerConfig);
688689
}
689690

690691
playerResponse = getPlayerResponse();
@@ -732,6 +733,10 @@ private String getPlayerUrl(final JsonObject playerConfig) throws ParsingExcepti
732733
private JsonObject getPlayerResponse() throws ParsingException {
733734
try {
734735
String playerResponseStr;
736+
if (newJsonScheme) {
737+
return initialAjaxJson.getObject(2).getObject("playerResponse");
738+
}
739+
735740
if (playerArgs != null) {
736741
playerResponseStr = playerArgs.getString("player_response");
737742
} else {
@@ -751,11 +756,30 @@ private EmbeddedInfo getEmbeddedInfo() throws ParsingException, ReCaptchaExcepti
751756
final String embedPageContent = downloader.get(embedUrl, getExtractorLocalization()).responseBody();
752757

753758
// Get player url
754-
final String assetsPattern = "\"assets\":.+?\"js\":\\s*(\"[^\"]+\")";
755-
String playerUrl = Parser.matchGroup1(assetsPattern, embedPageContent)
756-
.replace("\\", "").replace("\"", "");
759+
String playerUrl = null;
760+
try {
761+
final String assetsPattern = "\"assets\":.+?\"js\":\\s*(\"[^\"]+\")";
762+
playerUrl = Parser.matchGroup1(assetsPattern, embedPageContent)
763+
.replace("\\", "").replace("\"", "");
764+
} catch (Parser.RegexException ex) {
765+
// playerUrl is still available in the file, just somewhere else
766+
final Document doc = Jsoup.parse(embedPageContent);
767+
final Elements elems = doc.select("script").attr("name", "player_ias/base");
768+
for (Element elem : elems) {
769+
if (elem.attr("src").contains("base.js")) {
770+
playerUrl = elem.attr("src");
771+
}
772+
}
773+
774+
if (playerUrl == null) {
775+
throw new ParsingException("Could not get playerUrl");
776+
}
777+
}
778+
757779
if (playerUrl.startsWith("//")) {
758780
playerUrl = HTTPS + playerUrl;
781+
} else if (playerUrl.startsWith("/")) {
782+
playerUrl = HTTPS + "//youtube.com" + playerUrl;
759783
}
760784

761785
try {

0 commit comments

Comments
 (0)