How to Load External Flash Video (FLV) Files (AS3)

ActionScript 3.0 Flash

This article can be considered a sequel to “How to Load External Flash Video (FLV) Files (AS2).”  The code suggested here is nothing more than the ActionScript 3.0 way to accomplish the same goal achieved earlier; namely, to load an external Flash video (FLV) file at runtime — without using the FLVPlayback component.  To be sure, there’s nothing wrong with FLVPlayback.  Its skins are customizable (all the more so in Flash CS3, which is the first version of Flash to support AS3) and it provides plenty of built-in widgets, such as play/pause, a volume slider, mute button, and the like.  But to get those features, even if you choose a non-skinned component, you pay a 49KB price in an ActionScript 3.0 document.  If you go without the component, it costs you less than 1KB.  That means site visitors can spend their bandwidth on your video content itself, rather than the video player. 

An answer, short and sweet

As described in the AS2 version of this article, you’re going to use an instance each of the NetConnection and NetStream classes in addition to a Video object.  In ActionScript 3.0 — this is really neat — you can even create your Video instance via ActionScript.  This is new.  If you like, though, you can also still use the Library panel to create a video asset beforehand and drag it to the Stage.  We’ll look at both approaches.  First, the completely programmatic way:

var vid:Video = new Video(320, 240);
addChild(vid);

var nc:NetConnection = new NetConnection();
nc.connect(null);

var ns:NetStream = new NetStream(nc);
vid.attachNetStream(ns);

var listener:Object = new Object();
listener.onMetaData = function(evt:Object):void {};
ns.client = listener;

ns.play("externalVideo.flv");

How it works

An arbitrarily named variable, vid, is declared and set to an instance of the Video class.  To specify the size of this video, two parameters are passed into the constructor:  a width and height of 320 and 240 pixels.  As it turns out, this is the default, so you can leave those numbers out completely and your video will show as 320×240.  If you want something bigger or smaller, or if your video’s dimensions are some other aspect ratio, specify the relevant numbers.  The line immediately following, addChild(vid), invokes the DisplayObjectContainer.addChild() method on the timeline in which this code appears.

Why the timeline?  Because the method stands alone, doesn’t have an object reference prefixed to it.  (In contrast, other methods in the above snippet are preceded by object references.)  What’s a DisplayObjectContainer?  Well, it’s just another class, like the others we’re using here.  DisplayObjectContainer is inherited by a number of everyday classes, such as MovieClip.

The timeline in which this code appears (i.e., the main timeline) actually is a MovieClip instance, which means it has access to the addChild() method thanks to the fact that DisplayObjectContainer is a grandparent in its family tree.  By “adding the child” vid, you’re simply making the Video object visible.  You’re adding it to the display list of the main timeline, which means it’ll show up visually (even though it exists before then and would even if you failed to add it to the list — in which case it just wouldn’t show).

So now we have a Video object to display the video.  Now we need to hook it up.  Another arbitrarily named variable, nc, is declared and set to an instance of the NetConnection class, then the NetConnection.connect() method is called on it and passed a null parameter.  Why null?  All that means is that we’re requesting a progressive download FLV file; that is, one that isn’t streamed via Flash Media Server.

With this connection established, a third arbitrarily named variable, ns, is declared and set to an instance of the NetStream class.  This instance is associated with the net connection, and the Video.attachNetStream() method is invoked on vid to associate it with the net stream.  This may be a bit tedious, but it’s not too bad, and certainly pretty straightforward.

The next three lines merit a bit of explanation.  Here they are again:

var listener:Object = new Object();
listener.onMetaData = function(evt:Object):void {};
ns.client = listener;

This is one of the very few exceptions to how event handing is done in ActionScript 3.0.  Normally, the task is done as described in this excellent article by Trevor McCauley, “Introduction to event handling in ActionScript 3.0.”  Here, the NetStream.onMetaData event is taken care of by a sort of liaison — a generic Object instance — the way it’s often done in AS2.  Why are we even handling onMetaData?  Strictly speaking, you don’t have to.  If your FLV doesn’t have metadata embedded in it, the onMetaData event won’t be dispatched when the video starts playing.  Most FLV encoders, however (including the native Flash Import Video Wizard), do embed metadata, and if you don’t handle the dispatched event, you’ll see an error message in the Output panel.  The above three lines simply create a dummy stand-in function (that doesn’t do anything) and associate it with an onMetaData property of the Object instance, arbitrarily named listener.  This object is then connected with the NetStream instance by way of its client property.

Finally, NetStream.play() is invoked on ns and told which FLV to play.

What if I prefer a made-by-hand Video object?

If you remember the AS2 version of this article and prefer your older workflow, drop the first two lines of the above code sample.  Instead, right-click / Command-click in an open space in your Library panel, choose New Video… from the context menu, hit OK to accept the default values — this gives you an ActionScript-controllable Video object with an asset name of Video 1 — then drag that asset to the Stage.  Size it to the dimensions of your video content, then use the Property inspector to give the object an instance name, such as videoPlayer.  That instance name will be your key to associating this Video object with the NetStream instance:

var nc:NetConnection = new NetConnection();
nc.connect(null);

var ns:NetStream = new NetStream(nc);
videoPlayer.attachNetStream(ns);

var listener:Object = new Object();
listener.onMetaData = function(evt:Object):void {};
ns.client = listener;

ns.play("externalVideo.flv");

And there you have it.  See how most of that code overlaps?

Leave a Reply