I've been threatening to do this for a while, and so here it is... how to deliver 5.1 Surround Sound on the web...
Requisite Knowledge
I'm NOT going to assume that you know jack about 5.1 Surround Sound here. I'll only require that you have the following skills:
- Good HTML knowledge
- Moderate audio knowlege (i.e. You know a few different audio formats.)
- Moderate understanding of the HTTP protocol
- Moderate ASP and VBScript knowledge
So, as you can see, I'm not really asking too much of you. I'll explain most things along the way so even beginners can follow with a bit of effort.
Preconditions for 5.1 Surround Sound on the Web
Your client MUST meet the following conditions in order to hear 5.1 Surround Sound over the internet:
- Windows XP or higher
- Windows Media Player 9 or higher
- Have a 5.1 set of speakers properly configured
- A (good) broadband connection
If they don't have that, they can't hear 5.1 Surround Sound.
Now, the most obvious thing is the set of 5.1 Surround Sound speakers. This is just common sense. You can't have 6 discrete channels without at least 6 speakers. (The 6th is the subwoofer.)
The first 2 are less obvious though. Only Windows XP and higher permits the type of playback we'll learn about here. (There are more, but they are very advanced topics.) And even when the client has Windows XP, they will need Windows Media Player 9 or higher installed.
This all has to do with the Windows Media Audio (WMA) format. (That is the ONLY format that can realistically deliver 5.1 over the web reliably at the moment.) You can encode 5.1 files with the encoder, but you can't play them back without Windows XP.
So, now you're stuck with the dilemma of how to determine if the visitor can hear it... Short answer - you can't. You need to let the user do that themselves. But, you can help.
First, check the HTTP headers for the HTTP_USER_AGENT. You'll get something like one of these (listed in alphabetical order):
- FAST-WebCrawler/3.8 (crawler at trd dot overture dot com; http://www.alltheweb.com/help/webmaster/crawler)
- GetRight/5.0.2
- GetRight/5.0.2 [Segment 0]
- GetRight/5.0.2 [Segment 1]
- Googlebot/2.1 ( http://www.googlebot.com/bot.html)
- Mozilla/2.0 (compatible; Ask Jeeves/Teoma)
- Mozilla/4.0 (compatible; LINUX MSIE; Linux Fedora Core 1)
- Mozilla/4.0 (compatible; MSIE 5.0; Linux)
- Mozilla/4.0 (compatible; MSIE 5.0; Mac_PowerPC)
- Mozilla/4.0 (compatible; MSIE 5.0; Windows 95; DigExt)
- Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; Girafabot; girafabot at girafa dot com; http://www.girafa.com)
- Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)
- Mozilla/4.0 (compatible; MSIE 5.01; Windows 95)
- Mozilla/4.0 (compatible; MSIE 5.01; Windows 98; (R1 1.3))
- Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0; DigExt; .NET CLR 1.1.4322)
- Mozilla/4.0 (compatible; MSIE 5.5; Windows 95)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows 98) Opera 7.21 [nl]
- Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; H010818; MSIECrawler)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; iOpus-I-M; MyIE2)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Win 9x 4.90)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Win 9x 4.90; AUTOSIGN W98 WNT VER03)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 4.0; Girafabot; girafabot at girafa dot com; http://www.girafa.com)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; MyIE2)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.20 [en]
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.23 [en]
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.50 [pl]
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Avant Browser [avantbrowser.com]; NetCaptor 7.2.0)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; FunWebProducts-MyWay
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; NetCaptor 7.5.0 Gold; .NET CLR 1.0.3705; .NET CLR 1.1.4322)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Rogers Hi-Speed Internet; Crazy Browser 1.0.5; .NET CLR 1.0.3705)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Universe Web; yplus 4.1.00b)
- Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2) Opera 7.11 [en]
- Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686) Opera 7.23 [en]
- Mozilla/4.0 (compatible; MSIE 6.0; X11; Linux i686) Opera 7.50 [en]
- Mozilla/4.0 compatible ZyBorg/1.0 Dead Link Checker (wn.zyborg@looksmart.net; http://www.WISEnutbot.com)
- Mozilla/4.5 [fr] (Win95; I)
- Mozilla/5.0 (compatible; Konqueror/3.0-rc4; i686 Linux; 20021211)
- Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5
- Mozilla/5.0 (Slurp/si; slurp@inktomi.com; http://www.inktomi.com/slurp.html)
- Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.6b) Gecko/20031208
- Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
- Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
- Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.6) Gecko/20040206 Firefox/0.8
- Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.4) Gecko/20030703
- Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20030225
- Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 Netscape/7.1
- Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030630
- Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031007 Firebird/0.7
- Mozilla/5.0 (X11; U; Linux i686; it-IT; rv:1.5) Gecko/20031107 Galeon/1.3.11a (Debian package 1.3.11a-1)
- Mozilla/5.0 (X11; U; Linux i686; ru-RU; rv:1.5) Gecko/20031011
- Mozilla/5.0 (X11; U; Linux i686; uk-UA; rv:1.4.1) Gecko/20031112
- NPBot (http://www.nameprotect.com/botinfo.html)
- Opera/7.11 (Windows 95; U) [fr]
- Opera/7.21 (Windows ME; U) [de]
- Opera/7.x (compatible; Konqueror/2.2.2; Linux 2.4.14-xfs; X11; i686)
- psbot/0.1 ( http://www.picsearch.com/bot.html)
- YahooSeeker/1.0 (compatible; Mozilla 4.0; MSIE 5.5; http://search.yahoo.com/yahooseeker.html)
Right about now you may be wondering...
- What the hell is that?
- I know what that is... why the hell are you listing all that crap?
- Why 61? I mean, like that's just a wierd number...
The answers:
- Those are all different user agents on different machines with different purposes.
- Because it is important to get this stuff right, and there are lots of tricky ones in there if you look carefully.
- Cause it covers a moderate range without being too repetitive. And it will give you some testing data if you need. Definately try some of them out with your scripts. That's why they are there. A couple of them are devious :-)
Inside of those user agent strings, we're only concerned with determining if:
- It's a Windows XP box.
- It's a search engine spider or robot
If it's a Windows XP box, then we need to serve up the right 5.1 Super Sexy Swinging Surround Sound :-)
If it's a search engine poking around, then you need to decide whether to show them the content or not. Most likely you do want to serve it up to them. This is really important, because given the amount of work that will go into an endeavor like this, you might just want people to know about it ;-)
I won't get into search engine cloaking, ethics, or anthing like that here, but is something that you should be aware of.
Client side detection
You can also do client side detection for plugins and all that jazz, but the above should be sufficient to determine things relatively accurately.
Determining if a client machine is 'eligible'
(If you're using ASP, then you can use JScript or VBScript along with ASP, but I won't distinguish between them and we'll only use VBScript examples here since that is most common.)
The first thing you need is the HTTP header for the user agent:
request.servervariables("http_user_agent")
That will return something like one of those lines in the monster list above.
Store it in a variable something like so:
myVisitorType = lcase(replace(request.servervariables("http_user_agent"), " ", ""))
There we make everything lower case and get rid of the pesky spaces because it's just simpler and easier to deal with that way.
Now, let's check the string for a few values. I'll just set the values we want to check in a few variables (and continue to leave out all the variable declaration statements):
winNT5 = "windowsnt5.0"
winNT51 = "windowsnt5.1"
winNT52 = "windowsnt5.2"
ie = "msie"
linux = "linux"
avantBrowser = "avantbrowser"
opera = "opera"
netscape = "netscape"
apple = "apple"
mac = "mac"
konqueror = "konqueror"
galleon = "galleon"
We need a few conditions to be true and a few and to verify that some are false. So let's manage them with a bit of simple code. (You could do this all faster, I'm just laying things out 'longhand' for ease.)
winXP51=false ' Our 5.1 Surround boolean value
if inStr(myVisitorType, winNT51) OR inStr(myVisitorType, winNT52) OR inStr(myVisitorType, msie) then winXP51=true
if inStr(myVisitorType, linux) OR inStr(myVisitorType, apple) OR inStr(myVisitorType, mac) OR inStr(myVisitorType, opera) OR inStr(myVisitorType, mac) OR inStr(myVisitorType, konqueror) OR inStr(myVisitorType, galleon) OR inStr(myVisitorType, netscape) then winXP51=false
So there we set a true condition for when our user agent string confirms that it is Windows, we have Internet Explorer, and that it is either XP or Server 2003. Then we blacklist a whole bunch of user agents. That's because they either don't work at all, or have bugs.
Why Blacklist User Agents?
Because they lie!
Some user agents can 'tell us' that they are something other than what they really are. This is fine most of the time, but we're not going to take too many chances here.
In most cases, Konqueror and Galleon can get away with impersonating IE, but not in this case. We need to exclude them. (BTW: Konqueror and Galleon kick ass!) Similar for Safari.
No Linux box or Mac can embed Windows Media Player for what we want, so we nix them all. You can add more if you need. Atari would be the next OS I'd target for audio related stuff... People still use it - believe it or not!
You may want to think about AOL and blocking it as well. Here are a few AOL user agents:
- Mozilla/4.0 (compatible; MSIE 5.5; AOL 8.0; Windows 98; Win 9x 4.90)
- Mozilla/4.0 (compatible; MSIE 6.0; AOL 7.0; Windows NT 5.1; .NET CLR 1.0.3705)
- Mozilla/4.0 (compatible; MSIE 6.0; AOL 8.0; Windows NT 5.1)
- Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1; .NET CLR 1.1.4322)
Other browsers and OSes that slip through aren't really that important because they only represent a very small number of users. We could test for more, but the above should be enough at least for demonstration purposes. We could be really anal, but the users will 99% complain about their browser or OS instead of us ;-) So we can be a bit lazy there. hehe
So, we've got the user agents sorted out and we've got our booleand value stored in winXP51. (Don't forget the part about the spiders though... I'll cover that elsewhere.)
Audio on Web Pages
At this point, we've done most of the hard work and you can either check out Web Media Basics, or continue for a bit more detailed information.
I wouldn't suggest just serving up the content right off the bat. It would probably be better to offer several options to your visitor. This is a good selection and very easy to do:
- QuickTime player (Stereo MP3)
- RealOne Player (Stereo MP3 or RealAudio format)
- Windows Media Player 6.4 (Stereo MP3 or Stereo WMA)
- Windows Media Player 9 (5.1 WMA)
You should ideally come up with a nice simple display for users to choose. Something like this would work fine:
| Nifty graphic or title, description, whatever tickles your fancy |
| Option 1 |
Option 2 |
| Option 3 |
Option 4 |
Each option should hyperlink to a page with the player in it. You can use the same page with a bit of scripting. Let's assume the link is something like play-for-me-baby.asp?player=1, or 2, etc.
On the player page, you'll have your web player HTML and ASP script which will look something like this:
< %
player = request.querystring("player")
select case player
case 1
cls="02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
media="right-now.mp3"
auto="autoplay"
mime="image/x-macpaint"
case 2
cls="CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"
media="right-now.ra"
auto="autostart"
mime="audio/x-pn-realaudio"
case 3
cls="22D6F312-B0F6-11D0-94AB-0080C74C7E95"
media="right-now.mp3"
auto="autostart"
mime="audio/x-mpeg-3"
case 4
cls="6BF52A52-394A-11d3-B153-00C04F79FAA6"
media="right-now.wma"
auto="autostart"
mime="audio/x-ms-wma"
case else
cls="22D6F312-B0F6-11D0-94AB-0080C74C7E95"
media="right-now.mp3"
auto="autostart"
mime="audio/x-mpeg-3"
end select
% >
< OBJECT ID="myPlayer" NAME="myPlayer" CLASSID="clsid:< %=cls% >" WIDTH="200" HEIGHT="80">
< PARAM NAME="SRC" VALUE="< %=media% >">
< PARAM NAME="TYPE" VALUE="< %=mime% >">
< PARAM NAME="< %=auto% >" VALUE="True">
< EMBED
ID = "myPlayer"
NAME = "myPlayer"
WIDTH = "200"
HEIGHT = "80"
SRC = "< %=media% >"
TYPE = "< %=mime% >"
< %=auto% >="True"
>
< noembed>You do not have an appropriate player installed to view this or you have selected the wrong one - click back and try again.
< /noembed>
< /OBJECT>
MIME Types
So, you've got 1 of 4 players embedded in the page, with all the correct mime types (you can change them if you like), however you may be wondering about the QuickTime image/x-macpaint mime type - that's just a little trick to FORCE the web browser to use QuickTime and not another player, and it works according to Apple ;-) However, your web server must have its mime types configured to with *.pntg file extensions.
You can also use just plain jane x-mpeg-3 if you like. The important thing for mime types is that the browser understands what kind of plugin to use.
Windows Media file extension mime types are available at MSDN here:
UPDATED 2004-09-28: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmplay10/mmp_sdk/filenameextensions.asp
OLD URL: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmplay/mmp_sdk/filenameextensions.asp
(Microsoft is basically incapable of maintaining URLs, hence, the update.)
Done embedding 5.1 Surround Sound in a web page
However you actually do your implementation, it will still follow the basic priciples laid out above:
- Client detection
- Optional content
- Proper embedding
There isn't much more to it. You can embellish with more client side detection or whatever you like, but you've at least got the basic idea of how to embed 5.1 Surround Sound into a web page.
Cheers,
Renegade