How to display your most recent last.fm track with PHP

You may have noticed that in the footer of this website, the album artwork of my most recent track is displayed. This will be a short post about how you can do the same.

There are two requirements here:

  1. last.fm account (create one)
  2. API keys (generate some)

This is actually a simple cURL request, and since the last.fm endpoint returns data in JSON format, we can easily manipulate the data. So once you’ve got your API keys, we’ll be making a simple cURL request:

    $user     = '** USERNAME **'; // Enter your username here
    $key      = '** API KEYS **'; // Enter your API Key
    $status   = 'Last Played:'; // default to this, if 'Now Playing' is true, the json will reflect this.
    $endpoint = 'https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=' . $user . '&&limit=2&api_key=' . $key . '&format=json';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $endpoint);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); // 0 for indefinite
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 10 second attempt before timing out
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
    $response = curl_exec($ch);
    $lastfm[] = json_decode($response, true);
    curl_close($ch);

All we’re doing here is accessing the last.fm API at https://ws.audioscrobbler.com/2.0/?, using the getrecenttracks endpoint (full list of endpoints) with our username and API keys for authentication.

It’s worth noting at this point that for some reason the last.fm API requires a minimum of 2 tracks. If we wanted, we could change limit=2 to a higher number and display a few tracks.

We can now var_dump the $lastfm array and see all of the information that last.fm has on our last two tracks. This will include track name, artist, album, artwork, last.fm URL etc.

We’re going to grab the album artwork first. Since there’s multiple elements in our array, we could loop over the 2 tracks and grab the first one – or we can follow the tree and define our variable like so:

$artwork = $lastfm[0]['recenttracks']['track'][0]['image'][2]['#text'];

Note: last.fm will return artwork in 4 image sizes (small, medium, large & extra large) – in the above example, the [2] signifies that we’re grabbing the ‘large’ size. So change this as you please.

So now, if we  var_dump $artwork – we get the full URL of the image from last.fm. Great! Next, we’re going to grab the other information we want and push that into a new array:

$artwork = $lastfm[0]['recenttracks']['track'][0]['image'][2]['#text'];

if ( empty( $artwork ) ) {  // Check if album artwork exists on last.fm, else use our own fallback image
    $artwork = 'img/artwork-fallback.png';
}

$trackInfo = [
    'name'       => $lastfm[0]['recenttracks']['track'][0]['name'],
    'artist'     => $lastfm[0]['recenttracks']['track'][0]['artist']['#text'],
    'link'       => $lastfm[0]['recenttracks']['track'][0]['url'],
    'albumArt'   => $artwork,
    'status'     => $status
];

In the above, we are:

  • Checking that album artwork exists using empty(), and if not – loading our own fallback image
  • Grabbing track name, artist name, artwork, last.fm link
  • Adding our $status variable – the ‘Last Played’ text from the cURL code snippet above.

At this point, all of our track information is accessible via the $trackInfo array. To access each element individually, we can do this:

echo $trackInfo['name']; // Display track name
echo $trackInfo['artist']; // Display artist name
echo $trackInfo['link']; // Display last.fm song link
echo $trackInfo['albumArt']; // Display artwork image URL 

From here, you could simply display this data with HTML and be done. But I’m going to extend this by checking if the track is currently playing and pushing that to our array, while changing $status to reflect this:

if ( !empty($lastfm[0]['recenttracks']['track'][0]['@attr']['nowplaying']) ) {
    $trackInfo['nowPlaying'] = $lastfm[0]['recenttracks']['track'][0]['@attr']['nowplaying'];
    $trackInfo['status'] = 'Now Playing:';
}

If a track is currently being scrobbled to last.fm, the API response will add [nowplaying] => true to the response. This means that it’s safe to assume that ‘if this exists, then the track is currently playing’.

And that’s it! At a bare minimum, you can display the array elements in img and p tags however you’d like.

What I’ve done on my site is place the cURL request and array creation in its own function, which passes the $trackInfo array to a secondary function that displays the formatted data. The end result of that is what you see in the footer.

The last.fm API is quite fun to play with – I’d recommend taking a full look at the endpoints and seeing what you can come up with.

You can view the full code on my GitHub.