Closed timbodeit closed 9 years ago
Thanks for the report. Would you like to come up with a pull request? :) A HEAD request to the resource before playing it should be enough.
$ curl --head http://api.soundcloud.com/tracks/126602145/stream?client_id=3904229f42df3999df223f6ebf39a8fe
HTTP/1.1 302 Found
Access-Control-Allow-Headers: Accept, Authorization, Content-Type, Origin
Access-Control-Allow-Methods: GET, PUT, POST, DELETE
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Date
Cache-Control: no-cache
Content-Type: application/xml; charset=utf-8
Date: Tue, 11 Nov 2014 08:38:49 GMT
Location: https://ec-media.soundcloud.com/p73PcrUdtqLj.128.mp3?f10880d39085a94a0418a7ef69b03d522cd6dfee9399eeb9a522009969f1bb38c10fba845d2051e67df38082623306a464b4c9fc14772383ca0f3a353387fd36486dda8f65&AWSAccessKeyId=AKIAJNIGGLK7XA7YZSNQ&Expires=1415695449&Signature=%2B8U2l4n1hOZzu71Cvtz1OHcw%2F2k%3D
Server: am/2
Content-Length: 0
As requests is already a dependency, that should be easy.
I actually tried to fix this because I just ran into the same issue. The problem is that when stripping the https from the final URL, it invalidates the request signature. This is the response:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
<AWSAccessKeyId>AKIAJNIGGLK7XA7YZSNQ</AWSAccessKeyId>
<StringToSign>
GET 1415698906 /soundcloud-media/R81nGDq4qVFb.128.mp3
</StringToSign>
<SignatureProvided>TPkRetwEnrmxvtZUQOcwg/if8yU=</SignatureProvided>
<StringToSignBytes>
47 45 54 0a 0a 0a 31 34 31 35 36 39 38 39 30 36 0a 2f 73 6f 75 6e 64 63 6c 6f 75 64 2d 6d 65 64 69 61 2f 52 38 31 6e 47 44 71 34 71 56 46 62 2e 31 32 38 2e 6d 70 33
</StringToSignBytes>
<RequestId>FAFA88A224488F0E</RequestId>
<HostId>
DF5pVBaOi+KFZb1zT/B2D2HtSjfMLvM5+pE2xPnGZGzuA92922kXb2NPeezs6JT1
</HostId>
</Error>
The best real fix for this would probably be #45... Or do you have any other idea?
A workaround would be to download the file to a temporary location with requests and play it from there.
I got started on this last night (though your solution is much cleaner) and ran into the same problem. This is also the reason why I have not filed a pull request yet.
I assume this is a bug on Soundclouds servers. As it seems, the protocol is not part of the signed content and it works fine with a lot of tracks. With me this error only happens occasionally.
I agree that #45 would be the best solution. As much as I would like to contribute to it, I fear that it is a bit out of my league. The last time I worked with python was playing around with the python turtle in 6th grade. I might try to build the workaround for the meantime, though.
If you do want to implement the workaround, I'd suggest basing the work on the issue_52 branch. You can then add a HEAD request after switching the protocol from HTTPS to HTTP (line 138) to see whether the status code is fine or not (probably with response.raise_for_status()
). If it's not OK, then download the HTTPS version to a temporary location (which you can get using https://docs.python.org/2/library/tempfile.html). Make sure to delete it again afterwards, in order not to violate the rules by 8tracks.
Hm, Soundcloud appear to have fixed their signature issues! I'll merge this for now, hope it solves the problem.
Version 0.1.2 is on PyPI! Hope that resolves the playback issues.
mplayer currently cannot stream via https. This issue has been partially covered in player.py by exchanging the https protocol with http in the url.
This does not cover URLs with redirects though. These are for example used by soundcloud. When this http resource uses a 302 redirect that points to another https resource, orochi doesn't currently handle this and mplayer does not support the URL it is redirected to.