@@ -116,6 +116,8 @@ public class YoutubeStreamExtractor extends StreamExtractor {
116116 private String androidCpn ;
117117 private String tvHtml5SimplyEmbedCpn ;
118118
119+ private static boolean forceFetchIosClient ;
120+
119121 public YoutubeStreamExtractor (final StreamingService service , final LinkHandler linkHandler ) {
120122 super (service , linkHandler );
121123 }
@@ -781,9 +783,7 @@ public void onFetchPage(@Nonnull final Downloader downloader)
781783
782784 checkPlayabilityStatus (playerResponse , playerResponse .getObject ("playabilityStatus" ));
783785
784- if (webPoTokenResult == null ) {
785- // TODO: add ability to force fetch iOS player response even if
786- // webPoTokenResult != null
786+ if (forceFetchIosClient || webPoTokenResult == null ) {
787787 iosCpn = generateContentPlaybackNonce ();
788788 final JsonObject iosPlayerResponse = YoutubeStreamHelper .getIosPlayerResponse (
789789 contentCountry , localization , videoId , iosCpn );
@@ -795,10 +795,10 @@ public void onFetchPage(@Nonnull final Downloader downloader)
795795 final JsonObject iosStreamingData = iosPlayerResponse .getObject (STREAMING_DATA );
796796 if (!isNullOrEmpty (iosStreamingData )) {
797797 this .iosStreamingData = iosStreamingData ;
798- // TODO: only assign playerCaptionsTracklistRenderer when iOS client
799- // fetching is not forced
800- playerCaptionsTracklistRenderer = iosPlayerResponse .getObject ("captions" )
801- . getObject ( "playerCaptionsTracklistRenderer" );
798+ if (! forceFetchIosClient ) {
799+ playerCaptionsTracklistRenderer = iosPlayerResponse . getObject ( "captions" )
800+ .getObject ("playerCaptionsTracklistRenderer" );
801+ }
802802 }
803803 }
804804
@@ -1515,8 +1515,33 @@ public List<MetaInfo> getMetaInfo() throws ParsingException {
15151515 .getArray ("contents" ));
15161516 }
15171517
1518+ /**
1519+ * Sets the {@link PoTokenProvider} instance to be used for fetching poTokens.
1520+ *
1521+ * <p>
1522+ * This method allows setting an implementation of {@link PoTokenProvider} which will be used
1523+ * to obtain poTokens required for YouTube player requests. These tokens are used by YouTube to verify the
1524+ * integrity of the device and may be necessary for playback at times.
1525+ * </p>
1526+ *
1527+ * @param poTokenProvider the {@link PoTokenProvider} instance to set
1528+ */
15181529 public static void setPoTokenProvider (@ Nullable final PoTokenProvider poTokenProvider ) {
1519- // TODO: document the method and handle concurrent calls
15201530 YoutubeStreamExtractor .poTokenProvider = poTokenProvider ;
15211531 }
1532+
1533+ /**
1534+ * Sets whether to force fetch the iOS player response even if the webPoTokenResult is not null.
1535+ *
1536+ * <p>
1537+ * This method allows setting a flag to force the fetching of the iOS player response, even if a
1538+ * valid webPoTokenResult is available. This can be useful in scenarios where streams from the iOS player
1539+ * response is preferred.
1540+ * </p>
1541+ *
1542+ * @param forceFetchIosClient a boolean flag indicating whether to force fetch the iOS player response
1543+ */
1544+ public static void setForceFetchIosClient (boolean forceFetchIosClient ) {
1545+ YoutubeStreamExtractor .forceFetchIosClient = forceFetchIosClient ;
1546+ }
15221547}
0 commit comments