MD5 校验值:61e58c10a11e4adec8760ee3854e996a
YoutubeParsingHelper.java 文件包含反编译后的源代码,请注意,该内容仅供学习和参考使用,不得用于非法用途。
package org.schabi.newpipe.extractor.services.youtube; import S5.j; import S5.l; import V1.z; import a4.C0230a; import a4.C0231b; import androidx.fragment.app.X; import f0.AbstractC1761a; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeParseException; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Random; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.stream.Stream; import l3.AbstractC2026e; import org.apache.http.HttpHeaders; import org.apache.http.HttpHost; import org.apache.http.cookie.SM; import org.schabi.newpipe.extractor.Image; import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.downloader.Downloader; import org.schabi.newpipe.extractor.downloader.Response; import org.schabi.newpipe.extractor.exceptions.AccountTerminatedException; import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException; import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.playlist.PlaylistInfo; import org.schabi.newpipe.extractor.stream.AudioTrackType; import org.schabi.newpipe.extractor.utils.JsonUtils; import org.schabi.newpipe.extractor.utils.Parser; import org.schabi.newpipe.extractor.utils.RandomStringFromAlphabetGenerator; import org.schabi.newpipe.extractor.utils.Utils; import p4.r; public final class YoutubeParsingHelper { private static final String ANDROID_YOUTUBE_CLIENT_VERSION = "19.28.35"; public static final String CONTENT_CHECK_OK = "contentCheckOk"; private static final String CONTENT_PLAYBACK_NONCE_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; public static final String CPN = "cpn"; public static final String DISABLE_PRETTY_PRINT_PARAMETER = "prettyPrint=false"; private static final String FEED_BASE_CHANNEL_ID = "https://www.youtube.com/feeds/videos.xml?channel_id="; private static final String FEED_BASE_USER = "https://www.youtube.com/feeds/videos.xml?user="; private static final Set<String> GOOGLE_URLS; private static final String HARDCODED_CLIENT_VERSION = "2.20240718.01.00"; private static final String HARDCODED_YOUTUBE_MUSIC_CLIENT_VERSION = "1.20240715.01.00"; private static final Set<String> INVIDIOUS_URLS; private static final String IOS_DEVICE_MODEL = "iPhone16,2"; private static final String IOS_OS_VERSION = "17.5.1.21F90"; private static final String IOS_USER_AGENT_VERSION = "17_5_1"; private static final String IOS_YOUTUBE_CLIENT_VERSION = "19.28.1"; public static final String RACY_CHECK_OK = "racyCheckOk"; private static final String TVHTML5_SIMPLY_EMBED_CLIENT_VERSION = "2.0"; public static final String VIDEO_ID = "videoId"; private static final String WEB_CLIENT_ID = "1"; public static final String YOUTUBEI_V1_GAPIS_URL = "https://youtubei.googleapis.com/youtubei/v1/"; public static final String YOUTUBEI_V1_URL = "https://www.youtube.com/youtubei/v1/"; private static final String YOUTUBE_MUSIC_CLIENT_ID = "67"; private static final String YOUTUBE_MUSIC_URL = "https://music.youtube.com"; private static final Set<String> YOUTUBE_URLS; private static String clientVersion = null; private static boolean clientVersionExtracted = false; private static boolean consentAccepted; private static String youtubeMusicClientVersion; private static Optional<Boolean> hardcodedClientVersionValid = Optional.empty(); private static final String[] INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES = {"INNERTUBE_CONTEXT_CLIENT_VERSION\":\"([0-9\\.]+?)\"", "innertube_context_client_version\":\"([0-9\\.]+?)\"", "client.version=([0-9\\.]+)"}; private static final String[] INITIAL_DATA_REGEXES = {"window\\[\"ytInitialData\"\\]\\s*=\\s*(\\{.*?\\});", "var\\s*ytInitialData\\s*=\\s*(\\{.*?\\});"}; private static Random numberGenerator = new Random(); private static final Pattern C_WEB_PATTERN = Pattern.compile("&c=WEB"); private static final Pattern C_TVHTML5_SIMPLY_EMBEDDED_PLAYER_PATTERN = Pattern.compile("&c=TVHTML5_SIMPLY_EMBEDDED_PLAYER"); private static final Pattern C_ANDROID_PATTERN = Pattern.compile("&c=ANDROID"); private static final Pattern C_IOS_PATTERN = Pattern.compile("&c=IOS"); static { Object[] objArr = {"google.", "m.google.", "www.google."}; HashSet hashSet = new HashSet(3); for (int i5 = 0; i5 < 3; i5++) { Object obj = objArr[i5]; Objects.requireNonNull(obj); if (!hashSet.add(obj)) { throw new IllegalArgumentException("duplicate element: " + obj); } } GOOGLE_URLS = Collections.unmodifiableSet(hashSet); String[] strArr = {"invidio.us", "dev.invidio.us", "www.invidio.us", "redirect.invidious.io", "invidious.snopyta.org", "yewtu.be", "tube.connect.cafe", "tubus.eduvid.org", "invidious.kavin.rocks", "invidious.site", "invidious-us.kavin.rocks", "piped.kavin.rocks", "vid.mint.lgbt", "invidiou.site", "invidious.fdn.fr", "invidious.048596.xyz", "invidious.zee.li", "vid.puffyan.us", "ytprivate.com", "invidious.namazso.eu", "invidious.silkky.cloud", "ytb.trom.tf", "invidious.exonip.de", "inv.riverside.rocks", "invidious.blamefran.net", "y.com.cm", "invidious.moomoo.me", "yt.cyberhost.uk"}; HashSet hashSet2 = new HashSet(28); for (int i6 = 0; i6 < 28; i6++) { String str = strArr[i6]; Objects.requireNonNull(str); if (!hashSet2.add(str)) { throw new IllegalArgumentException("duplicate element: " + ((Object) str)); } } INVIDIOUS_URLS = Collections.unmodifiableSet(hashSet2); Object[] objArr2 = {"youtube.com", "www.youtube.com", "m.youtube.com", "music.youtube.com"}; HashSet hashSet3 = new HashSet(4); for (int i7 = 0; i7 < 4; i7++) { Object obj2 = objArr2[i7]; Objects.requireNonNull(obj2); if (!hashSet3.add(obj2)) { throw new IllegalArgumentException("duplicate element: " + obj2); } } YOUTUBE_URLS = Collections.unmodifiableSet(hashSet3); consentAccepted = false; } private YoutubeParsingHelper() { } private static int convertDurationToInt(String str) { if (str != null && !str.isEmpty()) { try { return Integer.parseInt(Utils.removeNonDigitCharacters(str)); } catch (NumberFormatException unused) { } } return 0; } public static byte[] createTvHtml5EmbedPlayerBody(Localization localization, ContentCountry contentCountry, String str, Integer num, String str2) { C0231b prepareTvHtml5EmbedJsonBuilder = prepareTvHtml5EmbedJsonBuilder(localization, contentCountry, str); prepareTvHtml5EmbedJsonBuilder.c("playbackContext"); prepareTvHtml5EmbedJsonBuilder.c("contentPlaybackContext"); prepareTvHtml5EmbedJsonBuilder.e(num, "signatureTimestamp"); prepareTvHtml5EmbedJsonBuilder.e("https://www.youtube.com/watch?v=" + str, "referer"); prepareTvHtml5EmbedJsonBuilder.b(); prepareTvHtml5EmbedJsonBuilder.b(); prepareTvHtml5EmbedJsonBuilder.e(str2, CPN); prepareTvHtml5EmbedJsonBuilder.e(str, VIDEO_ID); prepareTvHtml5EmbedJsonBuilder.f(CONTENT_CHECK_OK, true); prepareTvHtml5EmbedJsonBuilder.f(RACY_CHECK_OK, true); return AbstractC2026e.w(prepareTvHtml5EmbedJsonBuilder.f4553b).getBytes(StandardCharsets.UTF_8); } public static void defaultAlertsCheck(a4.c cVar) { C0230a b7 = cVar.b("alerts"); if (!Utils.isNullOrEmpty(b7)) { a4.c f7 = b7.c(0).f("alertRenderer"); String textFromObject = getTextFromObject(f7.f("text")); if (f7.h("type", "").equalsIgnoreCase("ERROR")) { if (textFromObject != null && (textFromObject.contains("This account has been terminated") || textFromObject.contains("This channel was removed"))) { if (!textFromObject.matches(".*violat(ed|ion|ing).*") && !textFromObject.contains("infringement")) { throw new AccountTerminatedException(textFromObject); } throw new AccountTerminatedException(textFromObject, AccountTerminatedException.Reason.VIOLATION); } throw new ContentNotAvailableException(AbstractC1761a.h("Got error: \"", textFromObject, "\"")); } } } public static AudioTrackType extractAudioTrackType(String str) { String str2; try { String queryValue = Utils.getQueryValue(new URL(str), "xtags"); if (queryValue == null) { return null; } String[] split = queryValue.split(":"); int length = split.length; boolean z6 = false; int i5 = 0; while (true) { if (i5 >= length) { str2 = null; break; } String[] split2 = split[i5].split("=", 2); if (split2.length > 1 && split2[0].equals("acont")) { str2 = split2[1]; break; } i5++; } if (str2 == null) { return null; } switch (str2.hashCode()) { case -1724545844: break; case -1320983312: if (str2.equals("dubbed")) { z6 = true; break; } z6 = -1; break; case 1379043793: if (str2.equals("original")) { z6 = 2; break; } z6 = -1; break; default: z6 = -1; break; } switch (z6) { case false: return AudioTrackType.DESCRIPTIVE; case true: return AudioTrackType.DUBBED; case true: return AudioTrackType.ORIGINAL; default: return null; } } catch (MalformedURLException unused) { return null; } } public static String extractCachedUrlIfNeeded(String str) { if (str == null) { return null; } return str.contains("webcache.googleusercontent.com") ? str.split("cache:")[1] : str; } private static void extractClientVersionFromHtmlSearchResultsPage() { if (clientVersionExtracted) { return; } String responseBody = NewPipe.getDownloader().get("https://www.youtube.com/results?search_query=&ucbcb=1", getCookieHeader()).responseBody(); Stream map = getInitialData(responseBody).f("responseContext").b("serviceTrackingParams").stream().filter(new Z5.a(7)).map(new l(17)); String clientVersionFromServiceTrackingParam = getClientVersionFromServiceTrackingParam(map, "CSI", "cver"); clientVersion = clientVersionFromServiceTrackingParam; if (clientVersionFromServiceTrackingParam == null) { try { clientVersion = Utils.getStringResultFromRegexArray(responseBody, INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1); } catch (Parser.RegexException unused) { } } if (Utils.isNullOrEmpty(clientVersion)) { clientVersion = getClientVersionFromServiceTrackingParam(map, "ECATCHER", "client.version"); } if (clientVersion == null) { throw new ParsingException("Could not extract YouTube WEB InnerTube client version from HTML search results page"); } clientVersionExtracted = true; } private static void extractClientVersionFromSwJs() { if (clientVersionExtracted) { return; } try { clientVersion = Utils.getStringResultFromRegexArray(NewPipe.getDownloader().get("https://www.youtube.com/sw.js", getOriginReferrerHeaders("https://www.youtube.com")).responseBody(), INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1); clientVersionExtracted = true; } catch (Parser.RegexException e) { throw new ParsingException("Could not extract YouTube WEB InnerTube client version from sw.js", e); } } public static String extractCookieValue(String str, Response response) { List<String> list = response.responseHeaders().get("set-cookie"); String str2 = ""; if (list == null) { return ""; } for (String str3 : list) { int indexOf = str3.indexOf(str); if (indexOf != -1) { str2 = str3.substring(str.length() + indexOf + 1, str3.indexOf(";", indexOf)); } } return str2; } public static PlaylistInfo.PlaylistType extractPlaylistTypeFromPlaylistId(String str) { if (Utils.isNullOrEmpty(str)) { throw new ParsingException("Could not extract playlist type from empty playlist id"); } return isYoutubeMusicMixId(str) ? PlaylistInfo.PlaylistType.MIX_MUSIC : isYoutubeChannelMixId(str) ? PlaylistInfo.PlaylistType.MIX_CHANNEL : isYoutubeGenreMixId(str) ? PlaylistInfo.PlaylistType.MIX_GENRE : isYoutubeMixId(str) ? PlaylistInfo.PlaylistType.MIX_STREAM : PlaylistInfo.PlaylistType.NORMAL; } public static PlaylistInfo.PlaylistType extractPlaylistTypeFromPlaylistUrl(String str) { try { return extractPlaylistTypeFromPlaylistId(Utils.getQueryValue(Utils.stringToURL(str), "list")); } catch (MalformedURLException e) { throw new ParsingException("Could not extract playlist type from malformed url", e); } } public static String extractVideoIdFromMixId(String str) { int i5; if (!Utils.isNullOrEmpty(str)) { if (isYoutubeMyMixId(str)) { i5 = 4; } else if (isYoutubeMusicMixId(str)) { i5 = 6; } else if (!isYoutubeChannelMixId(str)) { if (!isYoutubeGenreMixId(str)) { if (isYoutubeMixId(str)) { if (str.length() == 13) { i5 = 2; } else { throw new ParsingException("Video id could not be determined from mix id: ".concat(str)); } } else { throw new ParsingException(r.n("Video id could not be determined from playlist id: ", str)); } } else { throw new ParsingException(r.n("Video id could not be determined from genre mix id: ", str)); } } else { throw new ParsingException(r.n("Video id could not be determined from channel mix id: ", str)); } return str.substring(i5); } throw new ParsingException("Video id could not be determined from empty playlist id"); } public static String fixThumbnailUrl(String str) { if (str.startsWith("//")) { str = str.substring(2); } return str.startsWith(Utils.HTTP) ? Utils.replaceHttpWithHttps(str) : !str.startsWith(Utils.HTTPS) ? Utils.HTTPS.concat(str) : str; } public static String generateConsentCookie() { return "SOCS=".concat(isConsentAccepted() ? "CAISAiAD" : "CAE="); } public static String generateContentPlaybackNonce() { return RandomStringFromAlphabetGenerator.generate(CONTENT_PLAYBACK_NONCE_ALPHABET, 16, numberGenerator); } public static String generateTParameter() { return RandomStringFromAlphabetGenerator.generate(CONTENT_PLAYBACK_NONCE_ALPHABET, 12, numberGenerator); } public static String getAndroidUserAgent(Localization localization) { if (localization == null) { localization = Localization.DEFAULT; } return AbstractC1761a.h("com.google.android.youtube/19.28.35 (Linux; U; Android 14; ", localization.getCountryCode(), ") gzip"); } private static Map<String, List<String>> getClientHeaders(String str, String str2) { ArrayList arrayList = new ArrayList(1); Object obj = new Object[]{str}[0]; List w6 = X.w(obj, arrayList, obj, arrayList); ArrayList arrayList2 = new ArrayList(1); Object obj2 = new Object[]{str2}[0]; Map.Entry[] entryArr = {new AbstractMap.SimpleEntry("X-YouTube-Client-Name", w6), new AbstractMap.SimpleEntry("X-YouTube-Client-Version", X.w(obj2, arrayList2, obj2, arrayList2))}; HashMap hashMap = new HashMap(2); for (int i5 = 0; i5 < 2; i5++) { Map.Entry entry = entryArr[i5]; Object key = entry.getKey(); Objects.requireNonNull(key); Object value = entry.getValue(); Objects.requireNonNull(value); if (hashMap.put(key, value) != null) { throw new IllegalArgumentException("duplicate key: " + key); } } return Collections.unmodifiableMap(hashMap); } public static Map<String, List<String>> getClientInfoHeaders() { HashMap hashMap = new HashMap(getOriginReferrerHeaders("https://www.youtube.com")); hashMap.putAll(getClientHeaders(WEB_CLIENT_ID, getClientVersion())); return hashMap; } public static String getClientVersion() { if (!Utils.isNullOrEmpty(clientVersion)) { return clientVersion; } try { extractClientVersionFromSwJs(); } catch (Exception unused) { extractClientVersionFromHtmlSearchResultsPage(); } if (clientVersionExtracted) { return clientVersion; } if (!isHardcodedClientVersionValid()) { throw new ExtractionException("Could not get YouTube WEB client version"); } clientVersion = HARDCODED_CLIENT_VERSION; return HARDCODED_CLIENT_VERSION; } private static String getClientVersionFromServiceTrackingParam(Stream<a4.c> stream, String str, String str2) { return (String) stream.filter(new W5.a(str, 7)).flatMap(new a(11)).filter(new Z5.a(7)).map(new l(17)).filter(new W5.a(str2, 8)).map(new a(12)).filter(new b(7)).findFirst().orElse(null); } public static Map<String, List<String>> getCookieHeader() { Object[] objArr = {generateConsentCookie()}; ArrayList arrayList = new ArrayList(1); Object obj = objArr[0]; Map.Entry[] entryArr = {new AbstractMap.SimpleEntry(SM.COOKIE, X.w(obj, arrayList, obj, arrayList))}; HashMap hashMap = new HashMap(1); Map.Entry entry = entryArr[0]; Object key = entry.getKey(); Objects.requireNonNull(key); Object value = entry.getValue(); Objects.requireNonNull(value); if (hashMap.put(key, value) == null) { return Collections.unmodifiableMap(hashMap); } throw new IllegalArgumentException("duplicate key: " + key); } public static String getFeedUrlFrom(String str) { if (str.startsWith("user/")) { return r.n(FEED_BASE_USER, str.replace("user/", "")); } if (str.startsWith("channel/")) { return r.n(FEED_BASE_CHANNEL_ID, str.replace("channel/", "")); } return FEED_BASE_CHANNEL_ID.concat(str); } public static List<Image> getImagesFromThumbnailsArray(C0230a c0230a) { Collector unmodifiableList; Stream map = c0230a.stream().filter(new Z5.a(7)).map(new l(17)).filter(new b(6)).map(new a(10)); unmodifiableList = Collectors.toUnmodifiableList(); return (List) map.collect(unmodifiableList); } private static a4.c getInitialData(String str) { try { return (a4.c) z.h().H(Utils.getStringResultFromRegexArray(str, INITIAL_DATA_REGEXES, 1)); } catch (a4.d | Parser.RegexException e) { throw new ParsingException("Could not get ytInitialData", e); } } public static String getIosUserAgent(Localization localization) { if (localization == null) { localization = Localization.DEFAULT; } return AbstractC1761a.h("com.google.ios.youtube/19.28.1(iPhone16,2; U; CPU iOS 17_5_1 like Mac OS X; ", localization.getCountryCode(), ")"); } public static a4.c getJsonAndroidPostResponse(String str, byte[] bArr, Localization localization, String str2) { return getMobilePostResponse(str, bArr, localization, getAndroidUserAgent(localization), str2); } public static a4.c getJsonIosPostResponse(String str, byte[] bArr, Localization localization, String str2) { return getMobilePostResponse(str, bArr, localization, getIosUserAgent(localization), str2); } public static a4.c getJsonPostResponse(String str, byte[] bArr, Localization localization) { return JsonUtils.toJsonObject(getValidJsonResponseBody(NewPipe.getDownloader().postWithContentTypeJson(AbstractC1761a.h(YOUTUBEI_V1_URL, str, "?prettyPrint=false"), getYouTubeHeaders(), bArr, localization))); } private static a4.c getMobilePostResponse(String str, byte[] bArr, Localization localization, String str2, String str3) { ArrayList arrayList = new ArrayList(1); Object obj = new Object[]{str2}[0]; List w6 = X.w(obj, arrayList, obj, arrayList); ArrayList arrayList2 = new ArrayList(1); Object obj2 = new Object[]{"2"}[0]; Map.Entry[] entryArr = {new AbstractMap.SimpleEntry("User-Agent", w6), new AbstractMap.SimpleEntry("X-Goog-Api-Format-Version", X.w(obj2, arrayList2, obj2, arrayList2))}; HashMap hashMap = new HashMap(2); for (int i5 = 0; i5 < 2; i5++) { Map.Entry entry = entryArr[i5]; Object key = entry.getKey(); Objects.requireNonNull(key); Object value = entry.getValue(); Objects.requireNonNull(value); if (hashMap.put(key, value) != null) { throw new IllegalArgumentException("duplicate key: " + key); } } Map<String, List<String>> unmodifiableMap = Collections.unmodifiableMap(hashMap); String h6 = AbstractC1761a.h(YOUTUBEI_V1_GAPIS_URL, str, "?prettyPrint=false"); Downloader downloader = NewPipe.getDownloader(); if (!Utils.isNullOrEmpty(str3)) { h6 = r.h(h6, str3); } return JsonUtils.toJsonObject(getValidJsonResponseBody(downloader.postWithContentTypeJson(h6, unmodifiableMap, bArr, localization))); } private static Map<String, List<String>> getOriginReferrerHeaders(String str) { ArrayList arrayList = new ArrayList(1); Object obj = new Object[]{str}[0]; List w6 = X.w(obj, arrayList, obj, arrayList); Map.Entry[] entryArr = {new AbstractMap.SimpleEntry("Origin", w6), new AbstractMap.SimpleEntry(HttpHeaders.REFERER, w6)}; HashMap hashMap = new HashMap(2); for (int i5 = 0; i5 < 2; i5++) { Map.Entry entry = entryArr[i5]; Object key = entry.getKey(); Objects.requireNonNull(key); Object value = entry.getValue(); Objects.requireNonNull(value); if (hashMap.put(key, value) != null) { throw new IllegalArgumentException("duplicate key: " + key); } } return Collections.unmodifiableMap(hashMap); } public static String getTextAtKey(a4.c cVar, String str) { if (cVar.get(str) instanceof String) { return cVar.h(str, null); } return getTextFromObject(cVar.f(str)); } public static String getTextFromObject(a4.c cVar) { return getTextFromObject(cVar, false); } public static String getTextFromObjectOrThrow(a4.c cVar, String str) { String textFromObject = getTextFromObject(cVar); if (textFromObject != null) { return textFromObject; } throw new ParsingException(r.n("Could not extract text: ", str)); } public static List<Image> getThumbnailsFromInfoItem(a4.c cVar) { try { return getImagesFromThumbnailsArray(cVar.f("thumbnail").b("thumbnails")); } catch (Exception e) { throw new ParsingException("Could not get thumbnails from InfoItem", e); } } public static String getUrlFromNavigationEndpoint(a4.c cVar) { if (cVar.containsKey("urlEndpoint")) { String h6 = cVar.f("urlEndpoint").h("url", null); if (h6.startsWith("https://www.youtube.com/redirect?")) { h6 = h6.substring(23); } if (h6.startsWith("/redirect?")) { for (String str : h6.substring(10).split("&")) { if (str.split("=")[0].equals("q")) { return Utils.decodeUrlUtf8(str.split("=")[1]); } } } else { if (h6.startsWith(HttpHost.DEFAULT_SCHEME_NAME)) { return h6; } if (h6.startsWith("/channel") || h6.startsWith("/user") || h6.startsWith("/watch")) { return "https://www.youtube.com".concat(h6); } } } if (cVar.containsKey("browseEndpoint")) { a4.c f7 = cVar.f("browseEndpoint"); String h7 = f7.h("canonicalBaseUrl", null); String h8 = f7.h("browseId", null); if (h8 != null) { if (h8.startsWith("UC")) { return "https://www.youtube.com/channel/".concat(h8); } if (h8.startsWith("VL")) { return r.n("https://www.youtube.com/playlist?list=", h8.substring(2)); } } if (!Utils.isNullOrEmpty(h7)) { return r.n("https://www.youtube.com", h7); } } if (cVar.containsKey("watchEndpoint")) { StringBuilder sb = new StringBuilder("https://www.youtube.com/watch?v="); sb.append(cVar.f("watchEndpoint").h(VIDEO_ID, null)); if (cVar.f("watchEndpoint").containsKey("playlistId")) { sb.append("&list="); sb.append(cVar.f("watchEndpoint").h("playlistId", null)); } if (cVar.f("watchEndpoint").containsKey("startTimeSeconds")) { sb.append("&t="); sb.append(cVar.f("watchEndpoint").d(0, "startTimeSeconds")); } return sb.toString(); } if (cVar.containsKey("watchPlaylistEndpoint")) { return r.n("https://www.youtube.com/playlist?list=", cVar.f("watchPlaylistEndpoint").h("playlistId", null)); } if (cVar.containsKey("commandMetadata")) { a4.c f8 = cVar.f("commandMetadata").f("webCommandMetadata"); if (f8.containsKey("url")) { return r.n("https://www.youtube.com", f8.h("url", null)); } } return null; } public static String getUrlFromObject(a4.c cVar) { if (Utils.isNullOrEmpty(cVar)) { return null; } C0230a b7 = cVar.b("runs"); if (b7.isEmpty()) { return null; } Iterator<E> it = b7.iterator(); while (it.hasNext()) { String urlFromNavigationEndpoint = getUrlFromNavigationEndpoint(((a4.c) it.next()).f("navigationEndpoint")); if (!Utils.isNullOrEmpty(urlFromNavigationEndpoint)) { return urlFromNavigationEndpoint; } } return null; } public static String getValidJsonResponseBody(Response response) { if (response.responseCode() != 404) { String responseBody = response.responseBody(); if (responseBody.length() >= 50) { URL url = new URL(response.latestUrl()); if (url.getHost().equalsIgnoreCase("www.youtube.com")) { String path = url.getPath(); if (path.equalsIgnoreCase("/oops") || path.equalsIgnoreCase("/error")) { throw new ContentNotAvailableException("Content unavailable"); } } String header = response.getHeader("Content-Type"); if (header != null && header.toLowerCase().contains("text/html")) { throw new ParsingException(AbstractC1761a.h("Got HTML document, expected JSON response (latest url was: \"", response.latestUrl(), "\")")); } return responseBody; } throw new ParsingException("JSON response is too short"); } throw new ContentNotAvailableException("Not found (\"" + response.responseCode() + org.schabi.newpipe.extractor.stream.Stream.ID_UNKNOWN + response.responseMessage() + "\")"); } public static a4.c getWebPlayerResponse(Localization localization, ContentCountry contentCountry, String str) { C0231b prepareDesktopJsonBuilder = prepareDesktopJsonBuilder(localization, contentCountry); prepareDesktopJsonBuilder.e(str, VIDEO_ID); prepareDesktopJsonBuilder.f(CONTENT_CHECK_OK, true); prepareDesktopJsonBuilder.f(RACY_CHECK_OK, true); return JsonUtils.toJsonObject(getValidJsonResponseBody(NewPipe.getDownloader().postWithContentTypeJson("https://www.youtube.com/youtubei/v1/player?prettyPrint=false&$fields=microformat,playabilityStatus,storyboards,videoDetails", getYouTubeHeaders(), AbstractC2026e.w(prepareDesktopJsonBuilder.f4553b).getBytes(StandardCharsets.UTF_8), localization))); } public static Map<String, List<String>> getYouTubeHeaders() { Map<String, List<String>> clientInfoHeaders = getClientInfoHeaders(); Object[] objArr = {generateConsentCookie()}; ArrayList arrayList = new ArrayList(1); Object obj = objArr[0]; clientInfoHeaders.put(SM.COOKIE, X.w(obj, arrayList, obj, arrayList)); return clientInfoHeaders; } public static String getYoutubeMusicClientVersion() { if (!Utils.isNullOrEmpty(youtubeMusicClientVersion)) { return youtubeMusicClientVersion; } if (isHardcodedYoutubeMusicClientVersionValid()) { youtubeMusicClientVersion = HARDCODED_YOUTUBE_MUSIC_CLIENT_VERSION; return HARDCODED_YOUTUBE_MUSIC_CLIENT_VERSION; } try { youtubeMusicClientVersion = Utils.getStringResultFromRegexArray(NewPipe.getDownloader().get("https://music.youtube.com/sw.js", getOriginReferrerHeaders(YOUTUBE_MUSIC_URL)).responseBody(), INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1); } catch (Exception unused) { youtubeMusicClientVersion = Utils.getStringResultFromRegexArray(NewPipe.getDownloader().get("https://music.youtube.com/?ucbcb=1", getCookieHeader()).responseBody(), INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES, 1); } return youtubeMusicClientVersion; } public static Map<String, List<String>> getYoutubeMusicHeaders() { HashMap hashMap = new HashMap(getOriginReferrerHeaders(YOUTUBE_MUSIC_URL)); hashMap.putAll(getClientHeaders(YOUTUBE_MUSIC_CLIENT_ID, youtubeMusicClientVersion)); return hashMap; } public static boolean isAndroidStreamingUrl(String str) { return Parser.isMatch(C_ANDROID_PATTERN, str); } public static boolean isConsentAccepted() { return consentAccepted; } public static boolean isGoogleURL(String str) { try { return GOOGLE_URLS.stream().anyMatch(new j(new URL(extractCachedUrlIfNeeded(str)), 2)); } catch (MalformedURLException unused) { return false; } } public static boolean isHardcodedClientVersionValid() { if (hardcodedClientVersionValid.isPresent()) { return hardcodedClientVersionValid.get().booleanValue(); } a4.e eVar = new a4.e(); eVar.i(); eVar.j("context"); eVar.j("client"); eVar.r("hl", "en-GB"); eVar.r("gl", "GB"); eVar.r("clientName", "WEB"); eVar.r("clientVersion", HARDCODED_CLIENT_VERSION); eVar.r("platform", "DESKTOP"); eVar.m("utcOffsetMinutes"); boolean z6 = false; eVar.o(Integer.toString(0)); eVar.f(); eVar.j("request"); eVar.c("internalExperimentFlags"); eVar.f(); eVar.s("useSsl", true); eVar.f(); eVar.j("user"); eVar.s("lockedSafetyMode", false); eVar.f(); eVar.f(); eVar.s("fetchLiveState", true); eVar.f(); Response postWithContentTypeJson = NewPipe.getDownloader().postWithContentTypeJson("https://www.youtube.com/youtubei/v1/guide?prettyPrint=false", getClientHeaders(WEB_CLIENT_ID, HARDCODED_CLIENT_VERSION), eVar.d().getBytes(StandardCharsets.UTF_8)); String responseBody = postWithContentTypeJson.responseBody(); int responseCode = postWithContentTypeJson.responseCode(); if (responseBody.length() > 5000 && responseCode == 200) { z6 = true; } Optional<Boolean> of = Optional.of(Boolean.valueOf(z6)); hardcodedClientVersionValid = of; return of.get().booleanValue(); } public static boolean isHardcodedYoutubeMusicClientVersionValid() { a4.e eVar = new a4.e(); eVar.i(); eVar.j("context"); eVar.j("client"); eVar.r("clientName", "WEB_REMIX"); eVar.r("clientVersion", HARDCODED_YOUTUBE_MUSIC_CLIENT_VERSION); eVar.r("hl", "en-GB"); eVar.r("gl", "GB"); eVar.r("platform", "DESKTOP"); eVar.m("utcOffsetMinutes"); eVar.o(Integer.toString(0)); eVar.f(); eVar.j("request"); eVar.c("internalExperimentFlags"); eVar.f(); eVar.s("useSsl", true); eVar.f(); eVar.j("user"); eVar.s("lockedSafetyMode", false); eVar.f(); eVar.f(); eVar.r("input", ""); eVar.f(); byte[] bytes = eVar.d().getBytes(StandardCharsets.UTF_8); HashMap hashMap = new HashMap(getOriginReferrerHeaders(YOUTUBE_MUSIC_URL)); hashMap.putAll(getClientHeaders(YOUTUBE_MUSIC_CLIENT_ID, HARDCODED_YOUTUBE_MUSIC_CLIENT_VERSION)); Response postWithContentTypeJson = NewPipe.getDownloader().postWithContentTypeJson("https://music.youtube.com/youtubei/v1/music/get_search_suggestions?prettyPrint=false", hashMap, bytes); if (postWithContentTypeJson.responseBody().length() <= 500 || postWithContentTypeJson.responseCode() != 200) { return false; } return true; } public static boolean isHooktubeURL(URL url) { return url.getHost().equalsIgnoreCase("hooktube.com"); } public static boolean isInvidiousURL(URL url) { return INVIDIOUS_URLS.contains(url.getHost().toLowerCase(Locale.ROOT)); } public static boolean isIosStreamingUrl(String str) { return Parser.isMatch(C_IOS_PATTERN, str); } public static boolean isTvHtml5SimplyEmbeddedPlayerStreamingUrl(String str) { return Parser.isMatch(C_TVHTML5_SIMPLY_EMBEDDED_PLAYER_PATTERN, str); } public static boolean isVerified(C0230a c0230a) { if (Utils.isNullOrEmpty(c0230a)) { return false; } Iterator<E> it = c0230a.iterator(); while (it.hasNext()) { String h6 = ((a4.c) it.next()).f("metadataBadgeRenderer").h("style", null); if (h6 != null && (h6.equals("BADGE_STYLE_TYPE_VERIFIED") || h6.equals("BADGE_STYLE_TYPE_VERIFIED_ARTIST"))) { return true; } } return false; } public static boolean isWebStreamingUrl(String str) { return Parser.isMatch(C_WEB_PATTERN, str); } public static boolean isY2ubeURL(URL url) { return url.getHost().equalsIgnoreCase("y2u.be"); } public static boolean isYoutubeChannelMixId(String str) { return str.startsWith("RDCM"); } public static boolean isYoutubeGenreMixId(String str) { return str.startsWith("RDGMEM"); } public static boolean isYoutubeMixId(String str) { return str.startsWith("RD"); } public static boolean isYoutubeMusicMixId(String str) { return str.startsWith("RDAMVM") || str.startsWith("RDCLAK"); } public static boolean isYoutubeMyMixId(String str) { return str.startsWith("RDMM"); } public static boolean isYoutubeServiceURL(URL url) { String host = url.getHost(); return host.equalsIgnoreCase("www.youtube-nocookie.com") || host.equalsIgnoreCase("youtu.be"); } public static boolean isYoutubeURL(URL url) { return YOUTUBE_URLS.contains(url.getHost().toLowerCase(Locale.ROOT)); } public static boolean lambda$getClientVersionFromServiceTrackingParam$1(String str, a4.c cVar) { return cVar.h("service", "").equals(str); } public static Stream lambda$getClientVersionFromServiceTrackingParam$2(a4.c cVar) { return cVar.b("params").stream(); } public static boolean lambda$getClientVersionFromServiceTrackingParam$3(String str, a4.c cVar) { return cVar.h("key", "").equals(str); } public static boolean lambda$getClientVersionFromServiceTrackingParam$5(String str) { return !Utils.isNullOrEmpty(str); } public static boolean lambda$getImagesFromThumbnailsArray$6(a4.c cVar) { return !Utils.isNullOrEmpty(cVar.h("url", null)); } public static Image lambda$getImagesFromThumbnailsArray$7(a4.c cVar) { int d = cVar.d(-1, "height"); return new Image(fixThumbnailUrl(cVar.h("url", null)), d, cVar.d(-1, "width"), Image.ResolutionLevel.fromHeight(d)); } public static boolean lambda$isGoogleURL$0(URL url, String str) { return url.getHost().startsWith(str); } public static OffsetDateTime parseDateFrom(String str) { try { try { return OffsetDateTime.parse(str); } catch (DateTimeParseException e) { throw new ParsingException(AbstractC1761a.h("Could not parse date: \"", str, "\""), e); } } catch (DateTimeParseException unused) { return LocalDate.parse(str).atStartOfDay().atOffset(ZoneOffset.UTC); } } public static int parseDurationString(String str) { String[] split = str.split(str.contains(":") ? ":" : "\\."); int[] iArr = {24, 60, 60, 1}; int length = 4 - split.length; if (length < 0) { throw new ParsingException("Error duration string with unknown format: ".concat(str)); } int i5 = 0; for (int i6 = 0; i6 < split.length; i6++) { i5 = (i5 + convertDurationToInt(split[i6])) * iArr[i6 + length]; } return i5; } public static C0231b prepareAndroidMobileJsonBuilder(Localization localization, ContentCountry contentCountry) { C0231b a6 = a4.c.a(); a6.c("context"); a6.c("client"); a6.e("ANDROID", "clientName"); a6.e(ANDROID_YOUTUBE_CLIENT_VERSION, "clientVersion"); a6.e("MOBILE", "platform"); a6.e("Android", "osName"); a6.e("14", "osVersion"); a6.d(34, "androidSdkVersion"); a6.e(localization.getLocalizationCode(), "hl"); a6.e(contentCountry.getCountryCode(), "gl"); a6.d(0, "utcOffsetMinutes"); a6.b(); a6.c("request"); a6.a(); a6.b(); a6.f("useSsl", true); a6.b(); a6.c("user"); a6.f("lockedSafetyMode", false); a6.b(); a6.b(); return a6; } public static C0231b prepareDesktopJsonBuilder(Localization localization, ContentCountry contentCountry) { return prepareDesktopJsonBuilder(localization, contentCountry, null); } public static C0231b prepareIosMobileJsonBuilder(Localization localization, ContentCountry contentCountry) { C0231b a6 = a4.c.a(); a6.c("context"); a6.c("client"); a6.e("IOS", "clientName"); a6.e(IOS_YOUTUBE_CLIENT_VERSION, "clientVersion"); a6.e("Apple", "deviceMake"); a6.e(IOS_DEVICE_MODEL, "deviceModel"); a6.e("MOBILE", "platform"); a6.e("iOS", "osName"); a6.e(IOS_OS_VERSION, "osVersion"); a6.e(localization.getLocalizationCode(), "hl"); a6.e(contentCountry.getCountryCode(), "gl"); a6.d(0, "utcOffsetMinutes"); a6.b(); a6.c("request"); a6.a(); a6.b(); a6.f("useSsl", true); a6.b(); a6.c("user"); a6.f("lockedSafetyMode", false); a6.b(); a6.b(); return a6; } public static C0231b prepareTvHtml5EmbedJsonBuilder(Localization localization, ContentCountry contentCountry, String str) { C0231b a6 = a4.c.a(); a6.c("context"); a6.c("client"); a6.e("TVHTML5_SIMPLY_EMBEDDED_PLAYER", "clientName"); a6.e(TVHTML5_SIMPLY_EMBED_CLIENT_VERSION, "clientVersion"); a6.e("EMBED", "clientScreen"); a6.e("TV", "platform"); a6.e(localization.getLocalizationCode(), "hl"); a6.e(contentCountry.getCountryCode(), "gl"); a6.d(0, "utcOffsetMinutes"); a6.b(); a6.c("thirdParty"); a6.e("https://www.youtube.com/watch?v=" + str, "embedUrl"); a6.b(); a6.c("request"); a6.a(); a6.b(); a6.f("useSsl", true); a6.b(); a6.c("user"); a6.f("lockedSafetyMode", false); a6.b(); a6.b(); return a6; } public static void resetClientVersion() { clientVersion = null; clientVersionExtracted = false; } public static void setConsentAccepted(boolean z6) { consentAccepted = z6; } public static void setNumberGenerator(Random random) { numberGenerator = random; } public static String getTextFromObject(a4.c cVar, boolean z6) { if (Utils.isNullOrEmpty(cVar)) { return null; } if (cVar.containsKey("simpleText")) { return cVar.h("simpleText", null); } C0230a b7 = cVar.b("runs"); if (b7.isEmpty()) { return null; } StringBuilder sb = new StringBuilder(); Iterator<E> it = b7.iterator(); while (it.hasNext()) { a4.c cVar2 = (a4.c) it.next(); String h6 = cVar2.h("text", null); if (z6) { if (cVar2.containsKey("navigationEndpoint")) { String urlFromNavigationEndpoint = getUrlFromNavigationEndpoint(cVar2.f("navigationEndpoint")); if (!Utils.isNullOrEmpty(urlFromNavigationEndpoint)) { h6 = AbstractC1761a.j("<a href=\"", S5.r.b(urlFromNavigationEndpoint), "\">", S5.r.b(h6), "</a>"); } } boolean z7 = false; boolean z8 = cVar2.containsKey("bold") && cVar2.c("bold"); boolean z9 = cVar2.containsKey("italics") && cVar2.c("italics"); if (cVar2.containsKey("strikethrough") && cVar2.c("strikethrough")) { z7 = true; } if (z8) { sb.append("<b>"); } if (z9) { sb.append("<i>"); } if (z7) { sb.append("<s>"); } sb.append(h6); if (z7) { sb.append("</s>"); } if (z9) { sb.append("</i>"); } if (z8) { sb.append("</b>"); } } else { sb.append(h6); } } String sb2 = sb.toString(); return z6 ? sb2.replaceAll("\\n", "<br>").replaceAll(" {2}", " ") : sb2; } public static C0231b prepareDesktopJsonBuilder(Localization localization, ContentCountry contentCountry, String str) { C0231b a6 = a4.c.a(); a6.c("context"); a6.c("client"); a6.e(localization.getLocalizationCode(), "hl"); a6.e(contentCountry.getCountryCode(), "gl"); a6.e("WEB", "clientName"); a6.e(getClientVersion(), "clientVersion"); a6.e("https://www.youtube.com", "originalUrl"); a6.e("DESKTOP", "platform"); a6.d(0, "utcOffsetMinutes"); if (str != null) { a6.e(str, "visitorData"); } a6.b(); a6.c("request"); a6.a(); a6.b(); a6.f("useSsl", true); a6.b(); a6.c("user"); a6.f("lockedSafetyMode", false); a6.b(); a6.b(); return a6; } }