[Updated 7th Feb 2012
Changes:
+ file names are now as they would be if you downloaded via web browser
+ Playlist is now in reverse date uploaded order]
I like to have music while I’m coding. It breaks the silence while working alone at home.
When I have music playing, it’s best if I don’t have to think about setting up playlists, which is why I used to listen to the radio. The radio has it’s limits though, not enough Ninja Tune I think.
Speaking of Ninja Tune, I <3 their SolidSteel mixes http://soundcloud.com/ninja-tune/sets/solid-steel-radio-shows/
What I don’t like is having to listen via my web browser and their music player in Flash. A recourse hog and not great if you want their music on a device disconnected from the ‘net.
Thankfully, with SoundCloud tracks, you can download any file you wish. The downside to it is that there’s a lot to download. What if you want a whole playlist? A playlist of (currently) 151 tracks for instance?
The script below will download all of the tracks in a set to a directory and create a .m3u playlist at the same time.
Please excuse the justified text and syntax-highlighting gone wrong. View plain, or copy to clipboard and it’ll be fine.
<?php
$baseDir = "mp3s";
$soundcloudURL = "http://soundcloud.com/ninja-tune/sets/solid-steel-radio-shows/";
$urlBits = str_replace('http://', '', $soundcloudURL);
$urlBits = preg_replace('@/$@', '', $urlBits);
$urlBits = explode("/", $urlBits);
/**
* http://soundcloud.com/ninja-tune/sets/solid-steel-radio-shows/
* Array
* (
* [0] => soundcloud.com
* [1] => ninja-tune
* [2] => sets
* [3] => solid-steel-radio-shows
* )
*/
array_shift($urlBits);
$storage_dir = $baseDir . "/" . implode("/", $urlBits);
if (!file_exists($storage_dir))
{
mkdir($storage_dir, 0755, true);
}
$playListFile = $storage_dir . "/" . $urlBits[count($urlBits) - 1] . ".m3u";
if (file_exists($playListFile))
{
unlink($playListFile);
}
$playList = array();
$file = getPage($soundcloudURL);
if (!$file) die ("Can't get SoundCloud page\n");
$rows = explode("\n", $file);
$uris = array();
$pattern = '@"/.+download"@i';
$baseURL = 'http://soundcloud.com';
foreach ($rows as $row)
{
preg_match($pattern, $row, $matches);
if (count($matches) > 0)
{
$uris[] = str_replace("\"", '', $matches[0]);
}
}
$i = 0;
$uriCount = count($uris);
foreach ($uris as $uri)
{
$i++;
echo "\nFetching file " . $i . " of " . $uriCount . "\n";
$uriHeaders = get_headers($baseURL . $uri);
foreach ($uriHeaders as $header)
{
preg_match("/^Content\-Disposition\: attachment\;filename=\"(.*)\"$/", $header, $matches);
if (isset($matches[1]))
{
$outputFilename = $matches[1];
break;
}
}
$playList[] = $outputFilename;
if (file_exists($storage_dir . "/" . $outputFilename))
{
echo "File exists, skipping.\n";
continue;
}
$command = "wget " . $baseURL . $uri . " -O " . $storage_dir . "/" . $outputFilename;
`$command`;
}
echo "\nWriting play list\n";
file_put_contents($playListFile, implode("\n", array_reverse($playList)), FILE_APPEND);
echo "\nDone\n";
function getPage($url, $referer = false, $timeout = 30, $header = false)
{
$curl = curl_init();
if(strstr($referer,"://")){
curl_setopt ($curl, CURLOPT_REFERER, $referer);
}
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt ($curl, CURLOPT_USERAGENT, sprintf("Mozilla/%d.0",rand(4,5)));
curl_setopt ($curl, CURLOPT_HEADER, (int)$header);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0);
$html = curl_exec ($curl);
curl_close ($curl);
return $html;
}


this is great. ive been looking for somewhere or something that can help me download soundcloud sets.
can you tell me what to do with the code frame to run it? do i need a certain program to execute? or can i just save as a .bat or something like?
what im asking is what steps do i need to take to run the script and download a playlist?
Matt: This is a PHP script to be run from the command line (or slightly modified and run from a server in a web browser).
Have a look at http://windows.php.net/ for information about using the language on Windows.
It’s by no means a perfect script as it assumes that all files are MP3s. Will fix this at some point.