Skip to content

Commit 16b59af

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 271cdf5 commit 16b59af

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
@@ -926,6 +926,10 @@ private void fetchAndroidMobileJsonPlayer(@Nonnull final ContentCountry contentC
926926
mobileBody, localization, "&t=" + generateTParameter()
927927
+ "&id=" + videoId);
928928

929+
if (isPlayerResponseNotValid(androidPlayerResponse, videoId)) {
930+
return;
931+
}
932+
929933
final JsonObject streamingData = androidPlayerResponse.getObject(STREAMING_DATA);
930934
if (!isNullOrEmpty(streamingData)) {
931935
androidStreamingData = streamingData;
@@ -957,6 +961,10 @@ private void fetchIosMobileJsonPlayer(@Nonnull final ContentCountry contentCount
957961
mobileBody, localization, "&t=" + generateTParameter()
958962
+ "&id=" + videoId);
959963

964+
if (isPlayerResponseNotValid(iosPlayerResponse, videoId)) {
965+
return;
966+
}
967+
960968
final JsonObject streamingData = iosPlayerResponse.getObject(STREAMING_DATA);
961969
if (!isNullOrEmpty(streamingData)) {
962970
iosStreamingData = streamingData;
@@ -995,6 +1003,38 @@ private void fetchTvHtml5EmbedJsonPlayer(@Nonnull final ContentCountry contentCo
9951003
}
9961004
}
9971005

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

0 commit comments

Comments
 (0)