Show off the videos of your favourite band with the Yahoo Music API

There's a new kid on the API block in Yahoo land: the Yahoo Music API. It comes with programmatic access to the data on Yahoo Music and supports all the goodies you got to know from other Yahoo APIs: XML or JSON output, option to define a callback method for JSON output and filtering via REST parameters. All of this is explained in detail in the extensive API guide and there is also a Music API forum to get help.

A music video player created using the API and some JavaScript

The really cool thing about the API is that it allows you to get music videos of your favourite arists and play them immediately in your web site with only a few lines of JavaScript. Want to learn how?


All the code examples here are available live at http://ydntest.com/musicapi/ and you can download them as one zip.

Step One: Get an API key

The first thing you need to do is tell Yahoo Music who you are by getting yourself and API key. This is relatively painless, all you need to do is fill out the form at https://developer.yahoo.com/wsregapp and you get back 65 character API key. Done.

Step Two: Get the list of videos and display them

The API method to use to find a list of videos for a certain artist is "Search for Video" and the REST URL (for the US market) is:



http://us.music.yahooapis.com/video/v1/list/search/video/{artist}?

appid={your application ID}

This returns you an XML document as this is the out-of-the-box standard format. As we want to use the data in JavaScript, we'll need to define JSON as the output format and define a callback function to receive the data.



http://us.music.yahooapis.com/video/v1/list/search/video/{artist}?

appid={your application ID}&format=json&callback=videosreceived

This will return the data as an object and send it to the function videosreceived. In order to use it you can do the following, which (once you added your API key) will give you the data of all Depeche Mode videos:

<script type="text/javascript">
function videosreceived(data){
alert(data)
}
</script>
<script type="text/javascript"
src="http://us.music.yahooapis.com/video/v1/list/search/video/
depeche-mode?format=json&callback=videosreceived&
appid={your api key}"></script>

Try the plain example out here.

The data is in JSON format and the interesting part is the Video array with information about each video. If you look at the JSON output you'll find that there is a stunning amount of data for each video. What we need to show videos are: the duration, an image of the video, the video ID and the title. The following script will get them. Instead of just alerting them out, let's create an HTML list.

<script type="text/javascript" charset="utf-8">
function videosreceived(data){
var videos = data.Videos.Video;
var list = document.createElement('ul');
for(var i=0,j=videos.length;i<j;i++){
var title = videos[i].title;
var id = videos[i].id;
var photo = videos[i].Image.url;
var duration = videos[i].duration;
var id = videos[i].id;
var li = document.createElement('li');
var img = document.createElement('img');
img.setAttribute('src',photo);
img.setAttribute('alt','Video screenshot of: ' + title);
li.appendChild(img);
li.appendChild(document.createTextNode(title+' ('+duration+')'));
list.appendChild(li);
}
document.body.appendChild(list);
}
</script>
<script type="text/javascript"
src="http://us.music.yahooapis.com/video/v1/list/search/video/
depeche-mode?format=json&callback=videosreceived&
appid={your api key}"></script>

Try the list example out here.

This works nicely but looks terrible. For starters the video screenshots are too big and the time information doesn't make much sense in seconds as we are used to seeing them in minutes and seconds. The first problem can be resolved changing the size parameter on the photo URL, the second needs a bit of math:

<script type="text/javascript" charset="utf-8">
function videosreceived(data){
var videos = data.Videos.Video;
var list = document.createElement('ul');
for(var i=0,j=videos.length;i<j;i++){
var title = videos[i].title;
var id = videos[i].id;
var photo = videos[i].Image.url;
// resize photo
photo = photo.replace('=385','=75');
// turn duration into minutes and seconds
var duration = videos[i].duration;
var mins = parseInt(duration/60);
var seconds = duration % 60;
if(seconds < 10){
seconds = '0' + seconds;
}
duration = mins + ':' + seconds;
var id = videos[i].id;
var li = document.createElement('li');
var img = document.createElement('img');
img.setAttribute('src',photo);
img.setAttribute('alt','Video screenshot of: ' + title);
li.appendChild(img);
li.appendChild(document.createTextNode(title+' ('+duration+')'));
list.appendChild(li);
}
document.body.appendChild(list);
}
</script>
<script type="text/javascript"
src="http://us.music.yahooapis.com/video/v1/list/search/video/
depeche-mode?format=json&callback=videosreceived&
appid={your api key}"></script>

Try the time and photo size example out here.

Playing the AngelVideos

This displays the list, but it wouldn't play a video yet, now would it? Well, for this the Yahoo Music API has a video player API for us. First, add SWFObject then create a video container and inject the player - ready to play videos.

<script type="text/javascript" src="https://s.yimg.com/lq/lib/flash/
swfobject/1.0/swfobject.js"></script>
<script type="text/javascript" charset="utf-8">
function videosreceived(data){
var player = document.createElement('div');
player.id = 'videocontainer';
document.body.appendChild(player);
var so = new SWFObject('https://s.yimg.com/cosmos.bcst.'+
'yahoo.com/up/fop/embedflv/swf/fop.swf','videoplayer','512',
'322', '9', '#ffffff');
so.addVariable('eID','1301797');
so.addVariable('ympsc','4195351');
so.addVariable('lang','en');
so.addVariable('shareEnable','1');
so.addParam("allowFullScreen","true");
so.addVariable('enableFullScreen','1');
so.addVariable('autoStart','0');
so.addVariable('eh','bandsPlayer.handler');
so.addParam('allowScriptAccess','always');
so.write('videocontainer');
var videos = data.Videos.Video;
var list = document.createElement('ul');
for(var i=0,j=videos.length;i<j;i++){
var title = videos[i].title;
var id = videos[i].id;
var photo = videos[i].Image.url;
// resize photo
photo = photo.replace('=385','=75');
// turn duration into minutes and seconds
var duration = videos[i].duration;
var mins = parseInt(duration/60);
var seconds = duration % 60;
if(seconds < 10){
seconds = '0' + seconds;
}
duration = mins + ':' + seconds;
var id = videos[i].id;
var li = document.createElement('li');
var img = document.createElement('img');
img.setAttribute('src',photo);
img.setAttribute('alt','Video screenshot of: ' + title);
li.appendChild(img);
li.appendChild(document.createTextNode(title+' ('+duration+')'));
list.appendChild(li);
}
document.body.appendChild(list);
}
</script>
<script type="text/javascript"
src="http://us.music.yahooapis.com/video/v1/list/search/video/
depeche-mode?format=json&callback=videosreceived&
appid={your api key}"></script>

Try the player initiation example out here.

In order to play videos, we need to add links to the list calling the player with the right video ID. The player needs the video ID to be preceded by a "v" to work. The player is the element SWFobject injects into the container and you can get a handle to it using getElementById(). The ID is the second parameter in the new SWFObject() call. Doing this, and adding some CSS to make it pretty and we have ourselves a player:

<script type="text/javascript" src="https://s.yimg.com/lq/lib/flash/
swfobject/1.0/swfobject.js"></script>
<script type="text/javascript" charset="utf-8">
function videosreceived(data){
// create a new video player container
var player = document.createElement('div');
player.id = 'videocontainer';
document.body.appendChild(player);
// inject the video player with the id 'videoplayer'
var so = new SWFObject('https://s.yimg.com/cosmos.bcst.'+
'yahoo.com/up/fop/embedflv/swf/fop.swf','videoplayer','512',
'322', '9', '#ffffff');
so.addVariable('eID','1301797');
so.addVariable('ympsc','4195351');
so.addVariable('lang','en');
so.addVariable('shareEnable','1');
so.addParam("allowFullScreen","true");
so.addVariable('enableFullScreen','1');
so.addVariable('autoStart','0');
so.addVariable('eh','bandsPlayer.handler');
so.addParam('allowScriptAccess','always');
so.write('videocontainer');
// get a reference to the video player - this needs to be global!
vidplayer = document.getElementById('videoplayer');
var videos = data.Videos.Video;
var list = document.createElement('ul');
for(var i=0,j=videos.length;i<j;i++){
var title = videos[i].title;
var id = videos[i].id;
var photo = videos[i].Image.url;
// resize photo
photo = photo.replace('=385','=75');
// turn duration into minutes and seconds
var duration = videos[i].duration;
var mins = parseInt(duration/60);
var seconds = duration % 60;
if(seconds < 10){
seconds = '0' + seconds;
}
duration = mins + ':' + seconds;
var id = videos[i].id;
var li = document.createElement('li');
// creata a link pointing to the playID method of the movie player
var a = document.createElement('a');
a.setAttribute('href','javascript:vidplayer.playID("v"+'+id+')');
var img = document.createElement('img');
img.setAttribute('src',photo);
img.setAttribute('alt','Video screenshot of: ' + title);
a.appendChild(img);
a.appendChild(document.createTextNode(title+' ('+duration+')'));
li.appendChild(a);
list.appendChild(li);
}
document.body.appendChild(list);
}
</script>
<script type="text/javascript"
src="http://us.music.yahooapis.com/video/v1/list/search/video/
depeche-mode?format=json&callback=videosreceived&
appid={your api key}"></script>

Try the full example out here.

Doing things right

This is all nice and good, but it is also rather unclean. When you use "javascript" links, the player needs to be a global variable, and there is not much fallback and security measures (will the API work?) in this example. Please leave some comments and we can do a more generic and cleaner version, this is just meant as a start to get you going.

Chris Heilmann
Yahoo Developer Network