From 7bdca33a872a9e255e5a232e3fe673b326d7f2bf Mon Sep 17 00:00:00 2001 From: AudricV <74829229+AudricV@users.noreply.github.com> Date: Mon, 8 Aug 2022 22:40:49 +0200 Subject: [PATCH] [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. --- .../extractors/YoutubeStreamExtractor.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java index 82a5d0168..c71098525 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java @@ -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. + * + *
+ * 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 behavior has been already observed on the {@code ANDROID} client, see + * + * https://github.com/TeamNewPipe/NewPipe/issues/8713. + *
+ * + * @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();