Building a Spotify App

On Wednesday November 30, Spotify announced their Spotify Apps platform that will let developers create Spotify-powered music apps that run inside the Spotify App.   I like Spotify and I like writing music apps so I thought I would spend a little time kicking the tires and write about my experience.

First thing, the Spotify Apps are not part of the official Spotify client, so you need to get the Spotify Apps Preview Version.  This version works just like the version of Spotify except that it includes an APPS section in the left-hand navigator.

If you click on the App Finder  you are presented with a dozen or so Spotify Apps including Last.fm,  Rolling Stones, We are Hunted and Pitchfork.  It is worth your time to install a few of these apps and see how they work in Spotify to get a feel for the platform. MoodAgent has a particularly slick looking interface:

A Spotify App is essentially a web app run inside a sandboxed web browser within Spotify.  However, unlike a web app you can’t just create a Spotify App, post it on a website and release it to the world. Spotify is taking a cue from Apple and is creating a walled-garden for their apps. When you create an app, you submit it to Spotify and if they approve of it, they will host it and it will magically appear in the APPs sections on millions of Spotify desktops.

To get started you need to have your Spotify account enabled as a ‘developer’. To do this you have to email your credentials to  platformsupport@spotify.com.    I was lucky, it took just a few hours for my status to be upgraded to developer (currently it is taking one to three days for developers to get approved).  Once you are approved as a developer, the Spotify client automagically gets a new ‘Develop’ menu that gives you access to the Inspector, shows you the level of HTML5 support and lets you easily reload your app:

Under the hood, Spotify Apps is based on Chromium so those that are familiar with Chrome and Safari will feel right at home debugging apps.  Right click on your app and you can bring up the familiar Inspector to get under the hood of your application.

Developing a Spotify App is just like developing a modern HTML5 app.  You have a rich toolkit: CSS, HTML and Javascript. You can use jQuery, you can use the many Javascript  libraries. Your app can connect to 3rd party web services like The Echo Nest.  The  Spotify Apps supports just about everything your Chrome browser supports with some exceptions: no web audio, no video, no geolocation and no Flash (thank god).

Since your Spotify App is not being served over the web, you have to do a bit of packaging to make it available to Spotify during development.   To do this you create a single directory for your app. This directory should have at least the index.html file for your app and a manifest.json file that contains info about your app.  The manifest  has basic info about your app.  Here’s the manifest for my app:

% more manifest.json
{
 "BundleType": "Application",
 "AppIcon": {
     "36x18": "MusicMaze.png"
  },
 "AppName": {
     "en": "MusicMaze"
  },
 "SupportedLanguages": [
     "en"
 ],
 "RequiredPermissions": [
     "http://*.echonest.com"
 ]
}

The most important bit is probably the ‘RequiredPermissions’ field. This contains a list of hosts that my app will communicate with. The Spotify App sandbox will only let your app talk to hosts that you’ve explicitly listed in this field. This is presumably to prevent a rogue Spotify App using the millions of Spotify desktops as a botnet.  There are lots of other optional fields in the manifest. All the details are on the Spotify Apps integration guidelines page.

I thought it would be pretty easy to port my MusicMaze to Spotify.   And it turned out it really was. I just had to toss the HTML, CSS and Javascript into the application directory, create the manifest, and remove lots of code.  Since the Spotify App version runs inside Spotify, my app doesn’t have to worry about displaying album art, showing the currently playing song, album and artist name, managing a play queue, support searching for an artist. Spotify will do all that for me. That let me remove quite a bit of code.

Integrating with Spotify is quite simple (at least for the functionality I needed for the Music Maze). To get the currently playing artist I used this code snippet:

var sp = getSpotifyApi(1);
function getCurrentArtist() {
   var playerTrackInfo = sp.trackPlayer.getNowPlayingTrack();
   if (playerTrackInfo == null) {
      return null;
   } else {
      return track.album.artist;
   }
}

To play a track in spotify given its Spotify URI use the snippet:

function playTrack(uri) {
     sp.trackPlayer.playTrackFromUri(uri, {
        onSuccess: function() { console.log("success");} ,
        onFailure: function () { console.log("failure");},
        onComplete: function () { console.log("complete"); }
    });
}

You can easily add event listeners to the player so you are notified when a track starts and stops playing. Here’s my code snippet that will create a new music maze whenever the user plays a new song.

function addAudioListener() {
    sp.trackPlayer.addEventListener("playerStateChanged", function (event) {
        if (event.data.curtrack) {
            if (getCurrentTrack()  != curTrackID) {
                var curArtist = getCurrentArtist();
                if (curArtist != null) {
                    newTree(curArtist);
                }
            }
        }
    });
}

Spotify cares what your app looks like.  They want apps that run in Spotify to feel like they are part of Spotify. They have a set of UI guidelines that describe how to design your app so it fits in well with the Spotify universe.   They also helpfully supply a number of CSS themes.

Getting the app up and running and playing music in Spotify was really easy. It took 10 minutes from when I received my developer enabled account until I had a simple Echo Nest playlisting app running in Spotify

Getting the full Music Maze up and running took a little longer, mainly because I had to remove so much code to make it work.  The Maze itself works really well in Spotify.   There’s quite a bit of stuff that happens when you click on an artist node.  First, an Echo Nest artist similarity call is made to find the next set of artists for the graph. When those results arrive, the animation for the expanding the graph starts.  At the same time another call to Echo Nest is made to get an artist playlist for the currently selected artist. This returns a list of ‘good’ songs by that artist.  The first one is sent off to Spotify for it to play.  Click on a node again and the next song it that list of good songs plays.  Despite all these web calls, there’s no perceptible delay from the time you click on a node in the graph until you hear the music.

Here’s a video of the Music Maze in action.  Apologies for the crappy audio, it was recorded from my laptop speakers.

[youtube http://youtu.be/finObm36V6Y]

Here’s the down side of creating a Spotify App.  I can’t show it to you right now.  I have to submit it to Spotify and only when and if the approve it, and when they decided to release it will it appear in Spotify.  One of the great things about web development is that you can have an idea on Friday night and spend a weekend writing some code and releasing it to the world by Sunday night.  In the Spotify Apps world, the nimbleness of the web is lost .

Overall, the developer experience for writing Spotify Apps is great.  It is a very familiar programming environment for anyone who’s made a modern web app. The debugging tools are the same ones you use for building web apps. You can use all your favorite libraries and toolkits and analytics packages that you are used to.   I did notice some issues with some of  the developer docs – in the tutorial sample code the ‘manifest.json’ is curiously misspelled ‘maifest.json’.  The JS docs didn’t always seem to match reality.   For instance, as far as I can tell, there’s no docs for the main Spotify object or the trackPlayer.  To find out how to do things, I gave up on the JS docs and instead just dove into some of the other apps to see how they did stuff . (I love a world where you ship the source when you ship your app).  Update – In the comments Matthias Buchetics points us to this Stack Overflow post that points out where to find the Spotify JavaScript source in the Spotify Bundle.  At least we can look at the code until the time when Spotify releases better docs.

Update2 – here’s a gist that shows the simplest Spotify App that calls the Echo Nest API.  It creates a list of tracks that are similar to the currently playing artist.  Another Echo Nest based Spotify App called Mood Knobs is also on github.

From a technical perspective, Spotify has done a good job of making it easy for developers to write apps that can tap into the millions of songs in the Spotiverse.   For music app developers, the content and audience that Spotify brings to the table will be hard to ignore.  Still there are some questions about the Spotify Apps program that we don’t know the answer to:

  • How quickly will they turn around an app?  How long will it take for Spotify to approve a submitted app? Will it be hours, days, weeks?  How will updates be managed?  Typical web development turnaround on a bug fix is measured in seconds or minutes not days or weeks.  If I build a Music Hack Day hack in Spotify, will I be the only one able to use it?
  • How liberal will Spotify be about approving apps? Will they approve a wide range of indie apps or will the Spotify App store be dominated by the big music brands?
  • How will developers make money?  Spotify says that there’s no way for developers to make money building Spotify apps. No Ads, no revenue share.  No 99 cent downloads.  It is hard to imagine why developers  would flock to a platform if there’s no possibility of making money.

I hope to try to answer some of these questions. I have a bit of cleanup to do on my app, but hopefully sometime this weekend, I’ll submit it to Spotify to see how the app approval process works.  I’ll be sure to write more about my experiences as I work through the process.

, , ,

  1. #1 by Bruce Warila (@brucewarila) on December 2, 2011 - 10:29 am

    Thanks for grinding this out so quickly. Useful stuff for sure.

  2. #2 by Matthias Buchetics on December 2, 2011 - 10:35 am

    Good post! I had the same issues with the documentation though, a reference of the core API object would really be useful. Right now it’s more trial and error, trying to inspect the available apps to find useful code snippets. Also, they mention the built-in resources and images but there is no way to see what is available (and where), correct?
    Hope they provide some additional documents soon.

    • #3 by Johannes on December 2, 2011 - 5:58 pm

      • #4 by Paul on December 2, 2011 - 7:10 pm

        Johannes – those APIs don’t seem to match what you need to write an app. For instance, the tutorial says I should call ‘getSpotifyApi’ but I can’t find anywhere in the docs that describes getSpotifyApi, or the object it returns. Likewise, the tutorial shows an object called sp.trackPlayer that has methods like addEventListener() and getNowPlayingTrack(), but if I look at the docs for the model Player in the api/reference the only method I see is ‘play()’. The docs just don’t seem to match the tutorial or what some of the early apps like the Last.fm app are actually using. Perhaps the wrong docs are released? — Paul

  3. #5 by Marni on December 2, 2011 - 2:00 pm

    As always, this is such an interesting blog, even for the non-developer.
    As a Spotify user, it’s nice to know where the apps are (kinda) hidden.
    Let us know when and if they have answers to those key questions.

  4. #6 by anthony on December 2, 2011 - 11:57 pm

    Thanks for the post. I have so many cool ideas I would like to explore with Spotify. Very helpful post.

  5. #7 by tomardernm on December 3, 2011 - 9:09 am

    Thank you so much – this helped perfectly!

    Exactly what I wanted to do :) Great great stuff :)

  6. #8 by Beldar on December 4, 2011 - 9:41 am

    Hi!

    I’m trying to do a test application too, but I can’t get to retrieve data from cross-domain in my case from youtube feed, did you encounter any problems with that?

    Any solutions?

    Thanks!

    • #9 by Paul on December 4, 2011 - 9:44 am

      Beldar – I uses JSONP for cross-domain requests. That works fie for me. I’ve heard of others trying straight JSON, but having their requests ‘cancelled’ from within the spotify app.

      (note that spotify doesn’t support flash or the video element, so don’t plan on playing a video inside spotify)

      • #10 by anonimoeldar on December 5, 2011 - 10:40 am

        Thanks Paul, the problem is that the response is in XML format not JSON, can I use JSONP with a XML response?

        And I was planing using HTML5 video tag, but I’m not sure youtube lets you embed HTML5 videos..

        Thanks!

      • #11 by Paul on December 5, 2011 - 3:05 pm

        Beldar – I think you need to talk to a service that supports JSONP directly. Even if you get info back from youtube, you will be out of luck since Spotify doesn’t support the video element. — Paul

      • #12 by Matthias Buchetics on December 6, 2011 - 4:19 am

        I am able to use straight JSON with my own custom API backend. First, you need to set the RequiredPermissions in the manifest correctly. Still wasn’t working for me until I changed my server code to add the “Access-Control-Allow-Origin: *” header to all API responses. Works fine now.

      • #13 by Jon on December 11, 2011 - 9:30 am

        Would you mind sharing the method you are using for this?

        I have tried the following to do jquery calls:
        $.get(url, callback(), ‘jsonp’);

        And the following on the PHP backend:
        echo $_GET[‘callback’] . ‘(‘.json_encode($songs).’)’;

        Works well in a regular Chrome browser, but in Spotify I get the dreaded “canceled” status…

      • #14 by Jon on December 12, 2011 - 3:21 pm

        Solved!

        Alex says in post #31 down below:

        “When I was building the app, I initially got tons of cancelled requests to the server. You need to add the url to the RequiredPermissions in the manifest and *restart* your Spotify client.”

        Restarted – voîlà!

  7. #15 by onthedll on December 4, 2011 - 2:34 pm

    I also want to thank you for providing this tutorial – very helpful!

    One thing I can’t seem to figure out… and based on the Music Maze it looks like you’ve come across a solution. How do I search for song’s within Spotify’s streaming catalog and determine their URI so I can pass along to the play function? If I want to say… “Search for Radiohead and play the top track that comes back as a result”, how do I do that search and get the URI as a result?

    • #16 by onthedll on December 6, 2011 - 4:09 pm

      Answering my own question… just in case its of interest to anyone. I managed to dig into the Spotify search API by examining the contents of the Spotify App Bundle (thanks to whoever discovered that!) and here’s a function that will do a search of Spotify and then get the URI of the first result and play it (using the playTrack function Paul shared above in his original post):

      //returns the Spotify URI of the first search result
      function searchForURI(search) {
      var URI;
      console.log(“Searching for…” + search);
      sp.core.search(search, true, true, {
      onSuccess: function(result) {
      //return the URI of the first track
      URI = result.tracks[0].uri; //grabbing the URI at index 0…
      console.log(URI);
      playTrack(URI);
      }
      });
      }

      • #17 by Paul on December 6, 2011 - 4:11 pm

        Nice, thanks onthedll.

  8. #18 by Peter Jaric (@peterjaric) on December 4, 2011 - 5:38 pm

    Nice post, thanks!

    A question if you have the time:

    Can developers share apps between them? If you would send me a zip with your app and I would unpack it somewhere (assuming I had been approved as a developer) would I be able to run it right away? Or is there some kind of lock to prevent that? I am not asking you to send me your app :) but I am wondering if that would be a way to share apps?

    • #19 by Paul on December 4, 2011 - 7:26 pm

      It is possible technically but it would be a violation of the terms of service.

  9. #21 by Matthias Buchetics on December 5, 2011 - 7:58 am

    This answer to my question helped me a lot: http://stackoverflow.com/questions/8353471/spotify-apps-api-any-more-documentation
    You can find the whole source code of the API inside the Spotify folder. I am sure this will change a lot over time but it’s a great starting point until the documentation is better.

    • #22 by Paul on December 5, 2011 - 8:39 am

      Matthias – thanks for the tip.

    • #23 by onthedll on December 6, 2011 - 4:10 pm

      Thank you so much Matthias! Very helpful

  10. #24 by aliekens on December 6, 2011 - 6:12 am

    Can you provide the source of your echo nest app? I can’t seem to talk to the outside world, I’m getting really frustrated with it and would love to see some basic working code. My knowledge of JavaScript is not good enough to reverse engineer e.g. the Last.fm app, so a little example would help me a whole lot more!

    • #25 by Paul on December 6, 2011 - 9:50 am

      Here’s a gist that shows how I call the Echo Nest API from a spotify app: https://gist.github.com/1438262

      • #26 by aliekens on December 6, 2011 - 10:15 am

        Thanks a lot!

      • #27 by jay on December 6, 2011 - 3:18 pm

        Thank you Paul for the code.

        manifest and index are correct. But i still can’t talk to the server.
        status shows cancel.

  11. #28 by Paul on December 6, 2011 - 3:55 pm

    Jay – your app is still trying to talk to the Echo Nest? Or another service? I have seen a few times where Spotify decided not to load up changes, so you may want to try restarting the spotify client if you haven’t already. Also check to make sure that you can make the calls directly from your browser (just c+p the request urls into the url field).

    • #29 by aliekens on December 6, 2011 - 4:34 pm

      Confirmed. Spotify doesn’t seem to load changes to RequiredPermissions in the manifest unless you reload. I had this too when getting your code to work with my service.

    • #30 by jay on December 7, 2011 - 4:33 am

      i did reload exit and open back spotify app. still can’t. I tried to display image from public server with manifest url. no luck.

      i cloned mood-knobs. From the debugger’s network tab. it seems the app trying multiple times to be able to talk to the server.

  12. #31 by martinrosenlidholm on December 6, 2011 - 4:41 pm

    How would one go about developing a Spotify app TDD style?

  13. #32 by Alex on December 7, 2011 - 8:20 pm

    Hey guys,

    I am one of the guys that made Mood Knobs, so here’s my first experience with the platform.

    When I was building the app, I initially got tons of cancelled requests to the server. You need to add the url to the RequiredPermissions in the manifest and *restart* your Spotify client. If that doesn’t work, make sure that your manifest is correct. Spotify will silently ignore any wrong bits in the manifest and will not give you a warning – we’ve made that point to the Spotify developers during Music Hack Day.

    Also, many servers might not answer your requests – that happens because Spotify uses its own protocol (sp://) and many servers are configured to answer only on http or https origins.

    As a last point, sometimes the webkit inspector will show your requests in red, saying ‘cancelled’ but you actually get a response back. This seems like a bug which surprised the Spotify guys.

  14. #33 by Fabian Pimminger (@i_am_fabs) on December 8, 2011 - 3:37 pm

    I’m getting the same request cancelled error messages. That means you’re out of luck if you’re not using your own service and can configure the services to allow the sp:// protocol?

  15. #34 by Matthias Buchetics on December 12, 2011 - 7:11 am

    Looks like you can’t inspect the 3rd party and built-in apps anymore (latest preview build 0.8.0.873) …

  16. #35 by Josh Latham on December 22, 2011 - 5:01 pm

    Hey, I’ve never built an app so this is all new to me. I started playing with the tutorial today. I got the “Hello World” to show up. I’m confused as to where to put things like the following “var sp = getSpotifyApi(1);

    function getCurrentArtist() {
    var playerTrackInfo = sp.trackPlayer.getNowPlayingTrack();
    if (playerTrackInfo == null) {
    return null;
    } else {
    return track.album.artist;
    }
    }”

    In which file do I post that and where? Thanks.

  17. #36 by Peter Watts (@ptrwtts) on December 29, 2011 - 12:07 am

    If anyone’s interested, I’ve whipped together a Kitchen Sink App that demonstrates how to do much of the basic functionality:

    https://github.com/ptrwtts/kitchensink