Build a Better Web Audio Player
Pages: 1, 2, 3

The Phantom Plugin

Fig. 3. Firefox Windows Fails

Figure 3. Windows users will likely see this show-stopper if they aren't running Internet Explorer or QuickTime. Annoyingly, non-IE browsers usually do have the necessary plugin to play this audio file, but must be told where to find it.

The problem turned out to be the way Windows browsers handle audio. If QuickTime is installed, the pop-up audio player seems to work fine. If QuickTime is absent, Internet Explorer still works, because it can automatically embed the Windows Media Player. But other Windows browsers, like Firefox and Opera, must use the ancient Windows Media plugin instead. Because my original script didn't specify the plugin, Firefox and Opera would throw an error like the one in Figure 3.

So, to make the player work, I had to tell Macs to use QuickTime and Windows PCs to use the Windows Media plugin. To do that, I first make the script detect the visitor's operating system. Next, it determines the audio file's MIME type so the player will know how to handle it. Windows players will always get the MIME type application/x-mplayer2, which calls the Windows Media plugin. Macs (and Linux) will get a MIME type derived from the file's extension. For MP3 files, that's audio/mpeg.

Here's an example of how it works, using an audio file from Jim Aikin's recent vocoder tutorial:

First, there's a link to the external script:

<script src="BatmoAudioPop.js" type="text/javascript"></script>

Then there's the link itself, which looks like this:

<a href="/examples/oreilly/digitalmedia/2006/05/better-player-vocoder.mp3" 
target="_blank" onclick="javascript:BatmoAudioPop('Vocoder Example',this.href,'1'); 
return false">Vocoder Example</a>

As described in "Build a Simple MP3 Player," clicking the link passes three bits of information to the external script: the window title, the URL of the audio file, and an ID that will prevent subsequent clicks on the same link from spawning new windows. If JavaScript is disabled, the file will open normally in a new window or external player.

As before, all of the magic happens in the external script, which I've commented below. It's very similar to the code in the previous articles, with the addition of the browser and file-type detection. I also updated the embedding parameters based on some new information. Namely, most Boolean values in the object tag need to be written as 0 or 1, not false or true. I also discovered that the Windows Media plugin is three pixels taller than I'd thought, so the object height is now 45 instead of 42. Finally, I discovered that the plugin will display a handy status bar in Windows if you set the showstatusbar parameter to 1. So I increased the object height by 24 pixels to accommodate that.

// Pop-Up Embedder Script by David Battino, www.batmosphere.com
// Version 2006-05-31 
// OK to use if this notice is included
   
function BatmoAudioPop(filedesc,filepath,WindowNumber) {
   // Get Operating System 
   var isWin = navigator.userAgent.toLowerCase().indexOf("windows") !=-1
   if (isWin) { // Use MIME type = "application/x-mplayer2"
      visitorOS="Windows";
   } 
   else { // Use MIME type = "audio/mpeg"; // or audio/x-wav or audio/x-ms-wma, etc.
      visitorOS="Other";
   }

   // Get the MIME type of the audio file from its extension (for non-Windows browsers)
   var mimeType = "audio/mpeg"; // assume MP3/M3U
   var objTypeTag = "application/x-mplayer2"; // The Windows MIME type to load the WMP plug-in in Firefox, etc.
   var theExtension = filepath.substr(filepath.lastIndexOf('.')+1, 3); // truncates .aiff to aif
   if (theExtension.toLowerCase() == "wav") { mimeType = "audio/x-wav"};
   if (theExtension.toLowerCase() == "aif") { mimeType = "audio/x-aiff"};    
   if (theExtension.toLowerCase() == "wma") { mimeType = "audio/x-ms-wma"};
   if (theExtension.toLowerCase() == "mid") { mimeType = "audio/mid"};
   // Add additional MIME types as desired
   
   if (visitorOS != "Windows") { objTypeTag = mimeType; // audio/mpeg, audio/x-wav, audio/x-ms-wma, etc.};
      PlayerWin = window.open('',WindowNumber,'width=320,height=217,top=0,left=0,screenX=0,screenY=0,resizable=0,scrollbars=0,titlebar=0,toolbar=0,menubar=0,status=0,directories=0');
      PlayerWin.focus();
      PlayerWin.document.writeln("<html><head><title>" + filedesc + "</title></head>");
      PlayerWin.document.writeln("<body bgcolor='#9999ff'>"); // specify background img if desired
      PlayerWin.document.writeln("<div align='center'>");
      PlayerWin.document.writeln("<b style ='font-size:18px;font-family:Lucida,sans-serif;line-height:1.6'>" + filedesc + "</b><br />");
      PlayerWin.document.writeln("<object width='280' height='69'>");
      PlayerWin.document.writeln("<param name='src' value='" + filepath + "'>");
      PlayerWin.document.writeln("<param name='type' value='" + objTypeTag + "'>");
      PlayerWin.document.writeln("<param name='autostart' value='1'>");
      PlayerWin.document.writeln("<param name='showcontrols' value='1'>");    
      PlayerWin.document.writeln("<param name='showstatusbar' value='1'>");
      PlayerWin.document.writeln("<embed src ='" + filepath + "' type='" + objTypeTag + "' autoplay='true' width='280' height='69' controller='1' showstatusbar='1' bgcolor='#9999ff' kioskmode='true'>");
      PlayerWin.document.writeln("</embed></object></div>");
      PlayerWin.document.writeln("<p style='font-size:12px;font-family:Lucida,sans-serif;text-align:center'><a href='" + filepath +"'>Download this file</a> <span style='font-size:10px'>(right-click    or Control-click)</span></p>");
      PlayerWin.document.writeln("<form><div align='center'><input type='button' value='Close this window' onclick='javascript:window.close();'></div></form>");
      PlayerWin.document.writeln("</body></html>");
      PlayerWin.document.close(); // "Finalizes" new window
}

Pages: 1, 2, 3

Next Pagearrow