[YouTube] Ensure that an additional player response is the correct one

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.
This commit is contained in:
AudricV 2022-08-08 22:40:49 +02:00
parent c82317e318
commit 7bdca33a87
No known key found for this signature in database
GPG Key ID: DA92EC7905614198
1 changed files with 40 additions and 0 deletions

View File

@ -932,6 +932,10 @@ public class YoutubeStreamExtractor extends StreamExtractor {
mobileBody, localization, "&t=" + generateTParameter()
+ "&id=" + videoId);
if (isPlayerResponseNotValid(androidPlayerResponse, videoId)) {
return;
}
final JsonObject streamingData = androidPlayerResponse.getObject(STREAMING_DATA);
if (!isNullOrEmpty(streamingData)) {
androidStreamingData = streamingData;
@ -963,6 +967,10 @@ public class YoutubeStreamExtractor extends StreamExtractor {
mobileBody, localization, "&t=" + generateTParameter()
+ "&id=" + videoId);
if (isPlayerResponseNotValid(iosPlayerResponse, videoId)) {
return;
}
final JsonObject streamingData = iosPlayerResponse.getObject(STREAMING_DATA);
if (!isNullOrEmpty(streamingData)) {
iosStreamingData = streamingData;
@ -1001,6 +1009,38 @@ public class YoutubeStreamExtractor extends StreamExtractor {
}
}
/**
* 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();