Getting Track Artwork from Spotify using PHP

14th December 2012

At time of writing, Spotify doesn't provide a track's artwork via its API.

So, I've written a simple function to get the image; but please note, not only is it quick and dirty, but it's horribly inefficient and should be used sparingly - at the very least, make sure you cache the results somewhere!

You can access a public-facing web-page about a particular track using the following URL:

http://open.spotify.com/track/[TRACK-ID]

...where [TRACK-ID] is the last part of the track's URI - so for example, for the track represented by the URI spotify:track:5fpizYGbi5IQoEraj6FP0R, the track ID would be 5fpizYGbi5IQoEraj6FP0R, and thus the URL to the page would be:

http://open.spotify.com/track/5fpizYGbi5IQoEraj6FP0R

If you take a look at the HTML source, you'll see a fair few <meta> tags, like so:

<meta charset="utf-8">
<title>Intergalactic by Beastie Boys on Spotify</title>
<meta http-equiv="X-UA-Compatible" content="IE=9">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-itunes-app" content="app-id=324684580">
<meta property="og:site_name" content="Spotify">
<meta property="fb:app_id" content="174829003346">
<meta property="og:title" content="Intergalactic">
<meta property="og:description" content="Intergalactic, a song by Beastie Boys on Spotify.">
<meta property="og:url" content="http://open.spotify.com/track/5fpizYGbi5IQoEraj6FP0R">
<meta property="og:image" content="http://o.scdn.co/image/97092f295b383b1c59445ef9525051655ffa78e3">
<meta property="og:type" content="music.song">
<meta property="og:audio" content="spotify:track:5fpizYGbi5IQoEraj6FP0R">
<meta property="og:audio:type" content="audio/vnd.facebook.bridge">
<meta property="music:duration" content="231">
<meta property="music:album" content="http://open.spotify.com/album/6eGYLONkDMja0MNtZWnRRB">
<meta property="music:album:track" content="7">
<meta property="music:musician" content="http://open.spotify.com/artist/03r4iKL2g2442PT9n2UKsx">
<meta property="music:release_date" content="2009-09-22">
<meta property="twitter:card" content="summary">
<meta property="twitter:url" content="http://open.spotify.com/track/5fpizYGbi5IQoEraj6FP0R">
<meta property="twitter:image" content="http://o.scdn.co/image/97092f295b383b1c59445ef9525051655ffa78e3">
<meta property="twitter:description" content="A song by Beastie Boys on Spotify.">
<meta property="twitter:title" content="Intergalactic">
<meta property="twitter:site" content="@spotify">
<meta property="description" content="Intergalactic, a song by Beastie Boys on Spotify. Don&#39;t have Spotify? Get it at Spotify.com - it&#39;s free!">

There's loads of useful info in there, but this is the line I'm interested in:

<meta property="og:image" content="http://o.scdn.co/image/97092f295b383b1c59445ef9525051655ffa78e3" />

I'm going to use phpQuery to parse the HTML and extract the line I want - it provides a JQuery-like syntax for parsing an HTML document. It's available as a PEAR package, though for the purposes of this post, I simply downloaded it as a single file - here is a direct download link to the version I used.

The code starts with a very simple function for fetching a document using cURL:

function _fetch_url($url){
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_URL, $url);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($ch, CURLOPT_TIMEOUT, 20);

     $ret_data = curl_exec($ch);
     curl_close($ch); 
     return $re_data;
}

There are plenty of other ways of doing this, including file_get_contents, so use whatever you prefer.

Here's the example of a function, get_track_artwork which given a track ID, will return the artwork from Spotify - I've commented it heavily, so it should be self-explanatory:

function get_track_artwork($track_id)
{
     // require the phpQuery library
     require_once('libraries/phpquery/phpQuery-onefile.php');

     // Get the URL to the page for this track
     $track_url = 'http://open.spotify.com/track/' . $track_id;  

     // Grab the HTML
     $html = fetch_url($track_url);//load album cover info from track

     // Create a phpQuery document
     phpQuery::newDocument($html);

     // Get the meta tag og:image using phpQuery
     $image_url = pq('meta[property=og:image')->attr('content');

     // Optionally, get the thumbnail instead of the larger image, by simply substituting the relevant part of the URL
     $image_url = str_replace('image', 'thumb', $image_url);

     return $image_url;
}

Usage is extremely simple:

$track_id = '5fpizYGbi5IQoEraj6FP0R';

$image_url = get_track_artwork($track_id);

Of course if you're starting with a Spotify URI, you'll need to extract the ID, like so:

$track_uri = 'spotify:track:5fpizYGbi5IQoEraj6FP0R';
$track_id = substr($track_uri, strripos($track_uri, ':'));

Again, please use this function with caution - and cache the results!