8 May 2009
A basic understanding of how to use video in Flash, the FLVPlayback component, and Flash Media Server 3.5 is required.
Additional required product
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.
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.
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.
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:
Now that the assets are in place, you can turn your attention to "wiring up" this project with ActionScript 3.0:
import fl.video.*; 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.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.
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.
The new method is
play2(), which is an enhancement of the
NetStream.play() 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.
import fl.video.*; 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.
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:
<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.
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> 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.
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:
Tutorials & Samples