Tips for Writing an Awesome Online Service

From Winamp Developer Wiki
Jump to: navigation, search


"A Winamp Online Service is simply a web page"
       quote from an unidentified if not too creative web page developer, circa 2009.

When I first heard the above statement I was somewhat surprised. Winamp Online Services are not just web pages. True, you could create a web page and use it as an Online Service but that would be like, .... well like using your smart phone to just make phone calls. There's so much more creative things that can be done. In this document I'd like to point out some cool things that have already been done with Online Services hopefully generating ideas for even more fantastic mashups.

To start with, if you are unfamiliar with what an Online Service is, you can find an excellent description of creating, submitting and managing a service at the Online_Service_Developer page.

Most importantly, a full description of the JavaScript APIs that can be called from an Online Service can be found at the Complete_JavaScript_API_technology_framework page. These are the api methods that can make Online Services special, far beyond a 'normal' web page. Not to mention that I also wrote the wiki doc above, so if you like this one, the API reference above would also be good.

If you happened to actually read the two links listed above, rather than coming back to them after reading this, you may have realized what I will be driving at in this document:

In order to make an absolutely astounding Online Service, the web page must use the underlying APIs to integrate with the Winamp music player.

To restate this, there are facilities to control and retrieve information from the Winamp player. These apis turn a web page into a cool Winamp Online Service. Can you think of some cool things to do with this?....I thought you could. Let's see some Online Services that have already been done.

Tour Tracker

In case you don't know (check out the Winamp Online Services), the Tour Tracker Online Service provides a way for users to see upcoming concert information for the bands they are currently listening to on the Winamp player. There are links on this service to purchase tickets to the concerts. Way easier than the old days.

Here is some JavaScript code from the Tour Tracker Online Service.

function getartist() {
  if (!artist) {
    if (window.external && window.external.Transport) {
      artist = window.external.Transport.GetMetadata("artist");
      songtitle = window.external.Transport.GetMetadata("title");

      document.location.href="index.php?artist=" + artist;

This code retrieves the artist name and the title from the currently playing track. So what could you do with that? Well, how about....

function loadscript() {
  // just load ONCE on page-load
  if (window.external && window.external.Transport) {
    var refreshval = ReadCookie("refresh");
    if (refreshval == 1) {
      document.getElementById("refreshcheckbox").checked = true;
      rc = window.external.Transport.RegisterForEvents(onEvents);
function unloadscript() {
  if (window.external && window.external.Transport) {
    rc = window.external.Transport.UnregisterFromEvents(onEvents);

Here the JavaScript code is registering to receive 'events' from the Winamp player. The loadscript() function is executed when the web page is first loaded and the unloadscript() is executed when the page is unloaded. The function 'onEvents' is called when events occur in the player. Note that the refresh flag is read from the cookie and is used to set the "refreshcheckbox" UI element on the page. Don't forget to 'Transport.UnregisterFromEvents()' when the page unloads.

function onEvents(event){
  if (event.event == "OnPlay" && document.getElementById
            ("refreshcheckbox").checked == true) {
    if (document.getElementById("WindowBox").style.display=="block") {
      // empty then block
      // don't switch if user is in the process of purchasing tickets!
    } else {

Here is the onEvents handler. event.event == "OnPlay" is the event fired whenever a new music track is started on the Winamp player. What this means is that the Tour Tracker Online Service can retrieve the author and title whenever a new track starts playing. Tour Tracker then uses this information to open a new web page in the browser to a site that can show up-coming concerts for the artist and allow the user to purchase tickets.

function browsetab(urldata) {
  var urltouse = urldata.toLowerCase();
  urltouse = urltouse.replace(' ', '-');

In the following screenshot, you can see that the currently playing song is 'Stuck with You' by Huey Lewis and the News. The Tour Tracker Online Service appears in the browser, showing scheduled concerts for the band. There is an Auto-Refresh checkbox in the upper right corner of the screen (not visible in the screenshot), that will cause Tour Tracker to automatically bring up concert information (if any) for the artist for the next track (John Waite).


Now is that 'just' a web page? I think not.

AOL Radio

The AOL Radio Online Service does something else interesting. Here are two screenshots, one with the default Bento skin and another with a custom skin.

Here's the first


And here's the second


Do you see something different? Okay, Okay, other than the color difference. Did you notice that the AOL Radio Online Service web page changed color also? This is a good example of making an online service blend in with the Winamp player. Also notice the 'Sponsored Links'. This is a good example of NOT making it blend in with the Winamp player. But to be fair, the 'Sponsored Links' is somewhat different than the rest of the page so let's talk about the page itself.

The AOL Radio Online Service web page uses code like the following to obtain the color and font information about the Winamp player.

function updateSkinColors()
  // globals for anyone who wants 'em!
  sColorItemBg = window.external.Skin.GetClassicColor(0); 
  sColorItemFg = window.external.Skin.GetClassicColor(1); 
  sColorWndBg = window.external.Skin.GetClassicColor(2); 
  sColorBtnFg = window.external.Skin.GetClassicColor(3); 
  sColorWndFg = window.external.Skin.GetClassicColor(4); 
  sColorHilite = window.external.Skin.GetClassicColor(5); 
  sColorSel = window.external.Skin.GetClassicColor(6); 
  sColorListHeadBg = window.external.Skin.GetClassicColor(7); 
  sColorListHeadFont = window.external.Skin.GetClassicColor(8); 
  sColorListHeadTop = window.external.Skin.GetClassicColor(9); 
  sColorListHeadMid = window.external.Skin.GetClassicColor(10); 
  sColorListHeadBot = window.external.Skin.GetClassicColor(11); 
  sColorListHeadEmpty = window.external.Skin.GetClassicColor(12); 
  sColorScrollFg = window.external.Skin.GetClassicColor(13); 
  sColorScrollBg = window.external.Skin.GetClassicColor(14); 
  sColorScrollInvFg = window.external.Skin.GetClassicColor(15); 
  sColorScrollInvBg = window.external.Skin.GetClassicColor(16); 
  sColorScrollEmpty = window.external.Skin.GetClassicColor(17); 
  sColorSelbarFg = window.external.Skin.GetClassicColor(18); 
  sColorSelbarBg = window.external.Skin.GetClassicColor(19); 
  sColorInactSelbarFg = window.external.Skin.GetClassicColor(20); 
  sColorInactSelbarBg = window.external.Skin.GetClassicColor(21); 
  sColorPlFg = window.external.Skin.GetPlaylistColor(0); 
  sColorPlCurrentFg = window.external.Skin.GetPlaylistColor(1); 
  sColorPlBg = window.external.Skin.GetPlaylistColor(2); 
  sColorPlSelbar = window.external.Skin.GetPlaylistColor(3); 
  sColorPlGenericFg = window.external.Skin.GetPlaylistColor(4); 
  sColorPlGenericBg = window.external.Skin.GetPlaylistColor(5); 
  sFontName = window.external.Skin.font; 
  sFontSize = window.external.Skin.fontsize; 

The page then uses script such as this to change the page to use the same colors and fonts.

function updateColors()
  $("#wa_body").css("backgroundColor", sColorItemBg);
  $("#nav").css({ backgroundColor: sColorSelbarBg, color: sColorSelbarFg });
  $("#upgrade_msg").css("borderColor", sColorSelbarBg);

In the code above we're adjusting the css attributes for the elements identified with id= parameter set to the text after the "#"s. And we set them to the values we retrieved from the Winamp player in the previous function.

With these functions, you can make an Online Service look totally integrated inside the Winamp player. When done right, it doesn't even look like a separate web page.

Song of the Day

Here is another example of outstanding use of one of the apis, the Transport API.

Below is a snapshot of the "Song of the Day" Online Service from Spinner.


Notice the big, ol' round button in the center of the track information. Notice how the first track has a "Pause" button and all the rest have "Play" buttons. That's because I clicked on the play button for the first song and it started playing and now, I can pause it. If you listen to this track, Winamp will eventually move on to the next track in the playlist and, magically, the buttons will change as Winamp begins to play the next track. Also notice that when you click to play one of the items on the web page, a Playlist is created and the song you selected begins to play. How can this be done? Well, it isn't really magic. You don't need to be Harry Potter to do this.

This can be done using the Transport, Transport Events and Playqueue apis.


The Transport API controls the Winamp player, like pushing buttons on the front of a CD player. When the user presses on the buttons on this page, the page calls the following api methods depending on which button was previously being shown:


Simple, huh?

Transport Events

But how does the web page know to change from the pause image to the play image when the track ends? Conversly, how does it know to switch from play to pause when it starts the next song? The answer is to register for events from the Winamp player. You've seen this already in the first example we talked about, the Tour Tracker Online Service. Remember this api method?


Note: Don't forget to "UnregisterFromEvents" when you are done.

The onEvents function is passed a parameter indicating what kind of event occurred. Let's say "OnPlay" or "OnEndOfFile" (actually the end of a track). With these two events you can change the appropriate images.

PlayQueue API

Now what about that queing things to be played thingy? That can be done with the methods of the PlayQueue api. The following api call will clear the list of tracks to be played. You might want to use the Transport.Stop() api to stop the Winamp player as clearing the play queue will not stop the currently playing song.


To enqueue tracks to be played, you need to call....wait for it..... the Enqueue method.


Where <URL> is replaced with a string containing the URL of the track to be played. Do this for each of the tracks that you want queued.

Finally, how do we get the song that was clicked to begin playing? Especially if it was not the first one in our newly constructed Playqueue? You do this by changing the value of the PlayQueue cursor property.

window.external.PlayQueue.cursor = n;

Where n is the offset into the play queue of the track to be played. Be aware that this value is zero (0) based, meaning the first track in the play queue is at cursor=0.

Now just use the Transport.Play() method to kick off the music.


So. We've looked at three different Winamp Online Services. Each one uses apis to do things that 'normal' web pages cannot. The services are more tightly integrated with the Winamp player to cause some very interesting behaviors. Check out the documentation listed at the front of this article and spur on your imagination to create an Awesome Online Service.