Note that this Wiki is a work in progress, items may not be updated or may disappear entirely as the pages are updated.
PlayerSDK Tutorial1
From SpacialAudio
Welcome to the first Player SDK tutorial. We hope to show you how quick it is to develop a powerful player solution with a minimal amount of coding. The goal of this example is not to make a pretty player, but a functional player.
If you follow the steps in this tutorial you will have created a player with the following features:
- Dynamically load station information
- Dynamically load song history
- Dynamically load current track information if no in-stream metadata is available.
- Display sync banners and text ads with in-stream audio ads.
- The player is able to deliver 1-to-1 targeted audio ads (in-stream).
- The player is able to deliver 1-to-1 targeted video ads (in-stream).
- The player will support a wide ranges of installed player plugins (Silverlight, WMP, Flash, etc).
- The player will support a wide range of browsers (IE, FireFox, Chrome, etc).
Contents |
See it in action
Before we get started it might be best if you see what this example will do. If you are using a Mozilla browser like FireFox or Chrome make sure you have the latest version of SilverLight installed. Without it, the demo will be pretty unimpressive!
Once again this demo was not meant to be a pretty player, but show you the basics of how to use the player SDK. So keep that in mind while viewing this demo.
Ok, now that you have seen it - let's get into building your own version...
Step 1: Get listed at AudioRealm
This example depends a lot on AudioRealm to provide it with additional information like station data and track history data. Thus the very first step is to make sure your station is listed on AudioRealm. See this article for more information. Once you are listed on AudioRealm note down your AudioRealm stationID. (The easiest way to do this is to go to AudioRealm.com and search for your station. Then hover your mouse over the speaker icon(listen link) and look at the status bar of your browser. You will see something like javascript:player(12345,-1). The 12345 part is your stationID. Write it down.)
Important: The player SDK certainly does not require your station to list on AudioRealm. However, if you do list on AudioRealm, the Player SDK can automate a lot of tasks for you. In future tutorials we will cover how to work with a player not linked to AudioRealm.
Step 2: Include all the required external references
The Player SDK is written in 100% javascript so it does not require any server-side scripting languages like PHP, ASP or ASP.NET. Thus you can develop a player that takes very little server resources to deliver. In fact, the biggest resources required to make the SDK work is hosted by SpacialAudio - saving you a lot of costs and precious resources.
So the first thing you need to do is include the Player SDK in the header of your HTML page.
<head><title>Player Tutorial</title>
<!-- Include the compressed javascript SDK code --><script language="javascript" type="text/javascript" src="http://media.streamads.com/playersdk/v2/syncmeta.js.gz"></script><link href="textad.css" rel="stylesheet" type="text/css" /></head>
Important: We do not recommend downloading the file and hosting it yourself. The main reason is if we happen to update the Player SDK with enhancements or bug fixes your player will be without them until you download and update the file on your end. We plan to make a LOT of changes to the Player SDK over the next few months, so its best to link direct and be certain you always have the latest version.
You will also note we included a textad.css file. This file is basically used to format and text ads to fit the look & feel of our player.
Step 3: Initialize all settings
We need to wait for the entire page to finish loading before we start using the player SDK. The biggest reason is that the player SDK needs to communicate with the HTML DOM and the DOM might not be ready before the page is fully loaded.
<!-- We need to wait for the page to complete loading before we do our work - thus we assign a function to the body "onload" event --><body onload="pageLoaded();" leftMargin="0" topMargin="0" marginwidth="0" marginheight="0">
Below you will find the pageLoaded(); javascript function.
<script language="javascript" type="text/javascript">
//##============================================================================//## INITIALIZATION//##============================================================================function pageLoaded()
{doitall.stationID = 61540; //AudioRealm station ID
doitall.publisherID = 13100; //StreamAds publisher ID [Only required for 1-to-1 targeting]
doitall.loadStationInfo = true; //Load station information from AudioRealm
doitall.preloadHistory = true; //Load song history from AudioRealm
doitall.useDataPoller = true; //Check for track changes using "polling" method (Data provided by AudioRealm)
doitall.useLocalMedia = true; //Allow client-side targeted content
doitall.RegisterVideoArea('idVideo'); //If you wish to display targeted video content you must register video area
doitall.RegisterSyncIDs(null, null, "idTextAd"); //Register TextAd area (As DOM element)
doitall.RegisterSyncFrames("frmAd300x250", "frmAd728x90", null); //Register cover/banner ads (AS IFRAME areas)
//Subscribe to eventsdoitall.onMedia.subscribe(cbDisplayMedia);
doitall.onAds.subscribe(cbDisplayAds);
doitall.onHistoryLoaded.subscribe(cbHistoryLoaded); //Song history data from AudioRealm loaded
doitall.onStationData.subscribe(cbStationData); //Station information from AudioRealm loaded
doitall.player.onLoaded.subscribe(cbPlayerLoaded); //Player is loaded & ready to be controlled
doitall.onVideoBegin.subscribe(cbVideoBegin); //Video playback is about to start
doitall.onVideoEnd.subscribe(cbVideoEnd); //Video playback ended
doitall.onRestore.subscribe(cbRestore); //Advertisement time-out triggered
//Create playerdoitall.player.mediaurl = 'http://wm5.spacialnet.com/science1/canned/canned-localmedia-v4.wma';
doitall.mediadata.coverpicture_url = 'http://media.streamads.com/playersdk/v2/widgets/webplayer/arplayer/canned/';
doitall.player.showcontrols = true;
doitall.player.width=320;
doitall.player.height=240;
doitall.player.createPlayer('idPlayerSpace');
//Start all basic systemsdoitall.Start();
}</script>
Here is the HTML part of the page:
<table border="1" cellpadding="0" cellspacing="2"><tr><td><div id="idPlayerSpace"></div><div id="idPlayercontrols" style="display: none;"><input type="button" value="Play" onclick="doitall.player.Play();"><input type="button" value="Stop" onclick="doitall.player.Stop();"><input type="button" value="Mute" onclick="doitall.player.toggleMute();">Volume: <input id="idVolume" type="text" size="1" value="0">% <input type="button" value="set" onclick="setVolume();">
</div><div id="idStatus"></div></td><td align="left" valign="top" width="320"><div id="idVideo" style="position: relative; left: 0px; top: 0px"></div></td><td id="tdAd300x250" style="display: none;"><!-- 300x250 "Cover Ad" area --><iframe id="frmAd300x250" width=300 height=250 FRAMEBORDER=0 MARGINWIDTH=0 MARGINHEIGHT=0 SCROLLING=no></iframe></td><td width="200" id="tdTextAd" style="display: none;"><!-- "Text Ad" area --><div id="idTextAd" style="padding: 10px;" ></div></td></tr><tr id="trAd728x90" style="display: none;"><td colspan="4" align="center" valign="middle"><!-- 728x90 "Banner Ad" area --><iframe id="frmAd728x90" width=728 height=90 FRAMEBORDER=0 MARGINWIDTH=0 MARGINHEIGHT=0 SCROLLING=no></iframe></td></tr></table><br><b>Metadata information:</b>
<div id="idMetadata" style="overflow: scroll; width: 660px; height: 200px;"></div><br><b>Station information:</b>
<div id="idStationData" style="overflow: scroll; width: 660px; height: 150px;"></div>
Let's go over the above in detail.
Setting AudioRealm stationID
First thing we set is the stationID. The stationID is your AudioRealm stationID (as discussed in Step 1 above). Because you have specified a stationID you can now enable some automated features:
- By setting doitall.loadStationInfo to TRUE, the SDK will contact AudioRealm and ask it to send back the station name, description, logo picture, etc. and trigger the doitall.onStationData event when the data arrives.
- By setting doitall.preloadHistory to TRUE, the SDK will contact AudioRealm and ask it to send a list of the most recently played songs and store it in the history. The SDK will trigger the doitall.onHistoryLoaded event as soon as the data arrives.
- By setting the doitall.useDataPoller to TRUE, the SDK will contact AudioRealm at regular intervals (15s to 20s) and ask it to send information about the currently playing track. As soon as it is detected that the stream contains in-stream metadata the DataPoller will be stopped as all metadata can then be obtained from the stream.
Whenever new metadata arrives the onMedia, onAds and onData events are triggered (It does not matter if the data arrives via the DataPoller or via in-stream scripts). onData is always triggered, but onAds are only triggered if the songtype=A and onMedia when songtype<>A.
Setting StreamAds advertisement settings
Next you will notice we set the publisherID. This is only required if you wish to support client-side 1-to-1 targeting of both video and audio ads. For more information about StreamAds, please visit StreamAds.com. Note: For testing purposes feel free to use the publisherID of 13100.
To enable 1-to-1 targeting you must set doitall.useLocalMedia to TRUE. If you also wish to support video ads, you must register a video area - basically an HTML DOM element where video ads may be displayed. This is done by this command - doitall.RegisterVideoArea('idVideo');
Important: This video area may never be hidden or moved. However, it may be re-sized to 1x1 pixels while no video ads are playing. (Moving or making the video space invisible will cause the video players to reload and break.)
Next we register the areas where synchronized banners and text ads will be displayed.
doitall.RegisterSyncIDs(null, null, "idTextAd"); //Register TextAd area (As DOM element)
doitall.RegisterSyncFrames("frmAd300x250", "frmAd728x90", null); //Register cover/banner ads (AS IFRAME areas)
The RegisterSyncIDs method registers a DOM element by name (usually a DIV or SPAN element) where the advertisement must be displayed. We usually use this style of display for textads only. The big reason is then we are able to control the look & design of the textad with our own custom CSS. Notice we pass two null values - the first is for the cover-ad space and the second for the banner-ad space. Passing null values indicates that these spaces are not available.
The RegisterSyncFrames methods registers IFRAME areas by name where advertisements must be displayed. In this example we register both a cover-ad IFRAME and a banner-ad IFRAME.
By registering advertisement areas the SDK will automatically display advertisements for you in those areas. In some cases you will need to have more control over the process and display advertisements manually. In later tutorials we will cover how this is done.
Setting up event handlers
Event handlers were mentioned previously, but we will cover them in more detail here. The SDK is fully event driven meaning that your player must simply subscribe to certain events and your code will be executed when those events occur.
Subscribing to event handlers
Lets quickly list all the events we use in this example again. We are certainly not using all available events so make sure to check out the programming reference for full details.
//Subscribe to eventsdoitall.onMedia.subscribe(cbDisplayMedia);
doitall.onAds.subscribe(cbDisplayAds);
doitall.onHistoryLoaded.subscribe(cbHistoryLoaded); //Song history data from AudioRealm loaded
doitall.onStationData.subscribe(cbStationData); //Station information from AudioRealm loaded
doitall.player.onLoaded.subscribe(cbPlayerLoaded); //Player is loaded & ready to be controlled
doitall.onVideoBegin.subscribe(cbVideoBegin); //Video playback is about to start
doitall.onVideoEnd.subscribe(cbVideoEnd); //Video playback ended
doitall.onRestore.subscribe(cbRestore); //Advertisement time-out triggered
We already talked about the onMedia, onAds, onHistoryLoaded and onStationData events so we will limit the discussion here to those events not yet mentioned.
- doitall.player.onLoaded
- This event is called as soon as the player is done loading and ready to be used. It is very important to note that both the Flash and Silverlight player needs to load an external resource before they are functional. The Windows Media player is the only object that is instantly ready to be used. In short you CAN NOT immediately start using the player object right after it is created. You must wait for the onLoaded event to fire before you start using the player.
- doitall.onVideoBegin and doitall.onVideoEnd
- These events are called respectively when a video advertisement is about to be shown or when a video advertisement has played till the end. You can use these events to take special action - usually to hide or move content that is currently occupying the video space. We mentioned this before but will mention it again - never hide the video space completely or move it around. This will cause players to reload and break the functionality.
- doitall.onRestore
- This event is called a few seconds after the last advertisement played (around 15seconds afterward by default). On this event you should clean up the player from sync advertisement content. Basically, hide all sync advertisements or replace them with other content. You can for example change the IFRAMEs to display banners from other sources. (See our IFRAME rotation tutorial)
Setting up Player object
Our player object is initialized be the following code:
//Create playerdoitall.player.mediaurl = 'http://wm5.spacialnet.com/science1/canned/canned-localmedia-v4.wma';
doitall.mediadata.coverpicture_url = 'http://media.streamads.com/playersdk/v2/widgets/webplayer/arplayer/canned/';
doitall.player.showcontrols = true;
doitall.player.width=320;
doitall.player.height=240;
doitall.player.createPlayer('idPlayerSpace');
- doitall.player.mediaurl
- If you have specified a stationID, this line is not needed. The SDK will automatically generate an ASX file for your station that will allow listeners to tune into your station. You can however specifically set the mediaurl to point to your own ASX playlist file. In this example we are pointing it to a "canned demo" audio file. This Windows Media file contains embedded scripts that simulate a live station, making it ideal for testing during development.
- doitall.mediadata.coverpicture_url
- In order to display album cover art pictures one must specify where those pictures are stored on the internet. Usually the SDK can automatically detect this setting from AudioRealm. However, since we are using the "canned demo" audio file from the above link we need to hard-code this URL so it is able to find the album cover art pictures meant to be used with this audio file.
- Note that we won't actually be displaying these album cover pictures in this demo, but you will see the data contained in the output on the page for songs. (See next tutorials for examples that does indeed display album cover pictures)
- doitall.player.showcontrols
- Setting this to true will force the player to show its own controls. Usually you would want to set this to FALSE and provide your own method of controlling the player. In this example we set it to true for demonstration purposes only.
- doitall.player.width and doitall.player.height
- These are pretty easy ... sets the size of the player. In many cases you will simply set the player to a size of 1x1 to make it nearly invisible. You should never hide the player completely as this will stop the player.
- doitall.player.createPlayer('idPlayerSpace');
- This command will actually create the player object in the player space specified. (If none is specified the player will be added to the bottom of the webpage).
Step 4: Implementing event handlers
In the section Setting up event handlers we discussed how we subscribed our events to our event handler functions. The real work is done by the event handlers - see code listing below.
//##============================================================================//## EVENT HANDLERS//##============================================================================function cbDisplayMedia(type, args, me)
{var media = args[0];
DisplayItem(media);
}function cbDisplayAds(type, args, me)
{var ad = args[0];
DisplayItem(ad);
//Make the advertisement areas visiblesetVisibility("tdAd300x250", (ad['coverID']>0));
setVisibility("trAd728x90", (ad['bannerID']>0));
setVisibility("tdTextAd", (ad['textID']>0));
}function cbHistoryLoaded(type, args, me)
{DisplayHistory();
}function cbStationData(type, args, me)
{var stationdata = args[0];
DisplayStation(stationdata);
}function cbPlayerLoaded(type, args, me)
{//Only show controls if we are able to control playerif(doitall.player.isControllable())
{//Make our own custom player controls visiblesetVisibility('idPlayercontrols', true);
//Set the initial player volumevar idVolume = document.getElementById('idVolume');
idVolume.value = doitall.player.getVolume();
//Start timer to update status regularlysetInterval(cbUpdateStatus, 500);
}}function cbUpdateStatus()
{var code = doitall.player.getPlayerStatus();
var msg = doitall.player.getStatusMessage();
DynWrite("idStatus", 'Status: ('+code+') '+msg);
}function cbVideoBegin(type, args, me)
{//Video about to start...}function cbVideoEnd(type, args, me)
{//Video about to ended}function cbRestore(type, args, me)
{//Accompanying banners and text should be removed at this point//if we have something better to display//In this case we simply hide the advertisement areas//as we really have nothing better to do with themsetVisibility("tdAd300x250", false);
setVisibility("trAd728x90", false);
setVisibility("tdTextAd", false);
}
Let's analyze what each of them does in a bit more detail:
- cbDisplayMedia
- This event is called when any non-advertisement content is played, like songs or news. This event extracts the metadata from the args array and then passes it to DisplayItem to display. (See full listing at bottom of this article to see actual DisplayItem function code)
- cbDisplayAds
- This event is called when any advertisement content is played. This event extracts the metadata from the args array and then passes it to DisplayItem to display. (See full listing at bottom of this article to see actual DisplayItem function code)
- Also, the ad information is checked to see what kinds of synchronized content is available and those areas with ads are then made visible.
- cbHistoryLoaded
- This event is called as soon as history data is retrieved from AudioRealm. We simply call DisplayHistory to display the history data on the webpage. (See full listing at bottom of this article to see actual DisplayHistory function code).
- cbStationData
- This event is called as soon as station information is successfully loaded from AudioRealm. The DisplayStation function is called to display the raw station information on the webpage. (See full listing at bottom of this article to see actual DisplayStation function code). Notice how the station information is extracted from the args array.
- cbPlayerLoaded
- This is called as soon as the player is done loading and is ready. The first thing we do is check if the player is controllable (doitall.player.isControllable()). The only case where the player will not be controllable is on a Mozilla browser (like FireFox or Chrome) and they do not have the SilverLight plugin installed, forcing us to use the Windows Media Player plugin. Unfortunately due to security reasons the browser does not allow the javascript to communicate with the player.
- If we detect the player is indeed controllable, we do three things
- Make our custom player controls visible
- Set the initial value of the volume edit box
- Start a timer to update a status message regularly
- cbUpdateStatus
- This event is called by the setInterval timer initialized in the cbPlayerLoaded event handler. This function reads the status code and status message from the player and displays it on the website.
- cbVideoBegin and cbVideoEnd
- These two event handlers were just added for the sake of demonstration. We do not use them in this example.
- cbRestore
- This is called after in-stream ads have played and it's time to clean up any synchronized banners and text ads. In this example we simply hide all advertisement areas, but in your player you will most likely want to display some other content in these areas instead.
Step 5: Controlling the player
Controlling the player object is really simple. This code snippet basically explains everything:
<div id="idPlayercontrols" style="display: none;"><input type="button" value="Play" onclick="doitall.player.Play();"><input type="button" value="Stop" onclick="doitall.player.Stop();"><input type="button" value="Mute" onclick="doitall.player.toggleMute();">Volume: <input id="idVolume" type="text" size="1" value="0">% <input type="button" value="set" onclick="setVolume();">
</div>
Play, Stop and toggleMute is called directly on the player object.
Setting the volume was moved to a javascript function as it is slightly more complicated. It basically finds the Volume input edit box element and then changes the volume to value specified in the Volume input edit box. (Note: There is no error checking, so entering an invalid number will cause problems)
function setVolume()
{var idVolume = document.getElementById('idVolume');
doitall.player.setVolume(idVolume.value);
}
Note: Initialize the controls are set invisible with style="display: none;" and only made visible in the player.onLoaded event once it is verified the player is indeed controllable.
Full code listing
- Note: Replace [html] and [/html] with actual HTML tags. Unfortunately our wiki does not allow posting of these tags.
[html]
<head>
<title>Player Tutorial</title>
<!-- Include the compressed javascript SDK code -->
<script language="javascript" type="text/javascript" src="http://media.streamads.com/playersdk/v2/syncmeta.js.gz"></script>
<link href="textad.css" rel="stylesheet" type="text/css">
</head>
<!-- We need to wait for the page to complete loading before we do our work - thus we assign a function to the body "onload" event -->
<body onload="pageLoaded();" leftMargin="0" topMargin="0" marginwidth="0" marginheight="0">
<table border="1" cellpadding="0" cellspacing="2">
<tr>
<td>
<div id="idPlayerSpace"></div>
<div id="idPlayercontrols" style="display: none;">
<input type="button" value="Play" onclick="doitall.player.Play();">
<input type="button" value="Stop" onclick="doitall.player.Stop();">
<input type="button" value="Mute" onclick="doitall.player.toggleMute();">
Volume: <input id="idVolume" type="text" size="1" value="0">% <input type="button" value="set" onclick="setVolume();">
</div>
<div id="idStatus"></div>
</td>
<td align="left" valign="top" width="320">
<div id="idVideo" style="position: relative; left: 0px; top: 0px"></div>
</td>
<td id="tdAd300x250" style="display: none;">
<!-- 300x250 "Cover Ad" area -->
<iframe id="frmAd300x250" width=300 height=250 FRAMEBORDER=0 MARGINWIDTH=0 MARGINHEIGHT=0 SCROLLING=no></iframe>
</td>
<td width="200" id="tdTextAd" style="display: none;">
<!-- "Text Ad" area -->
<div id="idTextAd" style="padding: 10px;" ></div>
</td>
</tr>
<tr id="trAd728x90" style="display: none;">
<td colspan="4" align="center" valign="middle">
<!-- 728x90 "Banner Ad" area -->
<iframe id="frmAd728x90" width=728 height=90 FRAMEBORDER=0 MARGINWIDTH=0 MARGINHEIGHT=0 SCROLLING=no></iframe>
</td>
</tr>
</table>
<br>
<b>Metadata information:</b>
<div id="idMetadata" style="overflow: scroll; width: 660px; height: 200px;"></div>
<br>
<b>Station information:</b>
<div id="idStationData" style="overflow: scroll; width: 660px; height: 150px;"></div>
<!-- ======================================================================= -->
<script language="javascript" type="text/javascript">
//##============================================================================//## INITIALIZATION//##============================================================================function pageLoaded()
{doitall.stationID = 61540; //AudioRealm station ID
doitall.publisherID = 13100; //StreamAds publisher ID [Only required for 1-to-1 targeting]
doitall.loadStationInfo = true; //Load station information from AudioRealm
doitall.preloadHistory = true; //Load song history from AudioRealm
doitall.useDataPoller = true; //Check for track changes using "polling" method (Data provided by AudioRealm)
doitall.useLocalMedia = true; //Allow client-side targeted content
doitall.RegisterVideoArea('idVideo'); //If you wish to display targeted video content you must register video area
doitall.RegisterSyncIDs(null, null, "idTextAd"); //Register TextAd area (As DOM element)
doitall.RegisterSyncFrames("frmAd300x250", "frmAd728x90", null); //Register cover/banner ads (AS IFRAME areas)
//Subscribe to eventsdoitall.onMedia.subscribe(cbDisplayMedia);
doitall.onAds.subscribe(cbDisplayAds);
doitall.onHistoryLoaded.subscribe(cbHistoryLoaded); //Song history data from AudioRealm loaded
doitall.onStationData.subscribe(cbStationData); //Station information from AudioRealm loaded
doitall.player.onLoaded.subscribe(cbPlayerLoaded); //Player is loaded & ready to be controlled
doitall.onVideoBegin.subscribe(cbVideoBegin); //Video playback is about to start
doitall.onVideoEnd.subscribe(cbVideoEnd); //Video playback ended
doitall.onRestore.subscribe(cbRestore); //Advertisement time-out triggered
//Create playerdoitall.player.mediaurl = 'http://wm5.spacialnet.com/science1/canned/canned-localmedia-v4.wma';
doitall.mediadata.coverpicture_url = 'http://media.streamads.com/playersdk/v2/widgets/webplayer/arplayer/canned/';
doitall.player.showcontrols = true;
doitall.player.width=320;
doitall.player.height=240;
doitall.player.createPlayer('idPlayerSpace');
//Start all basic systemsdoitall.Start();
}//##============================================================================//## EVENT HANDLERS//##============================================================================function cbDisplayMedia(type, args, me)
{var media = args[0];
DisplayItem(media);
}function cbDisplayAds(type, args, me)
{var ad = args[0];
DisplayItem(ad);
//Make the advertisement areas visiblesetVisibility("tdAd300x250", (ad['coverID']>0));
setVisibility("trAd728x90", (ad['bannerID']>0));
setVisibility("tdTextAd", (ad['textID']>0));
}function cbHistoryLoaded(type, args, me)
{DisplayHistory();
}function cbStationData(type, args, me)
{var stationdata = args[0];
DisplayStation(stationdata);
}function cbPlayerLoaded(type, args, me)
{//Only show controls if we are able to control playerif(doitall.player.isControllable())
{//Make our own custom player controls visiblesetVisibility('idPlayercontrols', true);
//Set the initial player volumevar idVolume = document.getElementById('idVolume');
idVolume.value = doitall.player.getVolume();
//Start timer to update status regularlysetInterval(cbUpdateStatus, 500);
}}function cbUpdateStatus()
{var code = doitall.player.getPlayerStatus();
var msg = doitall.player.getStatusMessage();
DynWrite("idStatus", 'Status: ('+code+') '+msg);
}function cbVideoBegin(type, args, me)
{//Video about to start...}function cbVideoEnd(type, args, me)
{//Video about to ended}function cbRestore(type, args, me)
{//Accompanying banners and text should be removed at this point//if we have something better to display//In this case we simply hide the advertisement areas//as we really have nothing better to do with themsetVisibility("tdAd300x250", false);
setVisibility("trAd728x90", false);
setVisibility("tdTextAd", false);
}//##============================================================================//## WORKER FUNCTIONS//##============================================================================function setVolume()
{var idVolume = document.getElementById('idVolume');
doitall.player.setVolume(idVolume.value);
}//This function deletes all the nodes in a DOM tree starting at specified nodefunction DeleteAllChildren(domObj)
{var child = domObj.firstChild;
while(child != null)
{domObj.removeChild(child);
child = domObj.firstChild;
}}function DisplayItem(item)
{var idMetadata = document.getElementById('idMetadata');
DeleteAllChildren(idMetadata);
for (var key in item) //Iterate through all the values the item exposes
{var display = key+": "+item[key];
var objDiv = document.createElement('div');
var objText = document.createTextNode(display);
objDiv.appendChild(objText);
idMetadata.appendChild(objDiv);
}}function DisplayStation(item)
{var idStationData = document.getElementById('idStationData');
DeleteAllChildren(idStationData);
for (var key in item) //Iterate through all the values the item exposes
{var display = key+": "+item[key];
var objDiv = document.createElement('div');
var objText = document.createTextNode(display);
objDiv.appendChild(objText);
idStationData.appendChild(objDiv);
}}function DisplayHistory()
{var list = doitall.mediadata.getMediaHistory(1, "S,A"); //Return one item with songtype of A or S (Advertisement or Normal song)
for(var i=0; i<list.length; i++) //Iterate through all the items returned (Should only be 1)
{DisplayItem(list[i]);
}}</script>
</body>
[/html]
