chronx code and stuff

4Jan/104

Want XSPF playlists from playlist.com ?

Recently I found that I could not use the playlists I had created on playlist.com in my media player. The quick and short of this is that they are not providing a standardized XSPF format in their RSS feed.
All I really had to do was determine how to decrypt their hash which was pretty easy thanks to OneWeirdKid90, rename a few fields, and export a correctly formatted XSPF file. Below is the resultant code. I am using the script to access all the playlists on this site via playlist.com.

function hexToChars($hex) {
	$a = array();
	$b = (substr($hex, 0, 2) == "0x") ? 2 : 0;
	while ($b < strlen($hex)) {
		array_push($a, intval(substr($hex, $b, 2), 16));
		$b += 2;
	}
	return $a;
}
 
function charsToStr($chars) {
	$a = "";
	$b = 0;
	while ($b < count($chars)) {
		$a .= chr($chars[$b]);
		++$b;
	}
	return $a;
}
 
function strToChars($str) {
	$a = array();
	$b = 0;
	while ($b < strlen($str)) {
		array_push($a, ord($str[$b]));
		++$b;
	}
	return $a;
}
 
function calculate($plaintxt, $psw) {
	$sbox = array();
	$mykey = array();
 
	$a = 0;
	$b;
	$c = count($psw);
	$d = 0;
	while ($d <= 255) {
		$mykey[$d] = $psw[$d % $c];
		$sbox[$d] = $d;
		++$d;
	}
	$d = 0;
	while ($d <= 255) {
		$a = ($a + $sbox[$d] + $mykey[$d]) % 256;
		$b = $sbox[$d];
		$sbox[$d] = $sbox[$a];
		$sbox[$a] = $b;
		++$d;
	}
 
	$a = 0;
	$b = 0;
	$c = array();
	$d;
	$e;
	$f;
	$g = 0;
	while ($g < count($plaintxt)) {
		$a = ($a + 1) % 256;
		$b = ($b + $sbox[$a]) % 256;
		$e = $sbox[$a];
 
		$sbox[$a] = $sbox[$b];
 
		$sbox[$b] = $e;
		$h = ($sbox[$a] + $sbox[$b]) % 256;
		$d = $sbox[$h];
		$f = $plaintxt[$g] ^ $d;
		array_push($c, $f);
		++$g;
	}
	return $c;
}
 
function decrypt($src, $key) {
	return charsToStr(calculate(hexToChars($src), strToChars($key)));
}
 
$hashKey = "sdf883jsdf22";
 
$playlist = $_GET["playlist"];
if (!$playlist) {
	exit;
}
$url = "http://pl.playlist.com/pl.php?playlist=".$playlist;
 
$dom = new DOMDocument("1.0", "UTF-8");
$dom->formatOutput = true;
 
$playlist = $dom->createElement("playlist");
$playlist->setAttribute("version", "0");
$playlist->setAttribute("xmlns", "http://xspf.org/ns/0/");
$dom->appendChild($playlist);
 
$metaCacheControl = $dom->createElement("meta");
$metaCacheControl->setAttribute("http-equiv", "Cache-Control");
$metaCacheControl->setAttribute("content", "no-cache");
$playlist->appendChild($metaCacheControl);
 
$metaPragma = $dom->createElement("meta");
$metaPragma->setAttribute("http-equiv", "Pragma");
$metaPragma->setAttribute("content", "no-cache");
$playlist->appendChild($metaPragma);
 
$info = $dom->createElement("info", $url);
$playlist->appendChild($info);
 
$contents = file_get_contents($url, "r");
if (!empty($contents)) {
	$xml = new SimpleXMLElement($contents);
	if (!empty($xml)) {
		$title = $dom->createElement("title", $xml->title);
		$playlist->appendChild($title);
 
		$trackList = $dom->createElement("trackList");
		$playlist->appendChild($trackList);
 
		if ($xml->trackList && (count($xml->trackList) > 0)) {
			foreach ($xml->trackList->track as $item) {
				$track = $dom->createElement("track");
				$trackList->appendChild($track);
 
				$location = $dom->createElement("location");
				$usableLocation = empty($item->location) ? $item->originallocation : decrypt($item->location, $hashKey);
				$location->appendChild($dom->createTextNode($usableLocation));
				$track->appendChild($location);
 
				$title = $dom->createElement("title");
				$title->appendChild($dom->createTextNode($item->tracktitle));
				$track->appendChild($title);
 
				$creator = $dom->createElement("creator");
				$creator->appendChild($dom->createTextNode($item->artist));
				$track->appendChild($creator);
 
				/*
				$duration = $dom->createElement("duration");
				$creator->appendChild($dom->createTextNode($item->duration));
				$track->appendChild($duration);
				*/
 
				/*
				$album = $dom->createElement("album");
				$creator->appendChild($dom->createTextNode($item->album));
				$track->appendChild($album);
				*/
 
				/*
				$image = $dom->createElement("image");
				$creator->appendChild($dom->createTextNode($item->image));
				$track->appendChild($image);
				*/
			}
		}
	}
}
 
header("Content-Type: application/xspf+xml");
 
echo $dom->saveXML();
Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
  • Add to favorites
  • BlinkList
  • Diggita
  • Diigo
  • DZone
  • email
  • Fark
  • FriendFeed
  • Global Grind
  • HackerNews
  • LinkedIn
  • Linkter
  • MyShare
  • MySpace
  • Netvibes
  • Netvouz
  • NewsVine
  • Ping.fm
  • Propeller
  • RSS
  • Simpy
  • Slashdot
  • StumbleUpon
  • Suggest to Techmeme via Twitter
  • Technorati
  • Tumblr
  • Twitter
  • Yahoo! Buzz
Comments (4) Trackbacks (1)
  1. Dear mr Fehrenbacher,

    I like the yahoo media player a lot, am experimenting a lot with it.
    I’m trying to feed it with dynamic playlists, generated by php. But whatever I try, I don’t get it working.
    I see that in your site you’re using php to generate the playlists (ef.ymp.playlistproxy.php).
    Any chance you can share this code? I would be very grateful!

    Thanx, greetings, Jaap (Amsterdam, Holland)

  2. umm, all of the code is like 5 inches above where you typed your comment ;/

  3. Stupid, stupdid, stupdid …!!

    Although I see myself as a very very intelligent person (and I am!!!), there are days that I think: “$%@#$#$%!!!”

    I can’y believe I didn’t see that that was the code I meant!
    (maybe my age is getting to me :-( )

    Anyway, Thanks a lot, sorry for the stupid comment…

    greetings, Jaap

  4. I will soon be getting rid of this in favor of YQL. So it will all be in the cloud soon, no need to host the script anywhere. :) Don’t hold your breath though I am a busy boy.


Leave a comment