@@ -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