Detecting Streaming Media Players and Connection Speed Tutorial -
Part One
By Larry Bouthillier, Streaming Media Consultant, eMedia Communications
Strategies
(Back to Detecting Streaming Media Players
and Connection Speed Tutorial home page)
Wouldn't we all love a world in which all streaming video content could
be played with any streaming video player? Sure ... just like any
browser can render any HTML page, right? Unfortunately, the reality we
deal with is one in which the three major streaming media systems are
largely incompatible with each other. What's more, your users will be
using a variety of operating systems, browsers, media players, and
types of internet connections. One solution to this problem is to
choose a single streaming format to support. This can be a good option
if you can control the configuration of your viewers' computers, as in
many corporate or educational settings. If you can do this, it
certainly is a very cost-effective approach.
But if you're like many of us, you'll need to support multiple
streaming media formats to make your content easily available to as
many users as possible. Well, roll up your sleeves, because we're going
to get our hands dirty with some code that will let you determine which
players your users have installed, and what bandwidth they have
available on their Internet connection to stream your content. Then you
can let users choose which of their players they'd like to use to view
your content and stream to them a version appropriate for their
connection. In the process, we'll start to lay out the framework
for a simple streaming video content management and delivery management
system which can provide load balancing, fault tolerance, video search
and other advanced streaming media management features.
For now, we'll focus on player detection and user choice. There are
three parts to this that we'll cover in a short, weekly series of
articles. The solution we'll implement here is illustrated in Figure 1. 
First, we'll use client-side code in the browser to determine which
players are installed and what the connection speed is. This example
requires no server-side software - it all happens in the browser.
We'll set the results in a browser cookie that our server-side
code can read. (detectPlugin.jsp)
In part two of this series, we'll use that information to offer the
users a choice about which player they would prefer to use. This will
also be set in a cookie. (selectPlayer.jsp)
Finally, in part three, we'll honor user's choice by generating a
metafile (.ram for RealSystem, .asx for WindowsMedia, .smi for
QuickTime). This will launch the correct media player and direct it to
the server where the content lives. (playVideo.jsp, using
PlayerDataObject.java)
All the server-side code for these articles is written in Java/JSP.
I've chosen JSP because it's simple, powerful, and available on any
platform and for any Web server. Of course, the concepts here could
easily be implemented using Perl CGI, ColdFusion, or other server-side
Web application environments. The example
source code download page
includes instructions on how to set up the free Apache Tomcat JSP engine
to run the examples.
So, enough of that. Let's get down to business! There are two major
approaches required for determining which media players (or other
plugins) a user has installed: one for browsers that use plugins and
another for browsers that use ActiveX controls.
Browsers that use plugins: Opera,
Netscape Navigator/Communicator, IE on Macintosh, and any browser not
on Windows
Browsers that use ActiveX: IE on
Windows
Let's walk through the client-side code that lets us deal with each of
these possibilities. First we'll look at detecting plugins. Listing 1 shows a fragment of JavaScript code that
you can place in your HTML page. Browsers store information about the
installed plugins in an array of plugin objects that's accessible from
JavaScript. First, on Line 15, we double check to see that we are not
on IE on Windows. Then, starting on line 18, we begin to check the name
of each of the plugins in our plugins array. You'll notice that we have
to know exactly what the plugins are named in order to detect them. You
can see these by typing "about:plugins" in the Location field of your
browser. If we find a match for any plugin, we add a short name for it
to our 'playerString' variable (lines 22, 25 and 28).
Once you've checked all the plugins, you'll want to store the results
somewhere useful. This is what cookies are made for — storing small
bits of data on a user's computer for future use. A cookie is saved
with the host site's domain name, so only the site that originated the
cookie can read it. This means no other sites can take advantage of the
information you're storing here — it's just between you and your user.
So, line 32 calls the setCookie() function, storing the playerString in
a cookie named "MediaPlayers." If you don't provide an expiration date
for your cookie, it will go away when the user closes the browser.
Here, we've arbitrarily chosen to set our cookie to expire in 365 days.
If you have all three major media players installed, your playerString
will look something like this: "REAL,QT,QT,QT,WMP." Try it! Use the links under Client-side only Code Examples.
We don't care about the order of the names here. Yours may vary,
depending on the order in which your browser loaded its plugins.
You may also notice that if you use Internet Explorer 5.5 SP2 or 6.x on
Windows, you may not see the QuickTime control listed, even though you
know you have QuickTime installed. Microsoft recently
discontinued support for browser plugins in these products, in favor of
their own proprietary ActiveX control architecture (must be “good for
consumers”, huh?). If you use one of these browsers, or if you've
recently updated IE5.5, Apple's QuickTime plugin no longer
functions. To circumvent this change, Apple has released an
ActiveX version of the QuickTime player.
Listing 2 lets you do the same thing for users of
IE on Windows. Here on lines 21 through 23 we try to create ActiveX
instances of each player using VBScript. We simply check to see if each
attempt was successful. The same JavaScript functions we used for the
plugin example set the cookie value.
Bandwidth Detection
It's possible to detect the bandwidth of an internet connection using
Javascript code in the browser. Let's examine how this detection
is done. The short version is this: get the current time when the
page begins to load. Then, load a bunch of data to the page.
Finally, get the time again. You can see this in the code
listings at Listing 1 on lines 52-66.
Notice that the data lines (58-60) are not text, but are binary bits
put into comment lines. Using binary data here eliminates two
complications. First, the browser does not try to render and
format the text, which keeps the speed of the your user's
computer or browser from becoming as much of a factor affecting the
load time for the data. Secondly, if their modem uses data
compression, it will not be applied to streaming video content which is
already highly compressed. The binary data I pasted here is from
a highly compressed file (I happened to use a JPG), which will have
similar network compression characteristics to streaming video.
Next, we have to do some simple math to get a value in kbps (kilobits
per second). Our calcThroughput() function, on lines 41 through
50, handles this. Since we provided the block of data, we know
the number of kilobits we transferred. If we subtract the
beginning time from the ending time, we also know the number of seconds
it took to load. We simply divide kilobits by seconds to get
kbps. On line 47 we figure in a correction for network overhead
(packet headers and the like). The result is a ballpark estimate
of the network bandwidth at the moment this page loaded. We'll
set this information in a cookie, just as we did the player information
(line 48).
It's important to note my use of the word "ballpark" here. There
are a few points to keep in mind about this. Network bandwidth
can be very variable. If the user's connection bandwidth is
fluctuating, you'll only get the bandwidth at the moment that this page
loads. If the user is experiencing an unusually low- or
high-bandwidth moment due to network traffic (on your end or theirs),
you'll have an inaccurate notion of their real capability.
The other point to remember is that the accuracy of the results is
biased towards slower network connections. If you're connecting
on a 28.8 or 56k modem, the 31kBytes of data we're loading will take a
few seconds and we'll get good time data from the code. But if
the connection is very fast, the time it takes to load the data may be
just a few milliseconds. With a load time of just a few
milliseconds, we're working with a too small a time sample on which to
base our calculations. It's sort of like measuring inches with an
odometer (or is it like measuring miles with a micrometer?
Hmmm...). Anyway. in order to increase the accuracy at high
bandwidths, we'd have to make the data block much larger.
But....it turns out we really don't have to. Think of it – you
will probably want to treat users on a 28.8 connection differently from
those on a 56k, 128k ISDN, or 600k cable modem connection. But
for video streaming, it's less likely to be critical to know whether
your users are on, say, a 1Mbps, 10Mbps or 100Mbps connection.
Now you've got some working code that can detect the presence of the
three major media players, and the speed of your users' network
connection. Unfortunately, you have different player detection
code for different browser and platform combinations. Our solution will
be to detect the user's browser and platform at the server — before
sending this code. Then we'll respond with the correct code for the
user's environment. Stay tuned — in next week's installment we'll move
to the server-side and walk through the code that handles this. We'll
also examine the code that will read the cookies we've set here. Then,
we'll let our users make their own choice about which player they want
to use. See you next week!