17

I am trying to hide the URL of my audio streams for my HTML5 player and was really struggling to think of a way to do so and then I realised, soundcloud must hide the URL's of their streams. So i went onto soundcloud, opened up the console and played a track but I couldn't see any obvious way that the URL is hidden. After this I took a look at the DOM tree to see if there was any kind of audio information in there but I found nothing! There's not even an ID for the player/audio so i'm very confused as to how soundcloud have done it.

Now I have done as best as I can so far with hiding the audio URL. I have put an ID in the DOM for the track, got that ID when the play button is clicked and retrieved the URL for that ID from the database. The obvious problem with that is that anyone willing enough can just go to the console and get the URL from the network events.

I am not trying to break past soundcloud's security to download tracks I shouldn't be. I'm just curious as to how they've hidden the URL. Now i'm also curious as to how each track is distinguished as there's nothing in the DOM distinguishing them (not that I found on my brief look anyway).

So, in short, does anyone have any ideas on how soundcloud has achieved this or how this could be achieved?

Jacob Windsor
  • 6,750
  • 6
  • 33
  • 49

3 Answers3

21

Soundcloud is pretty much a pure JS site.

As you said, there is no ID of the song loaded with the HTML. The way songs are recognized is by the page URL. The is done via. this url (example):

https://api.sndcdn.com/resolve?url=https%3A//soundcloud.com/hoodinternet/joywave-tongues-hood-internet-remix&_status_code_map%5B302%5D=200&_status_format=json&client_id=YOUR_CLIENT_ID

This returns something like this:

{"status":"302 - Found","location":"https://api.soundcloud.com/tracks/100270342?client_id=YOUR_CLIENT_ID"}

Next up it loads the location URL, from the JSON above. This returns a bunch of information about the track, including:

stream_url: "https://api.soundcloud.com/tracks/100270342/stream"

Then it loads this URL:

https://api.sndcdn.com/i1/tracks/100270342/streams?client_id=YOUR_CLIENT_IT

Which returns a response like this:

{"http_mp3_128_url":"https://ec-media.soundcloud.com/2gNVBYiZ06bU.128.mp3?ff61182e3c2ecefa438cd021sdf02d0e385713f0c1faf3b0339595664fe070de810d30a8e3a1186eda958909e9ed97799adfeceabc135efac83aee4271217a108450591db3b88\u0026AWSAccessKeyId=AKIAsdfJ4IAZE5EOIdsf7PA7VQ\u0026Expires=1374883403\u0026Signature=%2B1%2B7dfdfLN4NWP3C3bNF3gizSEVIU%3D"}

So that's how they hide their stream URL's. The only non obvious part is that they find the song ID, by hitting an API with the URL as a parameter. Same can be done with download URL's on tracks that support it.

scandinavian_
  • 2,496
  • 1
  • 17
  • 19
  • 1
    some sounds are non streamable? this is an example http://soundcloud.com/ymcmbofficial/lil-wayne-ft-drake-and-future any solution? – Kassem Sep 12 '13 at 12:59
  • 2
    @Kassem - That is streamable for me. I made this soundcloud downloader a while ago: https://gist.github.com/calvin-nt/6629464 - Use it like this: python sc_dl.py soundcloud.com/ymcmbofficial/lil-wayne-ft-drake-and-future - it requires requests for python. – scandinavian_ Sep 19 '13 at 20:36
  • thanks @scandinavian_ i'm not familiar with pyhon but as i can understand is that the streaming url for that song will be https://api.sndcdn.com/i1/tracks/73544191/streams?client_id= i've tried using the browser with my client id but it gives 403 forbidden. any idea? – Kassem Sep 20 '13 at 17:54
  • Oh i get it now, you use the key that was provided by soundcloud itself. So smart :) thanks – Kassem Sep 20 '13 at 18:13
2

If you goto SoundCloud.com and open up your debugger (Chrome is what I'm using). Look at the "Network" tab and you'll see a script calling audio?anonymous_id#########.

This is structured like a REST call, meaning they pass an id to a service on their backend, and that returns the audio output anonymously.

Trendy
  • 460
  • 2
  • 12