Skip to content

Commit 7cf8edd

Browse files
authored
Merge pull request #618 from TeamNewPipe/soundcloud_id
Fix Soundcloud extraction
2 parents 7f202db + 9c12dc5 commit 7cf8edd

6 files changed

Lines changed: 36 additions & 16 deletions

File tree

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

Lines changed: 21 additions & 10 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;
@@ -40,7 +41,7 @@
4041
import static org.schabi.newpipe.extractor.utils.Utils.*;
4142

4243
public class SoundcloudParsingHelper {
43-
private static final String HARDCODED_CLIENT_ID = "Kl9G8jQT22DxqatQk09IjWRujGlut5Vd"; // Updated on 04/03/21
44+
private static final String HARDCODED_CLIENT_ID = "NcIaRZItQCNQp3Vq9Plvzf7tvjmVJnF6"; // Updated on 26/04/21
4445
private static String clientId;
4546

4647
private SoundcloudParsingHelper() {
@@ -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)