Recipe 18.6. Detecting BandwidthProblemYou want to determine the bandwidth capabilities of a user's computer. SolutionDownload a file using MovieClipLoader. Determine the amount of time it takes to download the file. DiscussionNot all users have the same bandwidth capabilities. Users in many parts of the world still have dial-up access with 56k modems. And even for those users with broadband connections, actual bandwidth capabilities can vary greatly. Users on DSL networks might have speeds of 384 Kbps, 768 Kbps, or 1.5 Mbps, for example. Network traffic can also play a role. The more users are on a network, the less bandwidth is likely to be available to each user. Video can require significant bandwidth capabilities when encoded at higher bit rates. Depending on your audience you might want to consider encoding videos at several bit rates. For example, you might encode a video at 800 Kbps, 400 Kbps, 200 Kbps, and 56 Kbps. In that case, each video will have four FLV filesone for each bitrate. You can name (exp 3pod.com) the files using a naming scheme such as videoname (exp 3pod.com)_bitrate. For example, you might have four FLV files named welcome_800.flv, welcome_400. flv, welcome_200.flv, and welcome_56.flv. In order to present the user with the optimal video configuration, you'll want to know the user's bandwidth settings. If the user is capable of downloading data quickly, you'll want to allow the user to view video encoded at high bit rates (and therefore high quality). A user with low bandwidth capabilities may or may not want to view a video encoded at a high bit rate if it takes a long time for her to download the file. There are several ways you can optimize the video configuration for a user. It is generally a good idea to allow users to make decisions about things involving quality and download times. A very direct way to ensure that users have the video configuration they want is to allow them to select the configuration manually. For example, you can allow the user to select a bit rate from a combo box or list. In that case, you don't need to detect the user's bandwidth because the user is selecting the bit rate manually. Allowing the user to select a bit rate directly has the advantage of ensuring that the user is in control. However, it's possible that such a direct approach may be inappropriate for your audience. If your audience is not technically savvy, they may not know which option to select. Furthermore, automatic bandwidth detection gives the user the sense that the application is sophisticated and smart. Automatic bandwidth detection requires that you download a file using MovieClipLoader and determine the amount of time required. You can then determine the approximate bandwidth capabilities by dividing the file size by the amount of time. You'll want to download a file that is not likely able to be decompressed by Flash Player (and therefore return incorrect bandwidth settings). Image files (JPEG, PNG, and so on) often work well. The smaller the file, the faster the download and the shorter the wait for your users. However, the less the user has to download, the less accurate the bandwidth detection as well. If the user has to download only 25 KB, then minor network traffic or CPU stutters could throw off the detection significantly. It's generally advisable to use a file that is at least 100 KB. Consider than a user with 768 Kbps DSL will be able to download a 100KB file in approximately one second. A user with a 56k modem can download that file in approximately 16 seconds. Sixteen seconds is about as long as you'd want to make a user wait for bandwidth detection. If you detect a user at 56k modem speeds you can download the file just once. If you detect the user at speeds higher than 56k modem speeds, consider downloading the file a few additional times and average the detected bit rates in order to have a more accurate result. For example, if the user has 384 Kbps DSL, it will take approximately eight seconds to download a 100KB file four times. To detect the bandwidth, you'll want to use a few variables. You'll want to use variables to store the download start time, the total bytes downloaded, the total download time, and the number of times downloaded. You can initialize the variables for total bytes, download time, and times downloaded each to 0: var nStartTime:Number; var nTotalBytes:Number = 0; var nTotalDownloadTime:Number = 0; var nTimesDownloaded:Number = 0; You'll also want to declare a variable to store the detected bandwidth: var nDetectedBandwidth:Number; You'll need to define a movie clip into which to download the file. You can use createEmptyMovieClip( ) to accomplish that. If you're downloading an image file, it's advisable that you add a movie clip nested within a movie clip. When you download an image file, it overwrites movie clip functionality. If you add a movie clip nested within a movie clip, you can overwrite the nested movie clip each time you want to download the file again. In that case, add the nested movie clip with a depth of 1. You'll create the nested movie clip in a function called testBandwidth( ) in just a few minutes. this.createEmptyMovieClip("mBandwidth", this.getNextHighestDepth()); Use MovieClipLoader to make the download request. Construct a MovieClipLoader as follows: var mlBandwidth:MovieClipLoader = new MovieClipLoader(); Register a listener object with the MovieClipLoader instance to detect events such as the download starting and completing. Construct a listener object using the Object constructor: var oBandwidthListener:Object = new Object(); Then, define onLoadStart( ) and onLoadComplete( ) methods for the listener object. The onLoadStart( ) method ought to assign the current timer value to the start time variable. The getTimer( ) global function returns a timer value in milliseconds since the Flash Player started running: oBandiwidthListener.onLoadStart = function(mClip:MovieClip):Void { nStartTime = getTimer(); }; The onLoadComplete( ) method should determine the difference between the current timer value and the start time and add that value to the total download time. It also should add the bytes downloaded to the total bytes downloaded. You can retrieve the bytes downloaded from the getBytesTotal( ) method of the movie clip reference passed to the method. Increment the times downloaded by 1. Then determine the detected bandwidth by multiplying the total bytes by 8 to convert bytes to bits (there are 8 bits in a byte) and dividing by the total time. If the detected bandwidth is near 56k modem speeds, you can exit the bandwidth detection. If the number of times downloaded has reached the maximum number of download times, you can exit the bandwidth detection. If the detected bandwidth is higher than 56k modem speeds and you still haven't reached the maximum number of downloads, download the file again. oBandwidthListener.onLoadComplete = function(mClip:MovieClip):Void { nTotalDownloadTime += getTimer() nStartTime; nTotalBytes += mClip.getBytesTotal(); nTimesDownloaded++; var nBandwidth:Number = nTotalDownloadTime * 8 / nTotalBytes; if(nBandwidth < 150 || nTimesDownloaded >= 4) { if(nBandwidth < 200) { nDetectedBandwidth = 56; } else if(nBandwidth < 400) { nDetectedBandwidth = 200; } else if(nBandwidth < 800) { nDetectedBandwidth = 400; } else { nDetectedBandwidth = 800; } // Call a function that starts the video. } else { testBandwidth(); } }; Next, define the testBandwidth( ) function. The function defines the nested movie clip and calls the loadClip( ) method of the MovieClipLoader method. Because you are downloading the file specifically to determine bandwidth, you'll want to ensure that the file is never retrieved from the browser cache, so use a unique URL each time you make the request. You can accomplish that by appending a query string with a unique number to the URL. You can use the getTime( ) method of a new Date object to generate the unique number: function testBandwidth():Void { mBandwidth.createEmptyMovieClip("mImage", 1); mlBandwidth.loadClip("http://www.server.com/file.jpg?id=" + (new Date()).getTime(), mBandwidth.mImage); } To start the bandwidth detection, call testBandwidth( ). As noted previously, it's generally advisable to allow the user to have control. Even if you use automatic bandwidth detection, consider allowing the user to override the detected settings. In the scenario presented in this recipe, you can accomplish that by allowing the user to manually override the value of nDetectedBandwidth. |
Tripod >> 3pod Tips & Learning and manuals for educations