Workaround for rate limits: always use the Android mobile API

This commit is contained in:
TiA4f8R 2021-07-05 19:21:54 +02:00
parent 8aa60d7e8f
commit 3adac6a150
No known key found for this signature in database
GPG Key ID: E6D3E7F5949450DD
1 changed files with 11 additions and 17 deletions

View File

@ -111,6 +111,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
private JsonObject videoPrimaryInfoRenderer; private JsonObject videoPrimaryInfoRenderer;
private JsonObject videoSecondaryInfoRenderer; private JsonObject videoSecondaryInfoRenderer;
private int ageLimit = -1; private int ageLimit = -1;
private boolean isGetVideoInfoPlayerResponse = false;
@Nullable @Nullable
private List<SubtitlesStream> subtitles = null; private List<SubtitlesStream> subtitles = null;
@ -759,9 +760,14 @@ public class YoutubeStreamExtractor extends StreamExtractor {
nextResponse = getJsonPostResponse("next", body, localization); nextResponse = getJsonPostResponse("next", body, localization);
streamingData = playerResponse.getObject("streamingData"); // Workaround for rate limits on web streaming URLs.
if (hasOtfStreams() || isCipherProtectedContent()) { // TODO: add ability to deobfuscate the n param of these URLs
// It's not needed to request the mobile API for age-restricted videos
if (!isGetVideoInfoPlayerResponse) {
fetchAndroidMobileJsonPlayer(contentCountry, localization, videoId); fetchAndroidMobileJsonPlayer(contentCountry, localization, videoId);
} else {
streamingData = playerResponse.getObject("streamingData");
} }
} }
@ -859,6 +865,8 @@ public class YoutubeStreamExtractor extends StreamExtractor {
streamingData = playerResponseWithSignatureTimestamp.getObject( streamingData = playerResponseWithSignatureTimestamp.getObject(
"streamingData"); "streamingData");
} }
} else {
streamingData = playerResponse.getObject("streamingData");
} }
} }
} }
@ -876,6 +884,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
throw new ParsingException( throw new ParsingException(
"Could not parse YouTube player response from video info page", e); "Could not parse YouTube player response from video info page", e);
} }
isGetVideoInfoPlayerResponse = true;
} }
@Nonnull @Nonnull
@ -940,21 +949,6 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
} }
private boolean hasOtfStreams() {
if (streamingData != null) {
final JsonArray adaptiveFormats = streamingData.getArray("adaptiveFormats");
for (final Object adaptiveFormat : adaptiveFormats) {
final JsonObject jsonAdaptiveFormat = (JsonObject) adaptiveFormat;
final String streamTypeFormat = jsonAdaptiveFormat.getString("type", EMPTY_STRING);
if (streamTypeFormat.equalsIgnoreCase("FORMAT_STREAM_TYPE_OTF")) {
return true;
}
}
}
return false;
}
private boolean isCipherProtectedContent() { private boolean isCipherProtectedContent() {
if (streamingData != null) { if (streamingData != null) {
if (streamingData.has("adaptiveFormats")) { if (streamingData.has("adaptiveFormats")) {