In the previous section we reviewed the process of creating a video object, setting up a NetConnection, and attaching an instance of the video object to the NetStream to play a streaming FLV file. We also added the functionality to toggle between pause/play, and mapped it to the right navigation key on the device using a custom component.
There is one more thing to consider if we want this to work on mobile phones: bandwidth! I'm sure you've all experienced dropped calls, where you are talking to someone on your cell phone and simply turning a corner causes you to lose the connection. Dropped call issues are often due to the proximity to cell towers. Depending on your location in relation to a cell tower, your connection and available bandwidth will change. To achieve the goal of successfully delivering streaming video content to cell phone users, you must consider a way to stream different content based on each user's available bandwidth. Unfortunately there's nothing we can do to avoid a lost cell phone connection—although that would be a neat trick.
At this point I was planning to show how we could use the native bandwidth detection of Flash Media Server 3 to automatically select the best streaming content for the current bandwidth of the Flash Lite-enabled device. However, there's a problem that will not allow this functionality to be used with Flash Lite 3.x.
I am still investigating the cause of this, but all is not lost. Although we cannot use the native bandwidth detection, we can use an approach developed back in the days of Flash Communication Server (the predecessor to FMS). This strategy is described by Stefan Richter in the Developer Connection article Delivering Flash video.
I really recommend that you check out the article linked above. It covers the approach for detecting bandwidth that will work with Flash Lite 3 content. In the article you'll also find tutorial files and the server-side script that performs the bandwidth detection. The approach involves a call from the client to a server-side script. The server-side script calls a method on the client to determine the device's bandwidth, and then sends the value back to the device. After this communication between the client and the server, the device can use this information to choose the most appropriate video content.
Let's see how this works in action. You'll need to download the server-side script (bwcheck.asc) and place it in a folder called "bwcheck" under the applications directory of the Flash Media Server 3 installation directory (see Figure 4).

Figure 4. Put the bwcheck.asc file in a folder named bwcheck inside the FMS directory
For all those not familiar with the Flash Media Server, the ".asc" extension denotes this file as a server-side script.
Now let's take a look at an example file (bwcheckExample.fla) that uses bandwidth detection to determine the appropriate video to play on the device. If you haven't already, download the sample files from the first page of this article. After you download the example, you'll need to substitute your FMS server's name or IP address for the reference to yourserver.com in the ActionScript of the bwcheckExample file. The video files for this example are provided in the sample files link on the first page of this article. Unzip the video files and place them in the _definst_ directory inside the streams folder of the Flash Media Server as shown in the following screenshot (see Figure 5).

Figure 5. The _definst_ directory contains the video files on the FMS server
There is a brief description of the bandwidth detection approach in the help files for Flash Media Server. Even though the description mentions "native bandwidth detection" the ActionScript will work for script-based detection as well—with one exception. You'll need to set the following line to false in the "Application.xml" file on your Flash Media Server:
<BandwidthDetection enabled="true">
In the next example we'll use two connections to the server. The first is a connection to get the available bandwidth. We'll use the second to connect and play the appropriate stream.
It's important to note that I had to create the different video files (.flv files) manually. There are server solutions to real-time transcoding but they are either too expensive or outside the scope of this article to explain.
It is also worth noting that in this example we only check the bandwidth once. In a real world situation, it would be a good idea to check the bandwidth again in the event of an error or to possibly avoid poor video playback performance.
Since I already covered the basics in the previous section of this article, I'll focus on the process for bandwidth detection in this example. We'll begin as we did last time, by creating a new NetConnection(). When the connection is made and accepted by the server-side script bwcheck.asc, the process of detecting the bandwidth begins. The server calls the method onBWCheck and sends packets of data in order to determine the client's bandwidth. When the process is complete, the server sends the results to onBWDone.
This is the part where we'll create the connection that will be used to check the bandwidth of the client:
nc = new NetConnection();
The following code in the bwcheck.asc file on the FMS server accepts the connection and kicks off the detection process by calling the function calculateClientBw inside the same file:
application.onConnect = function(p_client, p_autoSenseBW){
this.acceptConnection(p_client);
if (p_autoSenseBW)
this.calculateClientBw(p_client);
The client includes the method below, which is called by the server. This part assists in determining the bandwidth of the client:
nc.onBWCheck = function() {
return ++counter;
};
When the process is complete, the server calls the client with the following line of code, and passes in the values for bandwidth, deltaDown, deltaTime and latency:
p_client.call("onBWDone");
On the client, the following method retrieves the bandwidth, deltaDown, deltaTime and latency values and then calls the function on the client that will determine the appropriate video file to use.
nc.onBWDone = function(p_bw, deltaDown, deltaTime, latency) {
initVideo(p_bw);
};
The next function (playVideo) uses the bandwidth information passed to it to set a variable called useVideo to the appropriate video file. For simplicity, I named the video files based on the bandwidth they will use (for example, 200kbps). Additionally, it's also changing the amount of video that will be buffered before playing each video file.
function playVideo(param_detected_bw:Number) {
var detected_bw:Number = param_detected_bw;
if (detected_bw>200) {
bdwdth_txt.text = "connected @ "+detected_bw +"kbps playing 256kbps_Stream";
useVideo = "200kbps";
bufferlength = 4;
} else if (detected_bw<200 && detected_bw>=160) {
bdwdth_txt.text = "connected @ "+detected_bw +"kbps playing 150kbps_Stream";
useVideo = "150kbps";
bufferlength = 7;
} else if (detected_bw<160 && detected_bw>=120) {
bdwdth_txt.text = "connected @ "+detected_bw +"kbps playing 100kbps_Stream";
useVideo = "100kbps";
bufferlength = 9;
} else if (detected_bw<120 && detected_bw>=85) {
bdwdth_txt.text = "connected @ "+detected_bw +"kbps playing 75kbps_Stream";
useVideo = "75kbps";
bufferlength = 10;
} else if (detected_bw<85 && detected_bw>=65) {
bdwdth_txt.text = "connected @ "+detected_bw +"kbps playing 50kbps_Stream";
useVideo = "50kbps";
bufferlength = 12;
} else {
bdwdth_txt.text = "bandwidth too low. Sorry"
};
The final function above determines the correct video to play, based on the available bandwidth. It also displays the detected bandwidth, or an error message if the bandwidth is insufficient to play any of the streaming video files. Hopefully the strategies I've covered in this article will help you get started working with Flash video content streamed from FMS for Flash Lite 3.x.
The following articles will help you round out your understanding of Flash video support in Flash Lite 3:
And be sure to check out the Mobile and Devices Developer Center where you'll find more articles, tutorials and sample projects, as well as the newest information about Flash Lite development.