Skip to content

Commit 582fc21

Browse files
committed
[YouTube] Update again hardcoded client versions and update mobile user agents
Also provide ability to get mobile user-agents used for mobile InnerTube requests and deduplicate related code.
1 parent 408f85a commit 582fc21

1 file changed

Lines changed: 60 additions & 25 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeParsingHelper.java

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,18 @@ private YoutubeParsingHelper() {
9393
public static final String CPN = "cpn";
9494
public static final String VIDEO_ID = "videoId";
9595

96-
private static final String HARDCODED_CLIENT_VERSION = "2.20220114.01.00";
96+
private static final String HARDCODED_CLIENT_VERSION = "2.20220315.01.00";
9797
private static final String HARDCODED_KEY = "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8";
9898

9999
private static final String ANDROID_YOUTUBE_KEY = "AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w";
100100
private static final String IOS_YOUTUBE_KEY = "AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc";
101-
private static final String MOBILE_YOUTUBE_CLIENT_VERSION = "16.49.38";
101+
private static final String MOBILE_YOUTUBE_CLIENT_VERSION = "17.10.35";
102102

103103
private static String clientVersion;
104104
private static String key;
105105

106106
private static final String[] HARDCODED_YOUTUBE_MUSIC_KEY =
107-
{"AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30", "67", "1.20220110.00.00"};
107+
{"AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30", "67", "1.20220309.01.00"};
108108
private static String[] youtubeMusicKey;
109109

110110
private static boolean keyAndVersionExtracted = false;
@@ -851,44 +851,37 @@ public static JsonObject getJsonAndroidPostResponse(
851851
final byte[] body,
852852
@Nonnull final Localization localization,
853853
@Nullable final String endPartOfUrlRequest) throws IOException, ExtractionException {
854-
final Map<String, List<String>> headers = new HashMap<>();
855-
headers.put("Content-Type", Collections.singletonList("application/json"));
856-
// Spoofing an Android 11 device with the hardcoded version of the Android app
857-
headers.put("User-Agent", Collections.singletonList("com.google.android.youtube/"
858-
+ MOBILE_YOUTUBE_CLIENT_VERSION + " (Linux; U; Android 11; "
859-
+ localization.getCountryCode() + ") gzip"));
860-
headers.put("X-Goog-Api-Format-Version", Collections.singletonList("2"));
861-
862-
final String baseEndpointUrl = "https://youtubei.googleapis.com/youtubei/v1/" + endpoint
863-
+ "?key=" + ANDROID_YOUTUBE_KEY + DISABLE_PRETTY_PRINT_PARAMETER;
864-
865-
final Response response = getDownloader().post(isNullOrEmpty(endPartOfUrlRequest)
866-
? baseEndpointUrl : baseEndpointUrl + endPartOfUrlRequest,
867-
headers, body, localization);
868-
869-
return JsonUtils.toJsonObject(getValidJsonResponseBody(response));
854+
return getMobilePostResponse(endpoint, body, localization,
855+
getAndroidUserAgent(localization), ANDROID_YOUTUBE_KEY, endPartOfUrlRequest);
870856
}
871857

872858
public static JsonObject getJsonIosPostResponse(
873859
final String endpoint,
874860
final byte[] body,
875861
@Nonnull final Localization localization,
876862
@Nullable final String endPartOfUrlRequest) throws IOException, ExtractionException {
863+
return getMobilePostResponse(endpoint, body, localization, getIosUserAgent(localization),
864+
IOS_YOUTUBE_KEY, endPartOfUrlRequest);
865+
}
866+
867+
private static JsonObject getMobilePostResponse(
868+
final String endpoint,
869+
final byte[] body,
870+
@Nonnull final Localization localization,
871+
@Nonnull final String userAgent,
872+
@Nonnull final String key,
873+
@Nullable final String endPartOfUrlRequest) throws IOException, ExtractionException {
877874
final Map<String, List<String>> headers = new HashMap<>();
878875
headers.put("Content-Type", Collections.singletonList("application/json"));
879-
// Spoofing an iPhone 13 running iOS 15.2 with the hardcoded mobile client version
880-
headers.put("User-Agent", Collections.singletonList("com.google.ios.youtube/"
881-
+ MOBILE_YOUTUBE_CLIENT_VERSION + "(iPhone14,5; U; CPU iOS 15_2 like Mac OS X; "
882-
+ localization.getCountryCode() + ")"));
876+
headers.put("User-Agent", Collections.singletonList(userAgent));
883877
headers.put("X-Goog-Api-Format-Version", Collections.singletonList("2"));
884878

885879
final String baseEndpointUrl = "https://youtubei.googleapis.com/youtubei/v1/" + endpoint
886-
+ "?key=" + IOS_YOUTUBE_KEY + DISABLE_PRETTY_PRINT_PARAMETER;
880+
+ "?key=" + key + DISABLE_PRETTY_PRINT_PARAMETER;
887881

888882
final Response response = getDownloader().post(isNullOrEmpty(endPartOfUrlRequest)
889883
? baseEndpointUrl : baseEndpointUrl + endPartOfUrlRequest,
890884
headers, body, localization);
891-
892885
return JsonUtils.toJsonObject(getValidJsonResponseBody(response));
893886
}
894887

@@ -1111,6 +1104,48 @@ public static byte[] createDesktopPlayerBody(
11111104
// @formatter:on
11121105
}
11131106

1107+
/**
1108+
* Get the user-agent string used as the user-agent for InnerTube requests with the Android
1109+
* client.
1110+
*
1111+
* If the {@link Localization} provided is {@code null}, fallbacks to
1112+
* {@link Localization#DEFAULT the default one}.
1113+
*
1114+
* @param localization the {@link Localization} to set in the user-agent
1115+
* @return the Android user-agent used for InnerTube requests with the Android client,
1116+
* depending on the {@link Localization} provided
1117+
*/
1118+
@Nonnull
1119+
public static String getAndroidUserAgent(@Nullable final Localization localization) {
1120+
// Spoofing an Android 12 device with the hardcoded version of the Android app
1121+
return "com.google.android.youtube/" + MOBILE_YOUTUBE_CLIENT_VERSION
1122+
+ " (Linux; U; Android 12; "
1123+
+ (localization != null ? localization.getCountryCode()
1124+
: Localization.DEFAULT.getCountryCode())
1125+
+ ") gzip";
1126+
}
1127+
1128+
/**
1129+
* Get the user-agent string used as the user-agent for InnerTube requests with the iOS
1130+
* client.
1131+
*
1132+
* If the {@link Localization} provided is {@code null}, fallbacks to
1133+
* {@link Localization#DEFAULT the default one}.
1134+
*
1135+
* @param localization the {@link Localization} to set in the user-agent
1136+
* @return the iOS user-agent used for InnerTube requests with the iOS client, depending on the
1137+
* {@link Localization} provided
1138+
*/
1139+
@Nonnull
1140+
public static String getIosUserAgent(@Nullable final Localization localization) {
1141+
// Spoofing an iPhone 13 running iOS 15.4 with the hardcoded mobile client version
1142+
return "com.google.ios.youtube/" + MOBILE_YOUTUBE_CLIENT_VERSION
1143+
+ "(iPhone14,5; U; CPU iOS 15_4 like Mac OS X; "
1144+
+ (localization != null ? localization.getCountryCode()
1145+
: Localization.DEFAULT.getCountryCode())
1146+
+ ")";
1147+
}
1148+
11141149
/**
11151150
* Add required headers and cookies to an existing headers Map.
11161151
* @see #addClientInfoHeaders(Map)

0 commit comments

Comments
 (0)