Skip to content

Commit 7bdca33

Browse files
committed
[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.
1 parent c82317e commit 7bdca33

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,10 @@ private void fetchAndroidMobileJsonPlayer(@Nonnull final ContentCountry contentC
932932
mobileBody, localization, "&t=" + generateTParameter()
933933
+ "&id=" + videoId);
934934

935+
if (isPlayerResponseNotValid(androidPlayerResponse, videoId)) {
936+
return;
937+
}
938+
935939
final JsonObject streamingData = androidPlayerResponse.getObject(STREAMING_DATA);
936940
if (!isNullOrEmpty(streamingData)) {
937941
androidStreamingData = streamingData;
@@ -963,6 +967,10 @@ private void fetchIosMobileJsonPlayer(@Nonnull final ContentCountry contentCount
963967
mobileBody, localization, "&t=" + generateTParameter()
964968
+ "&id=" + videoId);
965969

970+
if (isPlayerResponseNotValid(iosPlayerResponse, videoId)) {
971+
return;
972+
}
973+
966974
final JsonObject streamingData = iosPlayerResponse.getObject(STREAMING_DATA);
967975
if (!isNullOrEmpty(streamingData)) {
968976
iosStreamingData = streamingData;
@@ -1001,6 +1009,38 @@ private void fetchTvHtml5EmbedJsonPlayer(@Nonnull final ContentCountry contentCo
10011009
}
10021010
}
10031011

1012+
/**
1013+
* Checks whether an additional player response is not valid.
1014+
*
1015+
* <p>
1016+
* If YouTube detect that requests come from a third party client, they may replace the real
1017+
* player response by another one of a video saying that this content is not available on this
1018+
* app and to watch it on the latest version of YouTube.
1019+
* </p>
1020+
*
1021+
* <p>
1022+
* We can detect this by checking whether the video ID of the player response returned is the
1023+
* same as the one requested by the extractor.
1024+
* </p>
1025+
*
1026+
* <p>
1027+
* This behavior has been already observed on the {@code ANDROID} client, see
1028+
* <a href="https://github.com/TeamNewPipe/NewPipe/issues/8713">
1029+
* https://github.com/TeamNewPipe/NewPipe/issues/8713</a>.
1030+
* </p>
1031+
*
1032+
* @param additionalPlayerResponse an additional response to the one of the {@code HTML5}
1033+
* client used
1034+
* @param videoId the video ID of the content requested
1035+
* @return whether the video ID of the player response is not equal to the one requested
1036+
*/
1037+
private static boolean isPlayerResponseNotValid(
1038+
@Nonnull final JsonObject additionalPlayerResponse,
1039+
@Nonnull final String videoId) {
1040+
return !videoId.equals(additionalPlayerResponse.getObject("videoDetails")
1041+
.getString("videoId", ""));
1042+
}
1043+
10041044
private static void storePlayerJs() throws ParsingException {
10051045
try {
10061046
playerCode = YoutubeJavaScriptExtractor.extractJavaScriptCode();

0 commit comments

Comments
 (0)