Prerequisite knowledge
Required Products
Sample Files
A basic understanding of how to use video in Flash, the FLVPlayback component, and Flash Media Server 3.5 is required.
Flash Media Server (Download trial)
Additional required product
FLVPlayback 2.5 component, Dynamic Stream and DynamicStreamItem classes    
User level    

This article shows you how Adobe Flash CS4 Professional, the new FLVPlayback 2.5 component for Flash, and Flash Media Server 3.5 now work together to accommodate the inevitable "bumps" in data streams. It's the seventh in a loose series of beginner's tutorials.

Here are all the articles in the series:

Though we have come to regard the term "information superhighway" as a tired description of the Internet, this would be a great place to start.

Let me explain. When I drive to the college where I teach, the trip usually takes 40 minutes. I start my trip on streets where the speed limit is 50 km/h. Next I travel up a road where the speed limit is 80 km/h, and from that road I spend the next 30 minutes on a highway where my average speed is around 120 km/h. This is on a good day, and it is important that you pay attention to these speed limits. They are going to play a huge role in the next section.

As I'm a Canadian, for me winter is an especially brutal time for traffic. If there is a lot of snow on the highway, the best highway speed I can hope to drive is 35 km/h as traffic slows down to accommodate the conditions. If there is an accident or a car has spun out into a ditch, the odds are about 100% that I will travel no faster than 20 km/h or slower as traffic bunches up. Once we get past the accident, I can inevitably accelerate back up to to the 100 km/h speed limit.

Now if we translate this snowy day situation into the universe of streaming bits, you can think of the cars as a data stream. On a clear day, data will merrily flow along the "information superhighway" at 120 Kbps, but add an accident or snow to the mix and your data stream will slow down. In the case of streaming video, this can be infuriating to the user—fits and starts in the stream—and, for you, a never-ending source of headaches over which you have little or no control—that is, until now.

Flash Media Server 3.5 enables you, essentially, to dynamically adjust the stream to accommodate driving conditions. Then it gets better: It is dead simple to accomplish this using the FLVPlayback component and, if you really want to geek out, you can team up the component with an external SMIL file to control multiple bit rates.

Dynamic stream switching to accommodate multiple bit rates

In Part 2 and Part 3 of this series, I showed you how you can use the FLVPlayback component to play a single video. In this article, I show you how to use that same component to dynamically change that video as traffic conditions in the stream change.

Why do you need this? The answer is self-evident. Today's Internet, especially when it comes to bandwidth and computing technologies, is vastly more powerful than when video first became viable in Flash 7. The introduction of HD video to Adobe Flash Player in Flash CS3 Professional was a game-altering addition. The fact that YouTube, among others, is adopting this format—and that users have come to regard HD video as a "must have" rather than a "nice to have"—tells you that the user is expecting a consistent video experience whether or not that data is being delivered wirelessly in a coffee shop, on a street corner, or through an Ethernet cable.

The problem, as I am fond of telling people, is that trying to push HD video encoded at 1500 Kbps through a wireless connection is like trying to push a watermelon through a worm. The stops and starts due to buffering issues are no longer regarded as a "necessary evil" of video. Being able to detect the available bandwidth and switch to the appropriate version of a video is a major step forward in providing the user with a consistent video experience regardless of where he or she is physically located and connected to the Internet.

How can you accomplish this? Essentially, all you have to do is write some ActionScript that functions as your "traffic spotter" and, when things get congested, switches the stream to a copy of the video encoded with a data rate that accommodates the "slowdown up ahead"—and, when you get through the bottleneck, switches to a video that has the appropriate data rate to accommodate the speed increase.

As you may have inferred from this, your workflow has somewhat increased. Instead of a single copy of a video encoded at a single data rate, you need to encode multiple copies of the same video and use different data rates, for each copy, as shown in Figure 1.

Export setting

What are the rates? That is best left to your judgment of the conditions your users will encounter. Still, if you poke around the articles by myself, David Hassoun, and others here at the Flash Media Server Developer Center, you will see projects such as this one that have as few as three copies of the video, as well as others that have five copies at data rates of 160 Kbps, 500 Kbps, 700 Kbps, 1000 Kbps, and 1500 Kbps. It all depends on your best guess as to the bandwidth and/or viewing situation that your users will encounter.

Using the FLVPlayback 2.5 component

In this exercise, you will use the FLVPlayback 2.5 component and write the ActionScript 3.0 code that will enable you to play multiple streams to accommodate changing bandwidth situations.

To start, download the exercise files at the beginning of the article. When you unzip the file, move the three videos in the MBR folder to the vod folder located at C:\Program Files\Adobe\Flash Media Server 3.5\applications\vod\media. Having done that, return to the desktop and create a folder named MBR that will be used for this exercise:

  1. Launch Flash CS4 Professional and create a new ActionScript 3.0 document.
  2. Select Modify > Document. When the Document Properties dialog box opens (see Figure 2), change width to 640 pixels and the height to 520 pixels. Click OK to accept the change and close the dialog box. You need this odd height because the videos are 640 × 480, but you need the extra 40 pixels to accommodate the height of the skin.
Document properties
  1. When the dialog box closes, select Window > Components and drag a copy of the FLVPlayback 2.5 component, found in the Video group, to the Stage. Close the Components panel when the component appears on the Stage.
  2. Click the component once to select it, and then open the Properties panel. Use the following settings (also shown in Figure 3):
    • Instance name: myVideo
    • X: 0
    • Y: 0
    • W: 640
    • H: 480
  1. Add a new Layer, name it actions, and save the file to the MBR folder on your desktop.

Writing the ActionScript to control multiple bit rates

Now that the assets are in place, you can turn your attention to "wiring up" this project with ActionScript 3.0:

  1. Select the first frame in the actions layer and open the Actions panel by pressing either F9 (Windows) or Option+F9 (Mac), or by selecting Window > Actions.
  2. Click once in the Script pane and enter the following code:
import*; var myDynamicStream:DynamicStreamItem = new DynamicStreamItem();

The example starts by importing all of the methods and properties of the video class. You need to do this when using ActionScript to manage the component. The next two lines make use of the two classes—DynamicStream and DynamicStreamItem—you downloaded and installed prior to starting this exercise.

The two classes hand you a relatively efficient way of doing what used to be regarded as the "heavy lifting" involved in writing an ActionScript-based custom solution to manage multiple-bit-rate scenarios.

The DynamicStream class extends the NetStream class and provides you with a solution to managing NetStreams. As you may recall, you only get one NetStream per video. For all intents and purposes, this new class, which is to be used as a substitute for the NetStream class, allows you to keep the stream flowing while videos are switched on the fly. The DynamicStream instance also contains a startPlay() method to which you can pass an Array of streams encoded at differing bit rates in the form of a DynamicStreamItem.

The second line of the code tells Flash to hand off the lifting duties to the DynamicStream class; the third line creates a new DynamicStreamItem object named myDynamicStream.

  1. Press Return/Enter a couple of times and enter:
myDynamicStream.uri = "rtmp://localhost/vod/";

The major difference here is that, instead of using NetConnection to connect to the server, you use the uri (Uniform Resource Identifier) property of the myDynamicStream object to make the connection.

Now that the stream is in place and Flash knows where the server is located, you simply need to add the video streams to be used.

  1. Press Return/Enter twice and add the following code:
myDynamicStream.addStream ("mp4:ChefSchool_500.f4v",500); myDynamicStream.addStream ("mp4:ChefSchool_700.f4v",700); myDynamicStream.addStream ("mp4:ChefSchool_1500.f4v",1500);

As you can see, you simply use the addStream method on the myDynamicStream object and pass it the name of the video and the bit rate.

Note: I would like to thank William Hanna, dean of the School of Media Studies and Information Technology at the Humber Institute of Advanced Learning and Technology in Toronto, for permission to use the videos included in this article.

  1. Now that Flash knows which videos to add and what bit rates to look for, all you need to do is to hook all of this into the component. Press Return/Enter twice and enter the following line of code:
myVideo.play2 (myDynamicStream);

The new method is play2(), which is an enhancement of the method traditionally used to stream video. Use this with the FLVPlayback 2.5 component to pass a DynamicStreamItem containing a list of stream names and varying bit rates as well a uri property that tells the component where the server is located.

  1. If your completed code is:
import*; var myDynamicStream:DynamicStreamItem = new DynamicStreamItem(); myDynamicStream.uri = "rtmp://localhost/vod/"; myDynamicStream.addStream ("mp4:ChefSchool_500.f4v",500); myDynamicStream.addStream ("mp4:ChefSchool_700.f4v",700); myDynamicStream.addStream ("mp4:ChefSchool_1500.f4v",1500); myVideo.play2 (myDynamicStream);

Save the file and test it.

SMIL and the FLVPlayback 2.5 component

As you have learned, it is a relatively simple matter to use the FLVPlayback 2.5 component to accommodate varying bit rates. As is usual with stuff that is great, there is an equally nasty gotcha. In this case the videos are "hard wired" into the component. What if you discover you need to add 300 and 1,000 Kbps bit rates (and the their corresponding F4V files) to the lineup? If you have access to the FLA file, this is a non-issue but it does tend to go against the grain when it comes to working with Flash.

There is a solution. Instead of an XML file, Flash Media Server supports dynamic streaming from an SMIL file. The beauty of this is you now have the ability to make changes without digging into the FLA or AS files. Here's how:

  1. Open the dynamicStream.smil file found in the MBR/SMIL directory. You can use Dreamweaver CS4 or any word processor to open the file. When it opens you should see the following:
<smil> <head> <meta base="rtmp://localhost/vod/" /> </head> <body> <switch> <video src="mp4:ChefSchool_500.f4v" system-bitrate="500000"/> <video src="mp4:ChefSchool_700.f4v" system-bitrate="700000"/> <video src="mp4:ChefSchool1_1500.f4v" system-bitrate="1500000"/> </switch> </body> </smil>

As you can see, the only major difference between the ActionScript written in the previous section and this file is in how the data rate is expressed. You need to enter the actual number, 500000, instead of the kilobit equivalent, 500.

  1. Close the SMIL file and open the MBR_SMIL.fla file found in the MBR/SMIL directory. Open the file, select the first frame of the actions layer, and then open the Actions panel.
  2. When the Script pane opens, click once in line 3 of the code and enter:
myVideo.source = "dynamicStream.smil"

That's all the code you need to add. At this point you can save and test the file.

You may have read that last line and wondered, "Hang on there, Tom. How does this get hooked into the FMS 3.5 server?" Good question: that information, contained in the RTMP address, is contained between the <head> </head> tags of the SMIL document. All you need to do is to enter the address and save the SMIL file to the same directory as the SWF.

Where to go from here

This tutorial showed you how to manage multiple-bit-rate scenarios using Flash Media Server 3.5 and the FLVPlayback 2.5 component and a SMIL file. In many respects, this is just a primer and is intended to introduce you to this new feature rather than let you really dig into it and get covered with electrons up to your elbows. If this subject has caught your attention, here are some other articles that will get you going: