Workaround for rate limits: always use the Android mobile API
This commit is contained in:
parent
8aa60d7e8f
commit
3adac6a150
1 changed files with 11 additions and 17 deletions
|
@ -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")) {
|
||||||
|
|
Loading…
Reference in a new issue