Skip to content

Commit 4fc18a6

Browse files
mauriciocolliTobiGr
authored andcommitted
[SoundCloud] Fix extraction of client id
- Hardcoded id and check at the first usage. - As a fallback, and considering that the scripts containing the client id were all split up, try searching it in each of them.
1 parent 250c0bb commit 4fc18a6

2 files changed

Lines changed: 37 additions & 18 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelper.java

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
import org.jsoup.Jsoup;
88
import org.jsoup.nodes.Document;
99
import org.jsoup.nodes.Element;
10+
import org.jsoup.select.Elements;
11+
import org.schabi.newpipe.extractor.DownloadResponse;
1012
import org.schabi.newpipe.extractor.Downloader;
1113
import org.schabi.newpipe.extractor.NewPipe;
1214
import org.schabi.newpipe.extractor.channel.ChannelInfoItemsCollector;
15+
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
1316
import org.schabi.newpipe.extractor.exceptions.ParsingException;
1417
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
1518
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
@@ -21,6 +24,7 @@
2124
import java.net.URLEncoder;
2225
import java.text.ParseException;
2326
import java.text.SimpleDateFormat;
27+
import java.util.Collections;
2428
import java.util.Date;
2529
import 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();

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudSearchQueryHandlerFactory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.schabi.newpipe.extractor.services.soundcloud;
22

3+
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
34
import org.schabi.newpipe.extractor.exceptions.ParsingException;
45
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
56
import org.schabi.newpipe.extractor.linkhandler.SearchQueryHandlerFactory;
@@ -48,10 +49,10 @@ public String getUrl(String id, List<String> contentFilter, String sortFilter) t
4849

4950
} catch (UnsupportedEncodingException e) {
5051
throw new ParsingException("Could not encode query", e);
51-
} catch (IOException e) {
52-
throw new ParsingException("Could not get client id", e);
5352
} catch (ReCaptchaException e) {
5453
throw new ParsingException("ReCaptcha required", e);
54+
} catch (IOException | ExtractionException e) {
55+
throw new ParsingException("Could not get client id", e);
5556
}
5657
}
5758

0 commit comments

Comments
 (0)