Skip to content

Commit 33445a5

Browse files
committed
Fix SoundCloud downloading by switching to api-v2. ffmpeg now seems to be required.
1 parent 5acf4ba commit 33445a5

File tree

4 files changed

+20
-33
lines changed

4 files changed

+20
-33
lines changed

app.rb

+18-28
Original file line numberDiff line numberDiff line change
@@ -682,25 +682,21 @@
682682
end
683683

684684
response = Soundcloud.get("/resolve", query: { url: "https://soundcloud.com/#{username}" })
685-
if response.code == 302
686-
uri = Addressable::URI.parse(response.json["location"])
687-
return [404, "URL does not resolve to a user."] if !uri.path.start_with?("/users/")
688-
id = uri.path[/\d+/]
685+
if response.code == 200
686+
data = response.json
687+
data = data["user"] if data.has_key?("user")
688+
return [404, "Can't identify the user."] if data["kind"] != "user"
689689
elsif response.code == 404 && username.numeric?
690690
response = Soundcloud.get("/users/#{username}")
691-
return [response.code, "Can't find a user with that id. Sorry."] if response.code == 404
691+
return [response.code, "Can't find a user with that id. Sorry."] if response.code == 400 || response.code == 404
692692
raise(SoundcloudError, response) if !response.success?
693-
id = response.json["id"]
693+
data = response.json
694694
elsif response.code == 404
695695
return [response.code, "Can't find a user with that name. Sorry."]
696696
else
697697
raise(SoundcloudError, response)
698698
end
699699

700-
response = Soundcloud.get("/users/#{id}")
701-
raise(SoundcloudError, response) if !response.success?
702-
data = response.json
703-
704700
redirect Addressable::URI.new(path: "/soundcloud/#{data["id"]}/#{data["permalink"]}").normalize.to_s
705701
end
706702

@@ -709,25 +705,19 @@
709705
url = "https://#{url}" if !url.start_with?("http:", "https:")
710706
response = Soundcloud.get("/resolve", query: { url: url })
711707
return [response.code, "URL does not resolve."] if response.code == 404
712-
raise(SoundcloudError, response) if response.code != 302
713-
uri = Addressable::URI.parse(response.json["location"])
714-
return [404, "URL does not resolve to a track."] if !uri.path.start_with?("/tracks/")
715-
response = Soundcloud.get("#{uri.path}/stream")
716-
raise(SoundcloudError, response) if response.code != 302
717-
media_url = response.json["location"]
708+
raise(SoundcloudError, response) if response.code != 200
718709

719-
if env["HTTP_ACCEPT"] == "application/json"
720-
response = Soundcloud.get("#{uri.path}")
721-
content_type :json
722-
data = response.json
723-
created_at = Time.parse(data["created_at"])
724-
return {
725-
url: media_url,
726-
filename: "#{created_at.to_date} - #{data["title"]}.mp3".to_filename,
727-
}.to_json
728-
end
710+
data = response.json
711+
return [404, "URL does not resolve to a track."] if data["kind"] != "track"
729712

730-
redirect media_url
713+
data_uri = Addressable::URI.parse(data["media"]["transcodings"][0]["url"])
714+
response = Soundcloud.get(data_uri.path)
715+
raise(SoundcloudError, response) if response.code != 200
716+
717+
url = response.json["url"]
718+
fn = "#{Date.parse(data["created_at"])} - #{data["title"]}.mp3".to_filename
719+
720+
"ffmpeg -i '#{url}' -acodec copy '#{fn}'"
731721
end
732722

733723
get %r{/soundcloud/(?<id>\d+)/(?<username>.+)} do |id, username|
@@ -737,7 +727,7 @@
737727
return [404, "That user no longer exist."] if response.code == 500 && response.body == '{"error":"Match failed"}'
738728
raise(SoundcloudError, response) if !response.success?
739729

740-
@data = response.json
730+
@data = response.json["collection"]
741731
@username = @data[0]["user"]["permalink"] rescue CGI.unescape(username)
742732
@user = @data[0]["user"]["username"] rescue CGI.unescape(username)
743733

app/soundcloud.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
class SoundcloudError < HTTPError; end
55

66
class Soundcloud < HTTP
7-
BASE_URL = "https://api.soundcloud.com"
7+
BASE_URL = "https://api-v2.soundcloud.com"
88
PARAMS = "client_id=#{ENV["SOUNDCLOUD_CLIENT_ID"]}"
99
ERROR_CLASS = SoundcloudError
1010
end

views/index.erb

+1-3
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,7 @@
136136
<div class="input-group-append">
137137
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
138138
<div class="dropdown-menu dropdown-menu-right">
139-
<a class="dropdown-item" data-download>Open track</a>
140-
<a class="dropdown-item" data-download download>Download track</a>
141-
<a class="dropdown-item" data-download-filename>Download track with nice filename</a>
139+
<a class="dropdown-item" data-download>Get download command</a>
142140
</div>
143141
<input class="btn btn-primary" type="submit" value="Get RSS Feed">
144142
</div>

views/soundcloud_feed.erb

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
<%= track["description"].linkify.to_paragraphs.esc %>
2424

2525
&lt;p>&lt;a href="<%= request.root_url %>/soundcloud/download<%= Addressable::URI.new(query: "url=#{track["permalink_url"]}").normalize.to_s %>">Download track&lt;/a>&lt;/p>
26-
&lt;p>&lt;a href="<%= request.root_url %>/<%= Addressable::URI.new(query: "download=#{track["permalink_url"]}").normalize.to_s %>">Download track with nice filename&lt;/a>&lt;/p>
2726
</content>
2827
</entry>
2928
<%- end -%>

0 commit comments

Comments
 (0)