Skip to content

Commit db0ef83

Browse files
committed
fix youtube decryption and three attemps bug
fixes TeamNewPipe/NewPipe#4572 fixes #439
1 parent 350eed6 commit db0ef83

1 file changed

Lines changed: 30 additions & 26 deletions

File tree

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

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.grack.nanojson.JsonArray;
44
import com.grack.nanojson.JsonObject;
55
import com.grack.nanojson.JsonParser;
6-
76
import org.mozilla.javascript.Context;
87
import org.mozilla.javascript.Function;
98
import org.mozilla.javascript.ScriptableObject;
@@ -36,6 +35,8 @@
3635
import org.schabi.newpipe.extractor.utils.Parser;
3736
import org.schabi.newpipe.extractor.utils.Utils;
3837

38+
import javax.annotation.Nonnull;
39+
import javax.annotation.Nullable;
3940
import java.io.IOException;
4041
import java.io.UnsupportedEncodingException;
4142
import java.text.SimpleDateFormat;
@@ -49,9 +50,6 @@
4950
import java.util.Locale;
5051
import java.util.Map;
5152

52-
import javax.annotation.Nonnull;
53-
import javax.annotation.Nullable;
54-
5553
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl;
5654
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonResponse;
5755
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
@@ -102,6 +100,7 @@ public class DecryptException extends ParsingException {
102100
private JsonObject videoPrimaryInfoRenderer;
103101
private JsonObject videoSecondaryInfoRenderer;
104102
private int ageLimit;
103+
private boolean newJsonScheme;
105104

106105
@Nonnull
107106
private List<SubtitlesInfo> subtitlesInfos = new ArrayList<>();
@@ -156,20 +155,23 @@ public String getTextualUploadDate() throws ParsingException {
156155
TimeAgoParser timeAgoParser = TimeAgoPatternsManager.getTimeAgoParserFor(Localization.fromLocalizationCode("en"));
157156
Calendar parsedTime = timeAgoParser.parse(time).date();
158157
return new SimpleDateFormat("yyyy-MM-dd").format(parsedTime.getTime());
159-
} catch (Exception ignored) {}
158+
} catch (Exception ignored) {
159+
}
160160

161161
try { // Premiered Feb 21, 2020
162162
Date d = new SimpleDateFormat("MMM dd, YYYY", Locale.ENGLISH).parse(time);
163163
return new SimpleDateFormat("yyyy-MM-dd").format(d.getTime());
164-
} catch (Exception ignored) {}
164+
} catch (Exception ignored) {
165+
}
165166
}
166167

167168
try {
168169
// TODO: this parses English formatted dates only, we need a better approach to parse the textual date
169170
Date d = new SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH).parse(
170171
getTextFromObject(getVideoPrimaryInfoRenderer().getObject("dateText")));
171172
return new SimpleDateFormat("yyyy-MM-dd").format(d);
172-
} catch (Exception ignored) {}
173+
} catch (Exception ignored) {
174+
}
173175
throw new ParsingException("Could not get upload date");
174176
}
175177

@@ -360,7 +362,8 @@ public String getUploaderName() throws ParsingException {
360362
try {
361363
uploaderName = getTextFromObject(getVideoSecondaryInfoRenderer().getObject("owner")
362364
.getObject("videoOwnerRenderer").getObject("title"));
363-
} catch (ParsingException ignored) { }
365+
} catch (ParsingException ignored) {
366+
}
364367

365368
if (isNullOrEmpty(uploaderName)) {
366369
uploaderName = playerResponse.getObject("videoDetails").getString("author");
@@ -650,27 +653,23 @@ public void onFetchPage(@Nonnull Downloader downloader) throws IOException, Extr
650653
} else {
651654
ageLimit = NO_AGE_LIMIT;
652655
JsonObject playerConfig;
656+
initialData = initialAjaxJson.getObject(3).getObject("response");
653657

654-
// sometimes at random YouTube does not provide the player config,
655-
// so just retry the same request three times
656-
int attempts = 2;
657-
while (true) {
658-
playerConfig = initialAjaxJson.getObject(2).getObject("player", null);
659-
if (playerConfig != null) {
660-
break;
661-
}
658+
// sometimes at random YouTube does not provide the player config
659+
playerConfig = initialAjaxJson.getObject(2).getObject("player", null);
662660

663-
if (attempts <= 0) {
664-
throw new ParsingException(
665-
"YouTube did not provide player config even after three attempts");
666-
}
667-
initialAjaxJson = getJsonResponse(url, getExtractorLocalization());
668-
--attempts;
661+
if (playerConfig == null) {
662+
newJsonScheme = true;
663+
final EmbeddedInfo info = getEmbeddedInfo();
664+
final String videoInfoUrl = getVideoInfoUrl(getId(), info.sts);
665+
final String infoPageResponse = downloader.get(videoInfoUrl, getExtractorLocalization()).responseBody();
666+
videoInfoPage.putAll(Parser.compatParseMap(infoPageResponse));
667+
playerUrl = info.url;
668+
} else {
669+
playerArgs = getPlayerArgs(playerConfig);
670+
playerUrl = getPlayerUrl(playerConfig);
669671
}
670-
initialData = initialAjaxJson.getObject(3).getObject("response");
671672

672-
playerArgs = getPlayerArgs(playerConfig);
673-
playerUrl = getPlayerUrl(playerConfig);
674673
}
675674

676675
playerResponse = getPlayerResponse();
@@ -718,6 +717,10 @@ private String getPlayerUrl(final JsonObject playerConfig) throws ParsingExcepti
718717
private JsonObject getPlayerResponse() throws ParsingException {
719718
try {
720719
String playerResponseStr;
720+
if (newJsonScheme) {
721+
return initialAjaxJson.getObject(2).getObject("playerResponse");
722+
}
723+
721724
if (playerArgs != null) {
722725
playerResponseStr = playerArgs.getString("player_response");
723726
} else {
@@ -988,7 +991,8 @@ private Map<String, ItagItem> getItags(String streamingDataKey, ItagItem.ItagTyp
988991

989992
urlAndItags.put(streamUrl, itagItem);
990993
}
991-
} catch (UnsupportedEncodingException ignored) {}
994+
} catch (UnsupportedEncodingException ignored) {
995+
}
992996
}
993997
}
994998

0 commit comments

Comments
 (0)