77import org .jsoup .Jsoup ;
88import org .jsoup .nodes .Document ;
99import org .jsoup .nodes .Element ;
10+ import org .jsoup .select .Elements ;
11+ import org .schabi .newpipe .extractor .DownloadResponse ;
1012import org .schabi .newpipe .extractor .Downloader ;
1113import org .schabi .newpipe .extractor .NewPipe ;
1214import org .schabi .newpipe .extractor .channel .ChannelInfoItemsCollector ;
15+ import org .schabi .newpipe .extractor .exceptions .ExtractionException ;
1316import org .schabi .newpipe .extractor .exceptions .ParsingException ;
1417import org .schabi .newpipe .extractor .exceptions .ReCaptchaException ;
1518import org .schabi .newpipe .extractor .stream .StreamInfoItemsCollector ;
2124import java .net .URLEncoder ;
2225import java .text .ParseException ;
2326import java .text .SimpleDateFormat ;
27+ import java .util .Collections ;
2428import java .util .Date ;
2529import java .util .HashMap ;
2630
@@ -32,29 +36,43 @@ public class SoundcloudParsingHelper {
3236 private SoundcloudParsingHelper () {
3337 }
3438
35- public static String clientId () throws ReCaptchaException , IOException , RegexException {
39+ public static String clientId () throws ExtractionException , IOException {
3640 if (clientId != null && !clientId .isEmpty ()) return clientId ;
3741
3842 Downloader dl = NewPipe .getDownloader ();
39- String response = dl .download ("https://soundcloud.com" );
40-
41- Document doc = Jsoup .parse (response );
42- Element jsElement = doc .select ("script[src^=https://a-v2.sndcdn.com/assets/app]" ).first ();
43+ clientId = "LHzSAKe8eP9Yy3FgBugfBapRPLncO6Ng" ; // Updated on 22/10/19
44+ final String apiUrl = "https://api.soundcloud.com/connect?client_id=" + clientId ;
45+ // Should return 200 to indicate that the client id is valid, a 401 is returned otherwise.
46+ // In that case, the fallback method is used.
47+ if (dl .head (apiUrl ).getResponseCode () == 200 ) {
48+ return clientId ;
49+ }
4350
51+ final DownloadResponse download = dl .get ("https://soundcloud.com" );
52+ String response = download .getResponseBody ();
4453 final String clientIdPattern = ",client_id:\" (.*?)\" " ;
4554
46- try {
47- final HashMap <String , String > headers = new HashMap <>();
48- headers .put ("Range" , "bytes=0-16384" );
49- String js = dl .download (jsElement .attr ("src" ), headers );
50-
51- return clientId = Parser .matchGroup1 (clientIdPattern , js );
52- } catch (IOException | RegexException ignored ) {
53- // Ignore it and proceed to download the whole js file
55+ Document doc = Jsoup .parse (response );
56+ final Elements possibleScripts = doc .select ("script[src*=\" sndcdn.com/assets/\" ][src$=\" .js\" ]" );
57+ // The one containing the client id will likely be the last one
58+ Collections .reverse (possibleScripts );
59+
60+ final HashMap <String , String > headers = new HashMap <>();
61+ headers .put ("Range" , "bytes=0-16384" );
62+
63+ for (Element element : possibleScripts ) {
64+ final String srcUrl = element .attr ("src" );
65+ if (srcUrl != null && !srcUrl .isEmpty ()) {
66+ try {
67+ return clientId = Parser .matchGroup1 (clientIdPattern , dl .download (srcUrl , headers ));
68+ } catch (RegexException ignored ) {
69+ // Ignore it and proceed to try searching other script
70+ }
71+ }
5472 }
5573
56- String js = dl . download ( jsElement . attr ( "src" ));
57- return clientId = Parser . matchGroup1 ( clientIdPattern , js );
74+ // Officially give up
75+ throw new ExtractionException ( "Couldn't extract client id" );
5876 }
5977
6078 public static String toDateString (String time ) throws ParsingException {
@@ -79,7 +97,7 @@ public static String toDateString(String time) throws ParsingException {
7997 *
8098 * See https://developers.soundcloud.com/docs/api/reference#resolve
8199 */
82- public static JsonObject resolveFor (Downloader downloader , String url ) throws IOException , ReCaptchaException , ParsingException {
100+ public static JsonObject resolveFor (Downloader downloader , String url ) throws IOException , ExtractionException {
83101 String apiUrl = "https://api.soundcloud.com/resolve"
84102 + "?url=" + URLEncoder .encode (url , "UTF-8" )
85103 + "&client_id=" + clientId ();
0 commit comments