@@ -94,18 +94,18 @@ private YoutubeParsingHelper() {
9494 public static final String CPN = "cpn" ;
9595 public static final String VIDEO_ID = "videoId" ;
9696
97- private static final String HARDCODED_CLIENT_VERSION = "2.20220114 .01.00" ;
97+ private static final String HARDCODED_CLIENT_VERSION = "2.20220315 .01.00" ;
9898 private static final String HARDCODED_KEY = "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8" ;
9999
100100 private static final String ANDROID_YOUTUBE_KEY = "AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w" ;
101101 private static final String IOS_YOUTUBE_KEY = "AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc" ;
102- private static final String MOBILE_YOUTUBE_CLIENT_VERSION = "16.49.38 " ;
102+ private static final String MOBILE_YOUTUBE_CLIENT_VERSION = "17.10.35 " ;
103103
104104 private static String clientVersion ;
105105 private static String key ;
106106
107107 private static final String [] HARDCODED_YOUTUBE_MUSIC_KEY =
108- {"AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30" , "67" , "1.20220110.00 .00" };
108+ {"AIzaSyC9XL3ZjWddXya6X74dJoCTL-WEYFDNX30" , "67" , "1.20220309.01 .00" };
109109 private static String [] youtubeMusicKey ;
110110
111111 private static boolean keyAndVersionExtracted = false ;
@@ -973,44 +973,37 @@ public static JsonObject getJsonAndroidPostResponse(
973973 final byte [] body ,
974974 @ Nonnull final Localization localization ,
975975 @ Nullable final String endPartOfUrlRequest ) throws IOException , ExtractionException {
976- final Map <String , List <String >> headers = new HashMap <>();
977- headers .put ("Content-Type" , Collections .singletonList ("application/json" ));
978- // Spoofing an Android 11 device with the hardcoded version of the Android app
979- headers .put ("User-Agent" , Collections .singletonList ("com.google.android.youtube/"
980- + MOBILE_YOUTUBE_CLIENT_VERSION + " (Linux; U; Android 11; "
981- + localization .getCountryCode () + ") gzip" ));
982- headers .put ("X-Goog-Api-Format-Version" , Collections .singletonList ("2" ));
983-
984- final String baseEndpointUrl = "https://youtubei.googleapis.com/youtubei/v1/" + endpoint
985- + "?key=" + ANDROID_YOUTUBE_KEY + DISABLE_PRETTY_PRINT_PARAMETER ;
986-
987- final Response response = getDownloader ().post (isNullOrEmpty (endPartOfUrlRequest )
988- ? baseEndpointUrl : baseEndpointUrl + endPartOfUrlRequest ,
989- headers , body , localization );
990-
991- return JsonUtils .toJsonObject (getValidJsonResponseBody (response ));
976+ return getMobilePostResponse (endpoint , body , localization ,
977+ getAndroidUserAgent (localization ), ANDROID_YOUTUBE_KEY , endPartOfUrlRequest );
992978 }
993979
994980 public static JsonObject getJsonIosPostResponse (
995981 final String endpoint ,
996982 final byte [] body ,
997983 @ Nonnull final Localization localization ,
998984 @ Nullable final String endPartOfUrlRequest ) throws IOException , ExtractionException {
985+ return getMobilePostResponse (endpoint , body , localization , getIosUserAgent (localization ),
986+ IOS_YOUTUBE_KEY , endPartOfUrlRequest );
987+ }
988+
989+ private static JsonObject getMobilePostResponse (
990+ final String endpoint ,
991+ final byte [] body ,
992+ @ Nonnull final Localization localization ,
993+ @ Nonnull final String userAgent ,
994+ @ Nonnull final String key ,
995+ @ Nullable final String endPartOfUrlRequest ) throws IOException , ExtractionException {
999996 final Map <String , List <String >> headers = new HashMap <>();
1000997 headers .put ("Content-Type" , Collections .singletonList ("application/json" ));
1001- // Spoofing an iPhone 13 running iOS 15.2 with the hardcoded mobile client version
1002- headers .put ("User-Agent" , Collections .singletonList ("com.google.ios.youtube/"
1003- + MOBILE_YOUTUBE_CLIENT_VERSION + "(iPhone14,5; U; CPU iOS 15_2 like Mac OS X; "
1004- + localization .getCountryCode () + ")" ));
998+ headers .put ("User-Agent" , Collections .singletonList (userAgent ));
1005999 headers .put ("X-Goog-Api-Format-Version" , Collections .singletonList ("2" ));
10061000
10071001 final String baseEndpointUrl = "https://youtubei.googleapis.com/youtubei/v1/" + endpoint
1008- + "?key=" + IOS_YOUTUBE_KEY + DISABLE_PRETTY_PRINT_PARAMETER ;
1002+ + "?key=" + key + DISABLE_PRETTY_PRINT_PARAMETER ;
10091003
10101004 final Response response = getDownloader ().post (isNullOrEmpty (endPartOfUrlRequest )
10111005 ? baseEndpointUrl : baseEndpointUrl + endPartOfUrlRequest ,
10121006 headers , body , localization );
1013-
10141007 return JsonUtils .toJsonObject (getValidJsonResponseBody (response ));
10151008 }
10161009
@@ -1233,6 +1226,48 @@ public static byte[] createDesktopPlayerBody(
12331226 // @formatter:on
12341227 }
12351228
1229+ /**
1230+ * Get the user-agent string used as the user-agent for InnerTube requests with the Android
1231+ * client.
1232+ *
1233+ * If the {@link Localization} provided is {@code null}, fallbacks to
1234+ * {@link Localization#DEFAULT the default one}.
1235+ *
1236+ * @param localization the {@link Localization} to set in the user-agent
1237+ * @return the Android user-agent used for InnerTube requests with the Android client,
1238+ * depending on the {@link Localization} provided
1239+ */
1240+ @ Nonnull
1241+ public static String getAndroidUserAgent (@ Nullable final Localization localization ) {
1242+ // Spoofing an Android 12 device with the hardcoded version of the Android app
1243+ return "com.google.android.youtube/" + MOBILE_YOUTUBE_CLIENT_VERSION
1244+ + " (Linux; U; Android 12; "
1245+ + (localization != null ? localization .getCountryCode ()
1246+ : Localization .DEFAULT .getCountryCode ())
1247+ + ") gzip" ;
1248+ }
1249+
1250+ /**
1251+ * Get the user-agent string used as the user-agent for InnerTube requests with the iOS
1252+ * client.
1253+ *
1254+ * If the {@link Localization} provided is {@code null}, fallbacks to
1255+ * {@link Localization#DEFAULT the default one}.
1256+ *
1257+ * @param localization the {@link Localization} to set in the user-agent
1258+ * @return the iOS user-agent used for InnerTube requests with the iOS client, depending on the
1259+ * {@link Localization} provided
1260+ */
1261+ @ Nonnull
1262+ public static String getIosUserAgent (@ Nullable final Localization localization ) {
1263+ // Spoofing an iPhone 13 running iOS 15.4 with the hardcoded mobile client version
1264+ return "com.google.ios.youtube/" + MOBILE_YOUTUBE_CLIENT_VERSION
1265+ + "(iPhone14,5; U; CPU iOS 15_4 like Mac OS X; "
1266+ + (localization != null ? localization .getCountryCode ()
1267+ : Localization .DEFAULT .getCountryCode ())
1268+ + ")" ;
1269+ }
1270+
12361271 /**
12371272 * Add required headers and cookies to an existing headers Map.
12381273 * @see #addClientInfoHeaders(Map)
0 commit comments