66import com .degoos .javayoutubedownloader .util .EncodedStreamUtils ;
77import com .degoos .javayoutubedownloader .util .HTMLUtils ;
88import com .degoos .javayoutubedownloader .util .IdExtractor ;
9+ import org .json .JSONArray ;
10+ import org .json .JSONObject ;
911
1012import java .io .IOException ;
1113import java .io .UnsupportedEncodingException ;
1214import java .net .URL ;
1315import java .net .URLDecoder ;
14- import java .util .HashMap ;
15- import java .util .LinkedList ;
16- import java .util .List ;
17- import java .util .Map ;
16+ import java .util .*;
1817
1918/**
2019 * This class represents a decoder that uses the Youtube's embedded API to decode stream options.
@@ -34,6 +33,10 @@ public class EmbeddedDecoder implements Decoder {
3433 public static final String MUXED_STREAM_LIST_PARAMETER = "url_encoded_fmt_stream_map" ;
3534 public static final String ADAPTIVE_STREAM_LIST_PARAMETER = "adaptive_fmts" ;
3635
36+ public static final String PLAYER_RESPONSE_LIST_PARAMETER = "player_response" ;
37+ public static final String STREAMING_DATA_JSON_PARAMETER = "streamingData" ;
38+ public static final String FORMATS_JSON_PARAMETER = "formats" ;
39+
3740 private String urlEncoding ;
3841 private String getVideoUrl ;
3942
@@ -69,15 +72,37 @@ public YoutubeVideo extractVideo(URL url) throws IOException {
6972 Map <String , String > queryData = getQueryMap (query );
7073 checkExceptions (queryData );
7174
72- String title = decode (queryData .get (TITLE_PARAMETER ));
73- String author = decode (queryData .get (AUTHOR_PARAMETER ));
75+ queryData .forEach ((key , value ) -> System .out .println (key + "=" + value ));
76+
77+ String title = queryData .containsKey (TITLE_PARAMETER ) ? decode (queryData .get (TITLE_PARAMETER )) : "null" ;
78+ String author = queryData .containsKey (AUTHOR_PARAMETER ) ? decode (queryData .get (AUTHOR_PARAMETER )) : "null" ;
7479 YoutubeVideo video = new YoutubeVideo (title , author );
7580
76- String encodedMuxedStreamList = decode (queryData .get (MUXED_STREAM_LIST_PARAMETER ));
77- String encodedAdaptiveStreamList = decode (queryData .get (ADAPTIVE_STREAM_LIST_PARAMETER ));
7881 List <EncodedStream > encodedStreams = new LinkedList <>();
79- EncodedStreamUtils .addEncodedStreams (encodedMuxedStreamList , encodedStreams , urlEncoding );
80- EncodedStreamUtils .addEncodedStreams (encodedAdaptiveStreamList , encodedStreams , urlEncoding );
82+
83+ //Player response data.
84+ if (queryData .containsKey (PLAYER_RESPONSE_LIST_PARAMETER )) {
85+ JSONObject obj = new JSONObject (decode (queryData .get (PLAYER_RESPONSE_LIST_PARAMETER )));
86+ if (obj .has (STREAMING_DATA_JSON_PARAMETER )) {
87+ obj = obj .getJSONObject (STREAMING_DATA_JSON_PARAMETER );
88+ if (obj .has (FORMATS_JSON_PARAMETER )) {
89+ addJSONStreams (obj .getJSONArray (FORMATS_JSON_PARAMETER ), encodedStreams );
90+ }
91+ }
92+ }
93+
94+ //Muxed stream data.
95+ if (queryData .containsKey (MUXED_STREAM_LIST_PARAMETER )) {
96+ String encodedMuxedStreamList = decode (queryData .get (MUXED_STREAM_LIST_PARAMETER ));
97+ EncodedStreamUtils .addEncodedStreams (encodedMuxedStreamList , encodedStreams , urlEncoding );
98+ }
99+
100+ //Adaptive stream data.
101+ if (queryData .containsKey (ADAPTIVE_STREAM_LIST_PARAMETER )) {
102+ String encodedAdaptiveStreamList = decode (queryData .get (ADAPTIVE_STREAM_LIST_PARAMETER ));
103+ EncodedStreamUtils .addEncodedStreams (encodedAdaptiveStreamList , encodedStreams , urlEncoding );
104+ }
105+
81106 encodedStreams .removeIf (target -> !target .decode (null , true ));
82107 encodedStreams .forEach (target -> video .getStreamOptions ().add (target .getDecodedStream ()));
83108 return video ;
@@ -111,9 +136,25 @@ private String checkExceptions(Map<String, String> queryMap) {
111136 private String decode (String string ) {
112137 try {
113138 return URLDecoder .decode (string , urlEncoding );
114- } catch (UnsupportedEncodingException e ) {
139+ } catch (UnsupportedEncodingException | NullPointerException e ) {
140+ System .err .println ("Error while decoding string " + string );
115141 e .printStackTrace ();
116142 return string ;
117143 }
118144 }
145+
146+ private void addJSONStreams (JSONArray array , Collection <EncodedStream > streams ) {
147+ array .forEach (target -> {
148+ try {
149+ if (!(target instanceof JSONObject )) return ;
150+ JSONObject obj = (JSONObject ) target ;
151+ int iTag = obj .getInt ("itag" );
152+ String url = URLDecoder .decode (obj .getString ("url" ), urlEncoding );
153+ streams .add (new EncodedStream (iTag , url ));
154+ } catch (UnsupportedEncodingException e ) {
155+ System .err .println ("Error while parsing url." );
156+ e .printStackTrace ();
157+ }
158+ });
159+ }
119160}
0 commit comments