@@ -85,6 +85,7 @@ public class SubtitlesException extends ContentNotAvailableException {
8585 private JsonObject playerArgs ;
8686 @ Nonnull
8787 private final Map <String , String > videoInfoPage = new HashMap <>();
88+ private JsonObject playerResponse ;
8889
8990 @ Nonnull
9091 private List <SubtitlesInfo > subtitlesInfos = new ArrayList <>();
@@ -486,7 +487,7 @@ public List<VideoStream> getVideoStreams() throws IOException, ExtractionExcepti
486487 assertPageFetched ();
487488 List <VideoStream > videoStreams = new ArrayList <>();
488489 try {
489- for (Map .Entry <String , ItagItem > entry : getItags (URL_ENCODED_FMT_STREAM_MAP , ItagItem .ItagType .VIDEO ).entrySet ()) {
490+ for (Map .Entry <String , ItagItem > entry : getItags (ADAPTIVE_FMTS , ItagItem .ItagType .VIDEO ).entrySet ()) {
490491 ItagItem itag = entry .getValue ();
491492
492493 VideoStream videoStream = new VideoStream (entry .getKey (), itag .getMediaFormat (), itag .resolutionString );
@@ -620,7 +621,7 @@ public String getErrorMessage() {
620621 //////////////////////////////////////////////////////////////////////////*/
621622
622623 private static final String URL_ENCODED_FMT_STREAM_MAP = "url_encoded_fmt_stream_map" ;
623- private static final String ADAPTIVE_FMTS = "adaptive_fmts " ;
624+ private static final String ADAPTIVE_FMTS = "adaptiveFormats " ;
624625 private static final String HTTPS = "https:" ;
625626 private static final String CONTENT = "content" ;
626627 private static final String DECRYPTION_FUNC_NAME = "decrypt" ;
@@ -667,6 +668,7 @@ public void onFetchPage(@Nonnull Downloader downloader) throws IOException, Extr
667668 playerUrl = getPlayerUrl (ytPlayerConfig );
668669 isAgeRestricted = false ;
669670 }
671+ playerResponse = getPlayerResponse ();
670672
671673 if (decryptionCode .isEmpty ()) {
672674 decryptionCode = loadDecryptionCode (playerUrl );
@@ -728,6 +730,20 @@ private String getPlayerUrl(JsonObject playerConfig) throws ParsingException {
728730 }
729731 }
730732
733+ private JsonObject getPlayerResponse () throws ParsingException {
734+ try {
735+ String playerResponseStr ;
736+ if (playerArgs != null ) {
737+ playerResponseStr = playerArgs .getString ("player_response" );
738+ } else {
739+ playerResponseStr = videoInfoPage .get ("player_response" );
740+ }
741+ return JsonParser .object ().from (playerResponseStr );
742+ } catch (Exception e ) {
743+ throw new ParsingException ("Could not parse yt player response" , e );
744+ }
745+ }
746+
731747 @ Nonnull
732748 private EmbeddedInfo getEmbeddedInfo () throws ParsingException , ReCaptchaException {
733749 try {
@@ -924,45 +940,21 @@ private static String getVideoInfoUrl(final String id, final String sts) {
924940 "&sts=" + sts + "&ps=default&gl=US&hl=en" ;
925941 }
926942
927- private Map <String , ItagItem > getItags (String encodedUrlMapKey , ItagItem .ItagType itagTypeWanted ) throws ParsingException {
943+ private Map <String , ItagItem > getItags (String streamingDataKey , ItagItem .ItagType itagTypeWanted ) throws ParsingException {
928944 Map <String , ItagItem > urlAndItags = new LinkedHashMap <>();
929945
930- String encodedUrlMap = "" ;
931- if (playerArgs != null && playerArgs .isString (encodedUrlMapKey )) {
932- encodedUrlMap = playerArgs .getString (encodedUrlMapKey , "" );
933- } else if (videoInfoPage .containsKey (encodedUrlMapKey )) {
934- encodedUrlMap = videoInfoPage .get (encodedUrlMapKey );
935- }
936-
937- for (String url_data_str : encodedUrlMap .split ("," )) {
938- try {
939- // This loop iterates through multiple streams, therefore tags
940- // is related to one and the same stream at a time.
941- Map <String , String > tags = Parser .compatParseMap (
942- org .jsoup .parser .Parser .unescapeEntities (url_data_str , true ));
943-
944- int itag = Integer .parseInt (tags .get ("itag" ));
945-
946- if (ItagItem .isSupported (itag )) {
947- ItagItem itagItem = ItagItem .getItag (itag );
948- if (itagItem .itagType == itagTypeWanted ) {
949- String streamUrl = tags .get ("url" );
950- // if video has a signature: decrypt it and add it to the url
951- if (tags .get ("s" ) != null ) {
952- if (tags .get ("sp" ) == null ) {
953- // fallback for urls not conaining the "sp" tag
954- streamUrl = streamUrl + "&signature=" + decryptSignature (tags .get ("s" ), decryptionCode );
955- }
956- else {
957- streamUrl = streamUrl + "&" + tags .get ("sp" ) + "=" + decryptSignature (tags .get ("s" ), decryptionCode );
958- }
959- }
960- urlAndItags .put (streamUrl , itagItem );
961- }
946+ JsonArray formats = playerResponse .getObject ("streamingData" ).getArray (streamingDataKey );
947+ for (int i = 0 ; i != formats .size (); ++i ) {
948+ JsonObject formatData = formats .getObject (i );
949+ int itag = formatData .getInt ("itag" );
950+
951+ if (ItagItem .isSupported (itag )) {
952+ ItagItem itagItem = ItagItem .getItag (itag );
953+ if (itagItem .itagType == itagTypeWanted ) {
954+ String streamUrl = formatData .getString ("url" );
955+ System .out .println (streamUrl );
956+ urlAndItags .put (streamUrl , itagItem );
962957 }
963- } catch (DecryptException e ) {
964- throw e ;
965- } catch (Exception ignored ) {
966958 }
967959 }
968960
0 commit comments