Build an OpenEMI music app with Echo Nest
The Echo Nest offers a great API for creating apps using content licensed via the OpenEMI initiative. Marc George explains how to use it to build an app to play Gorillaz tracks
This article first appeared in issue 233 of .net magazine – the world's best-selling magazine for web designers and developers.
Last November, EMI Music teamed up with music intelligence platform The Echo Nest to provide developers with access to an incredible collection of music-related assets. Including material from high profile and well-loved artists such as Gorillaz, Pet Shop Boys, Tinie Tempah, Professor Green and many others. This collaboration represents the most extensive collection of licensed music, video and images to ever be made available in this way.
The Echo Nest provides a fantastic developer API that will not only serve up the assets but can also analyse audio tracks and provide detailed metadata about them. If you’re into music, The Echo Nest API has some amazing tools to build mashups and apps with.
Getting started
The first decision that you’ll need to make is over which of the huge treasure chest of assets you want to make use of in your app. Assets are organised into ‘sandboxes’: individual collections grouped by artist, label or genre. You can get an overview of a sandbox’s contents by browsing the available ones – these range from the Blue Note label’s jazz, to an electronic music retrospective and Robbie Williams’s back catalogue, so quite a few bases are covered!
In order to get access, you’ll need to sign up to the Echo Nest developer programme. When you’ve registered, log in and go to the Sandboxes tab. Click on any of the sandboxes that might take your fancy, then read and agree to the terms, and press the Sign Up button. You might have to wait a little while, but you’ll be sent an email notification when your sandbox access has been approved and then you can start using the API.
Client libraries
The API responds to HTTP requests with JSON or XML responses. There are many Echo Nest client libraries available that will construct API requests for you. You’ll find lots on the Downloads page. One thing to watch is that not all of the libraries listed there have implemented the Sandbox API. In this tutorial we’re going to be using PHP, with a fork of Brent Shaffer’s client, which includes the Sandbox methods. The code is hosted on GitHub; if you have Git installed you can clone the repository with:
git clone github.com/theflyingbrush/php-echonest-api.git
If you don’t happen to have Git yet, then download it from the zip link on the same GitHub URL. The PHP client library depends upon cURL support, so you’ll need your PHP install to have been compiled with it. You’re also going to want to run the code examples below in your local L/M/WAMP set-up.
Using the API
Create a new project folder on your development server and Git clone the repository into it. If you’ve downloaded the zip, unzip it to your project and rename it php-echonest-api.
To authenticate with the API you’ll need the following pieces of information from your Echo Nest developer account: your API Key, Consumer Key and Shared Secret. All of these can be found on your Account page at the Echo Nest developer centre.
Get top Black Friday deals sent straight to your inbox: Sign up now!
We curate the best offers on creative kit and give our expert recommendations to save you time this Black Friday. Upgrade your setup for less with Creative Bloq.
You’ll also need to know the name of the sandbox that you have been given access to. This is found on the Sandboxes tab of your developer account, in the middle column. As an example the Gorillaz sandbox has a key of emi_gorillaz.
The Sandbox API has two different methods: sandbox/list and sandbox/access. The sandbox/list method returns a paginated list of assets and doesn’t require any special authentication (other than your API key, and approved Sandbox access). However, sandbox/access requires additional authentication with OAuth.
Here’s how to instantiate the Sandbox API and authenticate it:
<?php require("php-echonest-api/lib/EchoNest/Autoloader.php"); EchoNest_Autoloader::register(); define("API_KEY", "{YOUR API KEY}"); define("SANDBOX_KEY", "{YOUR SANDBOX KEY}"); define("CONSUMER_KEY", "{YOUR CONSUMER KEY}"); define("SHARED_SECRET", "{YOUR SHARED SECRET}"); $echonest = new EchoNest_Client(); $echonest->authenticate( API_KEY ); $echonest->setOAuthCredentials( CONSUMER_KEY, SHARED_SECRET ); $sandbox = $echonest->getSandboxApi(array("sandbox" => SANDBOX_KEY));?>
Now the $sandbox variable is an authenticated instance of the API, and you can get a list of the contents of the sandbox like this:
<?php $assets = $sandbox->getList(); var_dump($assets);?>
The response from a getList() call is a PHP associative array, with the following keys: status (an array of information about the request), start (the index of the first asset returned), total (the number of assets in the sandbox) and assets (an array of asset descriptions). The assets key points to a subarray, each item describing an available asset. A typical asset looks like this:
Array ( [echonest_ids] => Array ( [0] => Array ( [foreign_id] => emi_artists:track:EMIDD0779716 [id] => TRGHIRC1334BAE7AD6 ) ) [title] => Spitting Out The Demons [filename] => emi_gorillaz/EMIDD0779716.mp3 [release] => D-Sides (Special Edition) [type] => audio [id] => 6aff61700721ca5b9262a06ef8cea717 )
Without parameters, getList() will return up to 15 assets per call, starting from the first one. You can pass an array of options to getList() and modify the default behaviour, which looks like this:
<?php $options = array("results" => 100, "start" => 100); $assets = $sandbox->getList($options); var_dump($assets);?>
Providing there are enough assets in the sandbox, the previous request would return 100 assets starting at the 100th. If there aren’t enough (or indeed any at all), then you’ll end up with a smaller or empty assets array.
Retrieving assets
So, now you have some assets to work with, how do you get hold of them? Here, sandbox/access is the method to use, and it accepts one parameter: a unique asset ID. Many assets have only one simple ID, but audio assets can also have echonest_ids that associate assets with tracks in the wider Echo Nest API, and provide interoperability with other sandboxes via Project Rosetta Stone namespacing; read more on this in the documentation online.
So, taking the Spitting Out The Demons asset above, we’d access it with the following code:
<?php $asset = $sandbox->access("6aff61700721ca5b9262a06ef8cea717"); var_dump($asset);?>
The response from this request is an associative array, organised in the same way as a call to getList(), except that the items in assets use only URL and ID keys, URL being the one of interest as it is a link to the actual asset file. Asset links are timestamped, so cannot be cached or used after expiry.
Indexing a sandbox
Although the Sandbox API enables us to page through assets using the results and start parameters of getList() it doesn’t provide any facility to search for specific items. If you want to locate a particular asset you’re going to have to make repeated getList() calls until you find it – which is inconvenient, slow, and will devour your API allowance. The approach to take, of course, is to create your own inventory and cache it so you can refer to it later.
There are many ways you can go about accomplishing this, but probably the easiest method is to store your getList() results in a database. After you’ve created a new database, you’ll need to loop over getList() calls, paging through the sandbox and storing the results as you go. In the example below, I’m making use of an existing MySQL connection, database, and an assets table:
<?php $page = 0; $num_assets = 0; do { $list = $sandbox->getList(array("results" => 100, "start" => $page * 100)); foreach($list["assets"] as $asset){ if(!empty($asset["echonest_ids"])){ $track_id = $asset["echonest_ids"][0]["id"]; } else { $track_id = ""; } if(!empty($asset['title'])){ $title = mysql_real_escape_string($asset['title']); } else { $title = "Untitled"; } $sandbox_id = $asset['id']; $type = $asset['type']; $filename = $asset['filename']; $query = "INSERT INTO 'assets' SET 'title' = '" . $title . "', 'sandbox_id' = '" . $sandbox_id . "', 'type' = '" . $type . "', 'filename' = '" . $filename . "', 'track_id' = '" . $track_id . "'"; $success = mysql_query($query) or die(mysql_error()); if($success === true){ $num_assets += 1; } } $page += 1; } while(!empty($list["assets"])); echo "Complete. Retrieved $num_assets assets.";?>
All being well, you should have a full table of assets that you can query against filename, asset type, title or Echo Nest ID. Having a searchable index like this is the cornerstone of building your own apps.
Profiling track assets
As mentioned earlier, The Echo Nest API can analyse audio and describe it in detail. The Echo Nest Analyzer is described as the world’s only ‘listening’ API: it uses machine listening techniques to simulate how people perceive music.
When you’re working with Sandbox API audio assets, the methods of most use are song/search (part of the Song API), playlist/static (from the Playlist API), and track/profile (part of the Track API). Songs and tracks are conceptually separate: the Song API returns broadly discographic information, where the Track API deals with specific audio data and analysis.
The song/search method enables you to query the Echo Nest database for songs by title or artist, but also those that meet any listening criteria that you may have, including categories like ‘danceability’, ‘energy’, or ‘mood’.
To use the Song API with sandboxes typically involves code like this:
<?php $song_api = $echonest->getSongApi(); $params = array("bucket" => array("id:emi_artists","tracks"), "artist" => "Gorillaz", "limit" => true, "min_danceability" => 0.5); $results = $song_api->search($params); var_dump($results);?>
The critical parameters in the call above are bucket and limit. The sandbox index that you made earlier will have track IDs, rather than song IDs in it, so you’ll need to instruct the Song API to return track IDs. You can do this by passing a two element array to bucket, containing tracks and a Rosetta namespace.
The namespace that you use depends on which sandbox you have access to. So for instance, if you’re working with the Bluenote sandbox, you would use id:emi_bluenote here. (You can check the Project Rosetta Stone entry in the online documentation at the developer centre for further information on this.)
You also need to make sure that results are limited to the namespace, so pass true to the limit parameter also. There’s a wealth of track profile parameters to use, for instance min_danceability as I’ve used here. Again, refer to the documentation for the whole shebang.
Each result returned from a song/search request will contain a track subarray that lists track IDs. Use these IDs to match the track_id in your index database. In this way you can search for a song, look up the track ID in your index and then retrieve the asset using the unique asset ID: playlist/static is interchangeable with song/search, except the songs returned are random and non-repeating.
The track/profile method works in reverse by accepting a track ID and returning not only the high-level information, but also the URL of a beat-bybeat analysis of the entire track. These complete analyses are incredibly detailed and have been used as the basis of some highly impressive Echo Nest hacks.
Example app
I’ve put together an example app that employs all of the methods described above. It uses the Gorillaz sandbox, but you’re welcome to download it and then configure it with your own keys if you want to try it out against a different one.
You’ll need an Amazon Product Advertising API developer account for this, because it draws in artwork from there. For fun, I’m visualising the data with three.js, the WebGL library – and it’s only compatible with Google Chrome at the moment.
How it works
First the app makes a playlist/static call for Gorillaz tracks in the id:emi_ artists namespace. It then makes a title search against the Amazon API and the iTunes Search API, and tries to find album artwork for each Echo Nest song.
When the data is loaded I use three.js to make a 3D carousel. When a carousel item is clicked, the app looks up the track is in the local index and then makes two calls – the first to track/profile for the high-level audio analysis (danceability, energy, speechiness and tempo), which is then shown as a simple 3D bar graph.
Finally we make a call to sandbox/access to download the associated mp3 and play it. You can preview the app and get the source from GitHub.
Discover 15 stunning examples of CSS3 animation at our sister site, Creative Bloq.
Thank you for reading 5 articles this month* Join now for unlimited access
Enjoy your first month for just £1 / $1 / €1
*Read 5 free articles per month without a subscription
Join now for unlimited access
Try first month for just £1 / $1 / €1
The Creative Bloq team is made up of a group of design fans, and has changed and evolved since Creative Bloq began back in 2012. The current website team consists of eight full-time members of staff: Editor Georgia Coggan, Deputy Editor Rosie Hilder, Ecommerce Editor Beren Neale, Senior News Editor Daniel Piper, Editor, Digital Art and 3D Ian Dean, Tech Reviews Editor Erlingur Einarsson and Ecommerce Writer Beth Nicholls and Staff Writer Natalie Fear, as well as a roster of freelancers from around the world. The 3D World and ImagineFX magazine teams also pitch in, ensuring that content from 3D World and ImagineFX is represented on Creative Bloq.