Open stream_url of a Soundcloud Track via Client-S

2019-05-09 22:24发布

问题:

Since you can call the the Soundcloud API via XHR (because of the CORS headers it sends http://backstage.soundcloud.com/2010/08/of-cors-we-do/, right?) I was wondering if this was possible with the audio data itself, like a tracks' stream_url for example.

When trying to open the stream_url with a XHR (from the Client Side) using the Web Audio API, i get a Origin is not allowed by Access-Control-Allow-Origin. error. Is there a way to load Audio resources via XHttpRequest from Client-Side-Javascript, or is it impossible ( https://stackoverflow.com/questions/10871882/audio-data-api-and-streaming-a-no-go) ?

Would be great as this would allow some really cool things with the Web Audio API.

Thanks!

UPDATE

The problem might have to do with the 302 redirect you get when calling:

http://api.soundcloud.com/tracks/5646378/stream.json?client_id=[client_id]

or some other call requesting the actual media file (see comments).

HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Sun, 24 Jun 2012 09:58:01 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Cache-Control: no-cache
Location: http://ec-media.soundcloud.com/[...]
X-Runtime: 41
Content-Length: 339
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Headers: Accept, Authorization, Content-Type, Origin
Access-Control-Allow-Origin: *
X-Cacheable: NO:Cache-Control=no-cache
X-Varnish: 2433107209
Age: 0
Via: 1.1 varnish
X-Cache: MISS

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=252460800
Content-Type: audio/mpeg
Date: Sun, 24 Jun 2012 09:58:01 GMT
ETag: "c2241e[...]41bbcf7c0d32f09"
Last-Modified: Tue, 28 Sep 2010 17:57:26 GMT
Server: ECAcc (fra/D484)
x-amz-id-2: oB0XzQcc/[...]+mAr/a
x-amz-meta-bitrate: 128
x-amz-meta-duration: 152900
x-amz-meta-job: t405jWkfNvx7
x-amz-request-id: D65[...]E1355
X-Cache: HIT
Content-Length: 2445478

The original JSON response has the CORS headers, while the location of the redirect don't.

回答1:

Well, as long as the Audio Files themselves don't come with the CORS headers (see curl -IL output in the question), the only solution that worked for me is open the audio files and add the headers yourself.

From my understanding, this is what other apps like https://github.com/tsenart/audiojedit do too. (in node.js) This has the the huge downside of shifting the traffic of the binary files to your server, which would be otherwise served by soundcloud.com.

You can use PHP to open the file, add the headers and restream it with something like:

$fp = fopen('http://api.soundcloud.com/tracks/[track_id]/stream.json?client_id=[client_id]', 'rb');

header("Content-Type: audio/mpeg");
header("Access-Control-Allow-Methods: GET, PUT, POST, DELETE");
header("Access-Control-Allow-Headers: Accept, Authorization, Content-Type, Origin");
header("Access-Control-Allow-Origin: *");
fpassthru( $fp );

exit();

As I said, this is just a workaround, not a nice solution for a production environment, but helped me keep going with my Web Audio App.

Soundcloud, any chance of adding CORS headers to the audiofiles? :)



回答2:

If you're not necessarily tied down to using XHR, you could create new <audio/> elements and set their src to whatever asset you want, without being tied to Same-Origin Policy.

Newer versions of Chrome will allow you to create AudioNode instances from media elements via MediaElementAudioSourceNode -- so you can still use all the cool new Web Audio stuff.

var audio, body, context, source;
audio = document.createElement('audio');
body = document.getElementsByTagName('body')[0];
audio.setAttribute('src', 'http://kevincennis.com/mix/assets/sounds/1901_gtr1.mp3');
body.appendChild(audio);
context = new webkitAudioContext();
source = context.createMediaElementSource(audio);
source.connect(context.destination);
source.mediaElement.play();

Excuse the hideous code. It's late and I'm tired.