@@ -205,6 +205,7 @@ private YoutubeParsingHelper() {
205205 private static String [] youtubeMusicKey ;
206206
207207 private static boolean keyAndVersionExtracted = false ;
208+ private static final Object KEY_AND_VERSION_EXTRACTED_LOCK = new Object ();
208209 @ SuppressWarnings ("OptionalUsedAsFieldOrParameterType" )
209210 private static Optional <Boolean > hardcodedClientVersionAndKeyValid = Optional .empty ();
210211
@@ -575,80 +576,84 @@ public static boolean areHardcodedClientVersionAndKeyValid()
575576
576577 private static void extractClientVersionAndKeyFromSwJs ()
577578 throws IOException , ExtractionException {
578- if (keyAndVersionExtracted ) {
579- return ;
580- }
581- final String url = "https://www.youtube.com/sw.js" ;
582- final var headers = getOriginReferrerHeaders ("https://www.youtube.com" );
583- final String response = getDownloader ().get (url , headers ).responseBody ();
584- try {
585- clientVersion = getStringResultFromRegexArray (response ,
586- INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES , 1 );
587- key = getStringResultFromRegexArray (response , INNERTUBE_API_KEY_REGEXES , 1 );
588- } catch (final Parser .RegexException e ) {
589- throw new ParsingException ("Could not extract YouTube WEB InnerTube client version "
590- + "and API key from sw.js" , e );
579+ synchronized (KEY_AND_VERSION_EXTRACTED_LOCK ) {
580+ if (keyAndVersionExtracted ) {
581+ return ;
582+ }
583+ final String url = "https://www.youtube.com/sw.js" ;
584+ final var headers = getOriginReferrerHeaders ("https://www.youtube.com" );
585+ final String response = getDownloader ().get (url , headers ).responseBody ();
586+ try {
587+ clientVersion = getStringResultFromRegexArray (response ,
588+ INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES , 1 );
589+ key = getStringResultFromRegexArray (response , INNERTUBE_API_KEY_REGEXES , 1 );
590+ } catch (final Parser .RegexException e ) {
591+ throw new ParsingException ("Could not extract YouTube WEB InnerTube client version "
592+ + "and API key from sw.js" , e );
593+ }
594+ keyAndVersionExtracted = true ;
591595 }
592- keyAndVersionExtracted = true ;
593596 }
594597
595598 private static void extractClientVersionAndKeyFromHtmlSearchResultsPage ()
596599 throws IOException , ExtractionException {
597- // Don't extract the client version and the InnerTube key if it has been already extracted
598- if (keyAndVersionExtracted ) {
599- return ;
600- }
600+ synchronized (KEY_AND_VERSION_EXTRACTED_LOCK ) {
601+ // Don't extract the client version and the InnerTube key if it has been already extracted
602+ if (keyAndVersionExtracted ) {
603+ return ;
604+ }
601605
602- // Don't provide a search term in order to have a smaller response
603- final String url = "https://www.youtube.com/results?search_query=&ucbcb=1" ;
604- final String html = getDownloader ().get (url , getCookieHeader ()).responseBody ();
605- final JsonObject initialData = getInitialData (html );
606- final JsonArray serviceTrackingParams = initialData .getObject ("responseContext" )
607- .getArray ("serviceTrackingParams" );
606+ // Don't provide a search term in order to have a smaller response
607+ final String url = "https://www.youtube.com/results?search_query=&ucbcb=1" ;
608+ final String html = getDownloader ().get (url , getCookieHeader ()).responseBody ();
609+ final JsonObject initialData = getInitialData (html );
610+ final JsonArray serviceTrackingParams = initialData .getObject ("responseContext" )
611+ .getArray ("serviceTrackingParams" );
608612
609- // Try to get version from initial data first
610- final Stream <JsonObject > serviceTrackingParamsStream = serviceTrackingParams .stream ()
611- .filter (JsonObject .class ::isInstance )
612- .map (JsonObject .class ::cast );
613+ // Try to get version from initial data first
614+ final Stream <JsonObject > serviceTrackingParamsStream = serviceTrackingParams .stream ()
615+ .filter (JsonObject .class ::isInstance )
616+ .map (JsonObject .class ::cast );
617+
618+ clientVersion = getClientVersionFromServiceTrackingParam (
619+ serviceTrackingParamsStream , "CSI" , "cver" );
613620
614- clientVersion = getClientVersionFromServiceTrackingParam (
615- serviceTrackingParamsStream , "CSI" , "cver" );
621+ if (clientVersion == null ) {
622+ try {
623+ clientVersion = getStringResultFromRegexArray (html ,
624+ INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES , 1 );
625+ } catch (final Parser .RegexException ignored ) {
626+ }
627+ }
628+
629+ // Fallback to get a shortened client version which does not contain the last two
630+ // digits
631+ if (isNullOrEmpty (clientVersion )) {
632+ clientVersion = getClientVersionFromServiceTrackingParam (
633+ serviceTrackingParamsStream , "ECATCHER" , "client.version" );
634+ }
616635
617- if (clientVersion == null ) {
618636 try {
619- clientVersion = getStringResultFromRegexArray (html ,
620- INNERTUBE_CONTEXT_CLIENT_VERSION_REGEXES , 1 );
637+ key = getStringResultFromRegexArray (html , INNERTUBE_API_KEY_REGEXES , 1 );
621638 } catch (final Parser .RegexException ignored ) {
622639 }
623- }
624-
625- // Fallback to get a shortened client version which does not contain the last two
626- // digits
627- if (isNullOrEmpty (clientVersion )) {
628- clientVersion = getClientVersionFromServiceTrackingParam (
629- serviceTrackingParamsStream , "ECATCHER" , "client.version" );
630- }
631640
632- try {
633- key = getStringResultFromRegexArray (html , INNERTUBE_API_KEY_REGEXES , 1 );
634- } catch (final Parser .RegexException ignored ) {
635- }
641+ if (isNullOrEmpty (key )) {
642+ throw new ParsingException (
643+ // CHECKSTYLE:OFF
644+ "Could not extract YouTube WEB InnerTube API key from HTML search results page" );
645+ // CHECKSTYLE:ON
646+ }
636647
637- if (isNullOrEmpty ( key ) ) {
638- throw new ParsingException (
639- // CHECKSTYLE:OFF
640- "Could not extract YouTube WEB InnerTube API key from HTML search results page" );
641- // CHECKSTYLE:ON
642- }
648+ if (clientVersion == null ) {
649+ throw new ParsingException (
650+ // CHECKSTYLE:OFF
651+ "Could not extract YouTube WEB InnerTube client version from HTML search results page" );
652+ // CHECKSTYLE:ON
653+ }
643654
644- if (clientVersion == null ) {
645- throw new ParsingException (
646- // CHECKSTYLE:OFF
647- "Could not extract YouTube WEB InnerTube client version from HTML search results page" );
648- // CHECKSTYLE:ON
655+ keyAndVersionExtracted = true ;
649656 }
650-
651- keyAndVersionExtracted = true ;
652657 }
653658
654659 @ Nullable
0 commit comments