Detecting Streaming Media Players and Connection Speed Tutorial
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: we get the current time when the page begins to load. Then, we load a bunch of data to the page. Finally, we get the time again. You can see this in the code listings at Listing 1 on lines 84-100.
Notice that the data lines (90-92) are not text, but are binary bits put into comment lines. (Be careful editing this file -- if your text or HTML editor "wraps" text, these lines will break.) 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 72 through 82, 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 78 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 79).
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 ruler? 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.
Finally, there's one more factor that can confound the bandwidth detection script - browser caching. If the browser caches the bandwidth detection page, then on subsequent page loads the bandwidth will appear to be nearly infinite. There are two commonly used solutions for telling the browser not to cache a certain page. One is to use meta http-equiv tags directly in the HTML of the page to set the Pragma and Expires directives. Unfortunately, this is pretty much ignored by most browsers and does not work. The second way, which actually works, is to set the http headers using code on the server-side. For example, if you use JSP to deliver your bandwidth detection page, the http headers would be set at the very top of the page like this:
<%response.setHeader("Cache-Control", "no-cache");response.setHeader("Pragma", "no-cache");response.setDateHeader("max-age", 0);response.setDateHeader("Expires", -1);%>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. What you do with that information is up to you. You could simply display a message encouraging them to install the right video player software. You could read their MediaPlayers and MediaThroughput cookies on the server and automatically give them video in a format they can use. Or, you could build an HTML form that lets your users make their own choice about which player they want to use and sends the data back to your server. These last two ideas would, of course, require some server-side code to accept the client's selections and manage the delivery of multiple video formats. If there's interest, we'll suggest some ways to address that in a future article.