Skip to content

Commit d961d34

Browse files
FireMasterKAudricV
andauthored
[YouTube] Check whether player responses are valid for all InnerTube clients used (#1070)
Co-authored-by: Audric V <74829229+AudricV@users.noreply.github.com>
1 parent ad97f08 commit d961d34

1 file changed

Lines changed: 27 additions & 13 deletions

File tree

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

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,10 @@ public void onFetchPage(@Nonnull final Downloader downloader)
868868
playerMicroFormatRenderer = youtubePlayerResponse.getObject("microformat")
869869
.getObject("playerMicroformatRenderer");
870870

871+
if (isPlayerResponseNotValid(playerResponse, videoId)) {
872+
throw new ExtractionException("Initial player response is not valid");
873+
}
874+
871875
final byte[] body = JsonWriter.string(
872876
prepareDesktopJsonBuilder(localization, contentCountry)
873877
.value(VIDEO_ID, videoId)
@@ -1058,6 +1062,11 @@ private void fetchTvHtml5EmbedJsonPlayer(@Nonnull final ContentCountry contentCo
10581062
final JsonObject tvHtml5EmbedPlayerResponse = getJsonPostResponse(PLAYER,
10591063
createDesktopPlayerBody(localization, contentCountry, videoId, sts, true,
10601064
html5Cpn), localization);
1065+
1066+
if (isPlayerResponseNotValid(tvHtml5EmbedPlayerResponse, videoId)) {
1067+
return;
1068+
}
1069+
10611070
final JsonObject streamingData = tvHtml5EmbedPlayerResponse.getObject(
10621071
STREAMING_DATA);
10631072
if (!isNullOrEmpty(streamingData)) {
@@ -1067,35 +1076,40 @@ private void fetchTvHtml5EmbedJsonPlayer(@Nonnull final ContentCountry contentCo
10671076
}
10681077

10691078
/**
1070-
* Checks whether an additional player response is not valid.
1079+
* Checks whether a player response is invalid.
10711080
*
10721081
* <p>
10731082
* If YouTube detect that requests come from a third party client, they may replace the real
10741083
* player response by another one of a video saying that this content is not available on this
1075-
* app and to watch it on the latest version of YouTube.
1084+
* app and to watch it on the latest version of YouTube. This behavior has been observed on the
1085+
* {@code ANDROID} client, see
1086+
* <a href="https://github.com/TeamNewPipe/NewPipe/issues/8713">
1087+
* https://github.com/TeamNewPipe/NewPipe/issues/8713</a>.
10761088
* </p>
10771089
*
10781090
* <p>
1079-
* We can detect this by checking whether the video ID of the player response returned is the
1080-
* same as the one requested by the extractor.
1091+
* YouTube may also sometimes for currently unknown reasons rate-limit an IP, and replace the
1092+
* real one by a player response with a video that says that the requested video is
1093+
* unavailable. This behaviour has been observed in Piped on the InnerTube clients used by the
1094+
* extractor ({@code ANDROID} and {@code WEB} clients) which should apply for all clients, see
1095+
* <a href="https://github.com/TeamPiped/Piped/issues/2487">
1096+
* https://github.com/TeamPiped/Piped/issues/2487</a>.
10811097
* </p>
10821098
*
10831099
* <p>
1084-
* This behavior has been already observed on the {@code ANDROID} client, see
1085-
* <a href="https://github.com/TeamNewPipe/NewPipe/issues/8713">
1086-
* https://github.com/TeamNewPipe/NewPipe/issues/8713</a>.
1100+
* We can detect this by checking whether the video ID of the player response returned is the
1101+
* same as the one requested by the extractor.
10871102
* </p>
10881103
*
1089-
* @param additionalPlayerResponse an additional response to the one of the {@code HTML5}
1090-
* client used
1091-
* @param videoId the video ID of the content requested
1104+
* @param playerResponse a player response from any client
1105+
* @param videoId the video ID of the content requested
10921106
* @return whether the video ID of the player response is not equal to the one requested
10931107
*/
10941108
private static boolean isPlayerResponseNotValid(
1095-
@Nonnull final JsonObject additionalPlayerResponse,
1109+
@Nonnull final JsonObject playerResponse,
10961110
@Nonnull final String videoId) {
1097-
return !videoId.equals(additionalPlayerResponse.getObject("videoDetails")
1098-
.getString("videoId", ""));
1111+
return !videoId.equals(playerResponse.getObject("videoDetails")
1112+
.getString("videoId"));
10991113
}
11001114

11011115
private static void storePlayerJs() throws ParsingException {

0 commit comments

Comments
 (0)