Streaming media, unlike progressively loaded media, is delivered (or ‘streamed’) in a series of packets that are continually delivered to the user during playback. For this reason, unlike progressively delivered media, media files that are streamed are never actually stored on viewer computers. Streaming is a very effective way to deliver large audio and video files and, in particular, streaming facilitates rapid and immediate seeking (with progressive media, you can only seek to those portions of the media that have already downloaded).
If you are interested in working more with streaming, and you are on a Windows or Linux machine, you can install a local developer version of Flash Media Server (which you may download from http://adobe.com/products/flashmediaserver/). If you are working on Mac, or you wish to develop your FMS work on a live server, you can lease FMS inexpensively from http://Influxis.com.
URL Formatting for Streaming
Before we get into the code for streaming, if you aren’t used to working with Flash Media Server, you may not be used to the rather awkward logic FMS requires with respect to streaming media file extensions.
If you are streaming an FLV, you strip the ‘.flv’ when calling the file, as in:
rtmp://myFMS.com/appDirectory/my
Basic RTMP Streaming
OSMF makes streaming incredibly easy. If you return to our ‘Basic OSMF Example, we can change the URL in this line of code:
var videoElement : VideoElement = new VideoElement(new URLResource(“my.flv”));
to (assuming you had a Flash Media Server setup at myFMS.com):
var videoElement : VideoElement = new VideoElement(new URLResource(“rtmp://myFMS.
com/appDirectory/my”));
And voila! Our player is now a streaming video player. Seriously, that’s it. But it gets better.
HTTP Streaming
The above is an example of RTMP streaming—or streaming with the real-time media protocol (used by Adobe’s Flash Media Server).
With Flash Player 10.1, you can now stream your media without an RTMP server, straight from your web server, utilizing HTTP Streaming (assuming your web server is configured to support it, which the majority are). It’s just what it sounds like—streaming video without Flash Media Server.
Can you guess how difficult the code is? Well, it’s the same code as we’ve already worked with, but instead of pointing to an FLV, F4V, MP4 or MP3, we point to an F4M file, or a Flash Media Manifest file, which is an XML file containing information about a Flash media asset. For example:
var videoElement : VideoElement = new VideoElement(new URLResource(“http://my.com/
my.f4m”));
For more information on F4M, reference the specification at <"http://opensource.adobe.com/wiki/display/osmf/Flash+Media+Manifest +File+Format+Specification">http://opensource.adobe.com/wiki/display/osmf/Flash+Media+Manifest+File+Format+Specification>.
Dynamic Streaming
Sometimes you want to prepare multiple versions of the same video, at different quality bitrates, so that viewers can enjoy the highest quality video possible, given their bandwidth. And, because a viewer’s bandwidth can change over time, you will want to query the active bandwidth repeatedly, and change to a higher or lower quality video if the viewer’s bandwidth has shifted.
This process is called Dynamic Streaming—delivering the highest quality video possible, at all times during the viewing experience, from a collection of videos encoded at different bitrates.
Though not quite as simple as basic streaming (after all, there’s more information we have to setup to get this working), implementing dynamic streaming with OSMF is remarkably easy.
DynamicStreamingResource
In all of the prior examples, we have utilized a URLResource to wrap the URL to our media file, when creating our VideoElement, as in:
var videoElement : VideoElement = new VideoElement(new URLResource(“my.flv”));
To implement dynamic streaming, we need to use a different class—the DynamicStreamingResource. When we create a DynamicStreamingResource, instead of pointing to a media file, we point to a Flash Media Server application directory. First, we import the DynamicStreamingResource class:
import org.osmf.net.DynamicStreamingResource ;
Then, we create a new DynamicStreamingResource:
var resource : DynamicStreamingResource = new DynamicStreamingResource ( “rtmp://
myFMS.com/myAppDir” ) ;
DynamicStreamingItem
Our resource now points to an entire directory, instead of a single file. Next, we must populate our DynamicStreamingResource with the information pointing to our actual video files.
To do so, we create a DynamicStreamingItem instance for each bitrate we intend to support. When creating a DynamicStreamingItem, we specify a filename (respecting FMS file extension rules, noted above), and a minimum supported bandwidth (in kilobits-per-second, or kbps) required to view this version of the video:
new DynamicStreamingItem ( “my_high” , 1500 )
In our code, we will store these DynamicStreamingItem instances in a vector (vectors are similar to arrays, but the values stored in the indices of a vector must conform to the same datatype—in this case, all values stored in our vector will be DynamicStreamingItem instances).
For our example, we will support three separate bitrates in our player: 400kbps (low), 800kbps (medium) and 1.5mbps (high). To start, of course, we will need to import the DynamicStreamingItem class:
import org.osmf.net.DynamicStreamingItem ;
Then, we will create our vector of DynamicStreamingItems (with a fixed length of 3, because we wish to support precisely three bitrates):
var vector : Vector. = new Vector. (
3 ) ;
Next, we will populate our vector with the three DynamicStreamingItem instances.
vector [ 0 ] = new DynamicStreamingItem ( “my_high” , 1500 ) ;
vector [ 1 ] = new DynamicStreamingItem ( “my_low” , 400 ) ;
vector [ 2 ] = new DynamicStreamingItem ( “my_medium” , 800 ) ;
Note that the ordering of DynamicStreamingItems in the vector is irrelevant.
Then, before we move on, we ensure that the streamItems property of our DynamicStreamingResource points to our vector:
resource.streamItems = vector ;
Bringing it all Together
There may be some new and long class names involved, but building a dynamic streaming player with OSMF is remarkably easy—the code is very brief (only 12 lines in this example) and very similar to the basic six lines of code we used to progressively play a single video:
var player : MediaPlayer = new MediaPlayer ( ) ;
var container : MediaContainer = new MediaContainer ( ) ;
addChild ( container ) ;
var resource : DynamicStreamingResource = new DynamicStreamingResource ( “rtmp://
myFMS.com/myAppDir” ) ;
vector [ 0 ] = new DynamicStreamingItem ( “my_high” , 1500 ) ;
vector [ 1 ] = new DynamicStreamingItem ( “my_low” , 400 ) ;
vector [ 2 ] = new DynamicStreamingItem ( “my_medium” , 800 ) ;
resource.streamItems = vector ;
videoElement = new VideoElement( resource ) ;
player.media = videoElement ;
container.addMediaElement ( videoElement ) ;
Subclipping
When you stream with an RTMP server, it is easy to play segments from entire videos—referred to as subclipping, or playing clips within clips.
We do this with the StreamingURLResource, which we can use instead of a regular URLResource. A StreamingURLResource points only to a specific portion of a streamed video, determined by in and out points (measured in seconds), set when you create the instance:
new StreamingURLResource( url, streamType , clipStartTime , clipEndTime );
There are many potential uses for subclipping, but an obvious one is the insertion of interstitial advertising. Let’s say we wish to stream a one-minute clip, and progressively deliver a video ad half way through (at 30 seconds). This will require two subclips (aka StreamingURLResources) and a regular URLResource (for the ad), connected by a SerialElement (so that they play sequentially, rather than concurrently).
To start, we import the StreamingURLResource class:
import org.osmf.net.StreamingURLResource ;
Then we can write the following code:
var serialElement : SerialElement = new SerialElement();
var resource1 = new StreamingURLResource( “rtmp://myFMS.com/app/vid1” , null, 0,
30 );
serialElement.addChild( new VideoElement( resource1 ) );
var resource2 : URLResource = new URLResource ( “myAd.flv” ) ;
serialElement.addChild( new VideoElement( resource2 ) );
var resource3 = new StreamingURLResource( “rtmp://myFMS.com/app/vid1”, null, 30,
60 );
serialElement.addChild( new VideoElement( resource3 ) );
var mediaPlayer : MediaPlayer = new MediaPlayer( serialElement );
var container : MediaContainer = new MediaContainer();
addChild( container );
container.addMediaElement( serialElement );
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}