Skip to content

Commit

Permalink
[YouTube] Ensure that an additional player response is the correct one
Browse files Browse the repository at this point in the history
If YouTube detect that requests come from a third party client, they may
replace the real player response by another one of a video saying that this
content is not available on this app and to watch it on the latest version of
YouTube. We can detect this by checking whether the video ID of the player
response returned is the same as the one requested by the extractor.
  • Loading branch information
AudricV committed Aug 12, 2022
1 parent c82317e commit 7bdca33
Showing 1 changed file with 40 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,10 @@ private void fetchAndroidMobileJsonPlayer(@Nonnull final ContentCountry contentC
mobileBody, localization, "&t=" + generateTParameter()
+ "&id=" + videoId);

if (isPlayerResponseNotValid(androidPlayerResponse, videoId)) {
return;
}

final JsonObject streamingData = androidPlayerResponse.getObject(STREAMING_DATA);
if (!isNullOrEmpty(streamingData)) {
androidStreamingData = streamingData;
Expand Down Expand Up @@ -963,6 +967,10 @@ private void fetchIosMobileJsonPlayer(@Nonnull final ContentCountry contentCount
mobileBody, localization, "&t=" + generateTParameter()
+ "&id=" + videoId);

if (isPlayerResponseNotValid(iosPlayerResponse, videoId)) {
return;
}

final JsonObject streamingData = iosPlayerResponse.getObject(STREAMING_DATA);
if (!isNullOrEmpty(streamingData)) {
iosStreamingData = streamingData;
Expand Down Expand Up @@ -1001,6 +1009,38 @@ private void fetchTvHtml5EmbedJsonPlayer(@Nonnull final ContentCountry contentCo
}
}

/**
* Checks whether an additional player response is not valid.
*
* <p>
* If YouTube detect that requests come from a third party client, they may replace the real
* player response by another one of a video saying that this content is not available on this
* app and to watch it on the latest version of YouTube.
* </p>
*
* <p>
* We can detect this by checking whether the video ID of the player response returned is the
* same as the one requested by the extractor.
* </p>
*
* <p>
* This behavior has been already observed on the {@code ANDROID} client, see
* <a href="https://github.com/TeamNewPipe/NewPipe/issues/8713">
* https://github.com/TeamNewPipe/NewPipe/issues/8713</a>.
* </p>
*
* @param additionalPlayerResponse an additional response to the one of the {@code HTML5}
* client used
* @param videoId the video ID of the content requested
* @return whether the video ID of the player response is not equal to the one requested
*/
private static boolean isPlayerResponseNotValid(
@Nonnull final JsonObject additionalPlayerResponse,
@Nonnull final String videoId) {
return !videoId.equals(additionalPlayerResponse.getObject("videoDetails")
.getString("videoId", ""));
}

private static void storePlayerJs() throws ParsingException {
try {
playerCode = YoutubeJavaScriptExtractor.extractJavaScriptCode();
Expand Down

0 comments on commit 7bdca33

Please sign in to comment.