Spotify and Random Songs

Note: This post was originally published in August 2015

Imagine yourself sitting at your desk on a rainy Friday afternoon, bored out of your skull and not knowing what to listen to. Even though you have access to Spotify and its library of over 30 million songs (and if you're like me, a sizable portion of those divided into playlists), you don't know what to listen and Spotify Radio serves you songs you've heard a million times before.

What do you do? In my case I decided to turn my being bored into a little side project. Spotify has a Web API - so why not build a web site that serves you a random song from their collection? That shouldn't be difficult to accomplish.

TL;DR

Check it out here or view the source code.

The selection procedure

The first question that came to mind, was: what will be the criteria for selecting a 'random' song? Using the Web API's search end point seems pretty complete, so my idea was to generate one or more keywords to send to the end point. That should return a list of songs matching those keyword(s). Sounds easy enough. But how to generate those keywords?

I Googled something like 'most used words in song titles', and got a nice list somewhere (please forgive me for not giving credit, but I forgot the site and can't seem to find it again - apologies) - a little over a hundred words (you can see them here).

So I wrote a method that randomly selects 1 to max (default three) words:

// wordsList is defined above this code

var selectWords = function(max) {  
  if(!max || isNaN(max) || max < 1) max = 1;
  var howMany = Math.ceil(Math.random() * max);
  var words = [];
  for(var i = 0; i < howMany; i++) {
    var r = Math.floor(Math.random() * wordsList.length);
    words.push(wordsList[r]);
  }
  return words;
};

The method returns an array containing one to max words. Exactly what I need!

Search Away

Since I used jQuery to build the site, I can use its getJSON method to get the response from the Spotify Web API, but not before assembling the URL and query string.

In my initial test I used the default limit (amount of results to return), which is 20. But asking for twenty results every time while we only need one seemed a little ludicrous to me. So, to lighten the load on Spotify's services (which is always a polite thing to do), I selected a limit of 1 with an offset between 0 and 5 (which results in the Nth result being returned):

var doSearch = function(options, callback) {  
  var words = selectWords(options.maxWords);
  var offset = Math.ceil(Math.random() * options.maxOffset);
  var url = 'https://api.spotify.com/v1/search?type=track&limit=1&offset=' + offset + '&q=' + words.join('%20');
  $.getJSON(url, callback);
};

Too Many Words (coincidentally a good song too)

Randomly asking for the Nth result does mean it's completely possible that there just aren't that many results, and you don't get anything. I 'fixed' this by recursively calling getRandomSong. It feels kinda weird, and does make another call to the Spotify Web API (something that's impossible to avoid), but it works wonders:

$.getRandomSong = function(options, callback) {
  doSearch(options, function(response) {
    if(response.tracks.total === 0 || response.tracks.items.length === 0)
      return $.getRandomSong(options, callback);
    return callback(response.tracks.items[0]);
  });
};

I have found that randomly selecting three or more words seems to lead to zero results more often than one or two do, which is logical considering there are more variables involved. Three words randomly combined do produce occasional hilarious results though, as on one occasion it asked me to 'Feel Different Please' :)

Display

The format of the result can be found in the Spotify Web API documentation, but I will place the display code here for your convenience. Since I use jQuery, it felt only logical to use it to display the track info:

var displayTrackInfo = function(track) {  
  $('#randomSongTitle').html(track.name);
  $('#randomSongAlbum').html(track.album.name);
  $('#randomSongArtist').html(track.artists[0].name);

  $('#randomSongURI').prop('href', track.uri);
  $('#randomSongPreview').prop('src', track.preview_url);
  $('#randomSongCover').prop('src', track.album.images[0].url);
};

Now I can just call it on the $ (jQuery) object:

$.getRandomSong(displayTrackInfo);

Random Songs ftw

Now that you know how it's built, it's time for you to get a random song yourself. Make sure to click 'New random song' a few times, the results are sometimes very funny :) You can also look at the source code, which is MIT-licensed, so do with it what you want :)

Thanks for reading and I hope you'll be reading my blog in the future!

comments powered by Disqus