Skip to content

Commit 9c12dc5

Browse files
committed
[SoundCloud] Fix SoundCloud ID extraction
resolveIdWithEmbedPlayer() does not work anymore because the JSON data has been extracted to an API call. For this reason, replace resolveIdWithEmbedPlayer() with resolveIdWithWidgetApi)( which performs the API call.
1 parent 8f023c1 commit 9c12dc5

6 files changed

Lines changed: 35 additions & 15 deletions

File tree

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

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStreamExtractor;
2020
import org.schabi.newpipe.extractor.services.soundcloud.extractors.SoundcloudStreamInfoItemExtractor;
2121
import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector;
22+
import org.schabi.newpipe.extractor.utils.JsonUtils;
2223
import org.schabi.newpipe.extractor.utils.Parser;
2324
import org.schabi.newpipe.extractor.utils.Parser.RegexException;
2425
import org.schabi.newpipe.extractor.utils.Utils;
@@ -140,27 +141,37 @@ public static String resolveUrlWithEmbedPlayer(String apiUrl) throws IOException
140141
}
141142

142143
/**
143-
* Fetch the embed player with the url and return the id (like the id from the json api).
144+
* Fetch the widget API with the url and return the id (like the id from the json api).
144145
*
145146
* @return the resolved id
146147
*/
147-
public static String resolveIdWithEmbedPlayer(String urlString) throws IOException, ReCaptchaException, ParsingException {
148+
public static String resolveIdWithWidgetApi(String urlString) throws IOException, ReCaptchaException, ParsingException {
148149
// Remove the tailing slash from URLs due to issues with the SoundCloud API
149150
if (urlString.charAt(urlString.length() - 1) == '/') urlString = urlString.substring(0, urlString.length() - 1);
151+
// Make URL lower case and remove www. if it exists.
152+
// Without doing this, the widget API does not recognize the URL.
153+
urlString = Utils.removeWWWFromUrl(urlString.toLowerCase());
150154

151-
URL url;
155+
final URL url;
152156
try {
153157
url = Utils.stringToURL(urlString);
154158
} catch (MalformedURLException e) {
155159
throw new IllegalArgumentException("The given URL is not valid");
156160
}
157161

158-
String response = NewPipe.getDownloader().get("https://w.soundcloud.com/player/?url="
159-
+ URLEncoder.encode(url.toString(), UTF_8), SoundCloud.getLocalization()).responseBody();
160-
// handle playlists / sets different and get playlist id via uir field in JSON
161-
if (url.getPath().contains("/sets/") && !url.getPath().endsWith("/sets"))
162-
return Parser.matchGroup1("\"uri\":\\s*\"https:\\/\\/api\\.soundcloud\\.com\\/playlists\\/((\\d)*?)\"", response);
163-
return Parser.matchGroup1(",\"id\":(([^}\\n])*?),", response);
162+
try {
163+
final String widgetUrl = "https://api-widget.soundcloud.com/resolve?url="
164+
+ URLEncoder.encode(url.toString(), UTF_8)
165+
+ "&format=json&client_id=" + SoundcloudParsingHelper.clientId();
166+
final String response = NewPipe.getDownloader().get(widgetUrl,
167+
SoundCloud.getLocalization()).responseBody();
168+
final JsonObject o = JsonParser.object().from(response);
169+
return String.valueOf(JsonUtils.getValue(o, "id"));
170+
} catch (JsonParserException e) {
171+
throw new ParsingException("Could not parse JSON response", e);
172+
} catch (ExtractionException e) {
173+
throw new ParsingException("Could not resolve id with embedded player. ClientId not extracted", e);
174+
}
164175
}
165176

166177
/**

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/linkHandler/SoundcloudChannelLinkHandlerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public String getId(String url) throws ParsingException {
2323
Utils.checkUrl(URL_PATTERN, url);
2424

2525
try {
26-
return SoundcloudParsingHelper.resolveIdWithEmbedPlayer(url);
26+
return SoundcloudParsingHelper.resolveIdWithWidgetApi(url);
2727
} catch (Exception e) {
2828
throw new ParsingException(e.getMessage(), e);
2929
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/linkHandler/SoundcloudPlaylistLinkHandlerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public String getId(String url) throws ParsingException {
2222
Utils.checkUrl(URL_PATTERN, url);
2323

2424
try {
25-
return SoundcloudParsingHelper.resolveIdWithEmbedPlayer(url);
25+
return SoundcloudParsingHelper.resolveIdWithWidgetApi(url);
2626
} catch (Exception e) {
2727
throw new ParsingException("Could not get id of url: " + url + " " + e.getMessage(), e);
2828
}

extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/linkHandler/SoundcloudStreamLinkHandlerFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public String getId(String url) throws ParsingException {
3232
Utils.checkUrl(URL_PATTERN, url);
3333

3434
try {
35-
return SoundcloudParsingHelper.resolveIdWithEmbedPlayer(url);
35+
return SoundcloudParsingHelper.resolveIdWithWidgetApi(url);
3636
} catch (Exception e) {
3737
throw new ParsingException(e.getMessage(), e);
3838
}

extractor/src/main/java/org/schabi/newpipe/extractor/utils/Utils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
import java.net.URL;
88
import java.net.URLDecoder;
99
import java.util.*;
10+
import java.util.regex.Pattern;
1011

1112
public class Utils {
1213

1314
public static final String HTTP = "http://";
1415
public static final String HTTPS = "https://";
1516
public static final String UTF_8 = "UTF-8";
1617
public static final String EMPTY_STRING = "";
18+
private static final Pattern WWW_PATTERN = Pattern.compile("(https?)?:\\/\\/www\\.");
1719

1820
private Utils() {
1921
//no instance
@@ -170,6 +172,13 @@ public static boolean isHTTP(URL url) {
170172
return setsNoPort || usesDefaultPort;
171173
}
172174

175+
public static String removeWWWFromUrl(String url) {
176+
if (WWW_PATTERN.matcher(url).find()) {
177+
return url.replace("www.", "");
178+
}
179+
return url;
180+
}
181+
173182
public static String removeUTF8BOM(String s) {
174183
if (s.startsWith("\uFEFF")) {
175184
s = s.substring(1);

extractor/src/test/java/org/schabi/newpipe/extractor/services/soundcloud/SoundcloudParsingHelperTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ public void resolveUrlWithEmbedPlayerTest() throws Exception {
2929
}
3030

3131
@Test
32-
public void resolveIdWithEmbedPlayerTest() throws Exception {
33-
Assert.assertEquals("26057743", SoundcloudParsingHelper.resolveIdWithEmbedPlayer("https://soundcloud.com/trapcity"));
34-
Assert.assertEquals("16069159", SoundcloudParsingHelper.resolveIdWithEmbedPlayer("https://soundcloud.com/nocopyrightsounds"));
32+
public void resolveIdWithWidgetApiTest() throws Exception {
33+
Assert.assertEquals("26057743", SoundcloudParsingHelper.resolveIdWithWidgetApi("https://soundcloud.com/trapcity"));
34+
Assert.assertEquals("16069159", SoundcloudParsingHelper.resolveIdWithWidgetApi("https://soundcloud.com/nocopyrightsounds"));
3535

3636
}
3737

0 commit comments

Comments
 (0)