Accessibility

Flash Player Article

 

Exploring Flash Player support for high-definition H.264 video and AAC audio


Table of Contents

Importing H.264 video and M4A audio using the NetStream object

This section gives a hands-on approach to integrating H.264 video and AAC/AAC+ audio using the power of ActionScript. For these examples you will use an AAC/AAC+ encoded M4A file. You will gain an understanding of how to play audio and video content using the power of the NetConnection, NetStream, and Video classes.

Playing H.264 content using NetStream

MPEG-4 content must be brought in through a NetStream object, but what it takes to play H.264 content in your Flash movie doesn't change much—although you'll need to watch out for a few more unsupported content messages. The new status messages are NetStream.Play.FileStructureInvalid and NetStream.Play.NoSupportedTrackFound. The former is sent when the MPEG-4 file structure is invalid, and the latter is sent when none of the audio or video tracks in the MPEG-4 file is supported.

You can also trick the video components in Flash into playing H.264 video files by changing their file extension to .flv. The video components currently look for the .flv extension for files they are playing, although Adobe is currently working on changing the specification and in a future update this won't be necessary.

Here is the more orthodox way to play a video using progressive download:

  1. Create a new ActionScript 3.0 Flash file. Save the file and name it H264_Video_AS3.fla.
  2. In the Timeline, rename Layer 1 as ~AS:Main (see Figure 2).

    Creating a new ActionScript 3.0 file

    Figure 2. Creating a new ActionScript 3.0 file

  3. Select Frame 1 in the Timeline and open the Actions panel (on Windows: F9, on Mac: Option+F9).
  4. Declare a video variable at the top of the code:

    var video:Video;
  5. Create a new NetConnection object and pass in null as the only parameter for the connect method:

    var connect_nc:NetConnection = new NetConnection();
    connect_nc.connect(null);
  6. Create a new NetStream object, passing your NetConnection object as a parameter to the constructor:

    var stream_ns:NetStream = new NetStream(connect_nc);
  7. In ActionScript 3.0 you'll need to specify a client object for the NetStream to handle stream events, otherwise you will receive a compile error. You don't actually have to create the handler methods, but you must have the client object. Let's set the client object equal to this so the Timeline can handle the NetStream's events. Add this code before you attach the NetStream video to the video object:

    stream_ns.client = this;
  8. Now to create the event listeners. Create the handler function for the NetStatusEvent as shown below:

    function netStatusHandler(p_evt:NetStatusEvent):void
    {
    }
  9. Inside the netStatusHandler function, create an if conditional statement. The conditional will check if the code property of the event object is equal to the string value of NetStream.Play.FileStructureInvalid:

    if(p_evt.info.code == "NetStream.Play.FileStructureInvalid")
    {
    }
  10. Inside the if conditional, use the trace() method to output a string that states the file structure is invalid:

    trace("The MP4's file structure is invalid");
  11. After the if condition, create an else condition. The else condition will check if the code value of the event object is equal to the string NetStream.Play.NoSupportedTrackFound:

    else if(p_evt.info.code == "NetStream.Play.NoSupportedTrackFound")
    {
    }
  12. Inside the else condition, use the trace() method to output a string that states the MP4 doesn't contain any supported tracks:

    trace("The MP4 doesn't contain any supported tracks");

    The completed netStatusHandler() function should look like this:

    function netStatusHandler(p_evt:NetStatusEvent):void
    {
       if(p_evt.info.code == "NetStream.Play.FileStructureInvalid")
       {
          trace("The MP4's file structure is invalid.");
       }
       else if(p_evt.info.code == "NetStream.Play.NoSupportedTrackFound")
       {
          trace("The MP4 doesn't contain any supported tracks");
       }
    }   
  13. Now let's attach this event handler to the NetStream object:

    stream_ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
  14. Under the line where you added the event handler, let's create your video dynamically:

    video = new Video();
    addChild(video);
  15. Use the attachNetStream method of the Video class rather than the old attachVideo method used in ActionScript 2.0:

    video.attachNetStream(stream_ns);
  16. Pass the URL or path of your H.264 video to the play method of the NetStream object:

    stream_ns.play("backcountry_bombshells_4min_HD_H264.mp4");

Using ActionScript to play AAC files

Playing AAC (M4A) files is the same in both ActionScript 2.0 and ActionScript 3.0. Just use the NetStream object and play the file:

  1. Create a new ActionScript 3.0 Flash file. Save the file and name it AAC_Audio_AS3.fla.
  2. In the Timeline, rename Layer 1: ~AS:Main (see Figure 3).

    Creating a new ActionScript 3.0 file: ~AS:Main

    Figure 3. Creating a new ActionScript 3.0 file: ~AS:Main

  3. Select the Frame 1 in the Timeline and open the Actions panel (on Windows: F9, on Mac: Option+F9).
  4. Create a new NetConnection object named connect_nc, and then call the connect() method, passing in null as the only parameter:

    var
    connect_nc:NetConnection = new NetConnection();
    		      
    connect_nc.connect(null);
  5. Create a new NetStream object, passing your NetConnection object as a parameter to the constructor:

    var stream_ns:NetStream = new NetStream(connect_nc);
  6. Pass the URL or path of your AAC (M4A) file to the play method of the NetStream object:

    stream_ns.play("RE-Sample.m4a"); 

    The completed code should look like this:

    var connect_nc:NetConnection = new NetConnection();
    connect_nc.connect(null);
    var stream_ns:NetStream = new NetStream(connect_nc);
    stream_ns.play("RE-Sample.m4a");
  7. Test your movie in the browser. The audio should begin to play.

Using a Sound object to control an AAC file

The previous section reviewed how to use ActionScript to play AAC files. Controlling your M4A audio with a Sound object is a little trickier. The Sound object can't load in M4A files the way it can load MP3 files, so for this part you'll need to bring files in using the NetStream and then work with them from there:

  1. Open the same Flash file that you worked with in the first audio example (AAC_Audio_AS3.fla) or open the AAC_Audio_AS3_Sound_complete.fla file in the sample files folder.
  2. On the ~AS:Main layer in the Timeline, select Frame 1 and open the Actions panel (on Windows: F9, on Mac: Option+F9).
  3. Declare the SoundTransform variable at the beginning of the code:

    var mySound:SoundTransform;
  1. You can't directly access the properties of the NetStream's SoundTransform object, but you can reference the object itself. So after you start playing the video in the NetStream, set the mySound variable equal to the NetStream's soundTransform property, like this:

    stream_ns.play("RE-Sample.m4a"); 
    mySound = stream_ns.soundTransform; 
  2. Set the volume for mySound, using a number between 0 and 1:

    mySound.volume = .5;
  3. Overwrite the NetStream's soundTransform property with mySound so the changes to the volume will be applied:

    mySound.volume = .5; 
    stream_ns.soundTransform = mySound;

    The completed ActionScript should look like this:

    var mySound:SoundTransform;
    var connect_nc:NetConnection = new NetConnection();
    connect_nc.connect(null);
    var stream_ns:NetStream = new NetStream(connect_nc);
    stream_ns.play("RE-Sample.m4a");
    mySound = stream_ns.soundTransform;
    mySound.volume = .5;
    stream_ns.soundTransform = mySound;
  4. Test your movie in the browser. The audio should begin to play, with the volume level at about half of what it was originally.

Using a SoundTransform object to control an H.264 file

With ActionScript 3.0, you cannot use the Sound object to control the video's audio, because the Sound object has been altered so you can no longer attach sounds. Instead, you'll need to use the SoundTransform object attached to the NetStream. Here are the steps:

  1. Open the same file that you worked with in the video example (H264_Video_AS3.fla) or open the H264_Video_AS3_Audio.fla file in the sample files folder.
  2. On the ~AS:Main layer in the Timeline, select Frame 1 and open the Actions panel (on Windows: F9, on Mac: Option+F9).
  3. Declare the SoundTransform variable at the beginning of the code:

    var mySound:SoundTransform; 
  4. This is where things get a bit odd. You can't directly access the properties of the NetStream's SoundTransform object, but you can reference the object itself. So after you start playing the video in the NetStream, set your mySound variable equal to the NetStream's soundTransform property, like this:

    mySound = stream_ns.soundTransform;
  5. Set the volume for mySound, using a number between 0 and 1:

    mySound.volume = .5;
  6. Overwrite the NetStream's soundTransform property with mySound so the changes to the volume will be applied:

    stream_ns.soundTransform = mySound;

Using ActionScript 3.0 and Flex to play H.264 content

H.264 content is supported in Flex as well. Here are the steps:

  1. Create a custom class that extends the UIComponent class. Call yours H264Video and store it in a subfolder called video.
  2. Before the constructor, declare some variables, like this:
    private var _video:Video;      
    private var _connection_nc:NetConnection;      
    private var _stream_ns:NetStream;      
    private var _client:Object;      
    private var _filePath:String; 
  3. In the constructor, call both the super() and an init() methods:
    public function H264Video()
    {
         super();      
         init();
    } 
  4. Write the init method as shown below to create Video, NetConnection, and NetStream objects:
    public function init():void      
    {      
         _video = new Video();           
          
         _connection_nc = new NetConnection();      
         _connection_nc.connect(null);           
          
         _stream_ns = new NetStream(_connection_nc);   
          
    } 
  5. Under the _stream_ns = NetStream(_connection_nc); line, add in a line of code to set an object as the client for your NetStream. The handling isn't necessary, but you must construct the client object:
    _client = new Object();      
    _stream_ns.client = _client; 
  6. Also add in a line of code to handle status events from the NetStream:

    _stream_ns.addEventListener(NetStatusEvent.NET_STATUS, onStatus); 
  7. In the init() method, attach the NetStream to the video, add the video to the display list, and start playing the video file if the _filePath exists. The completed method should look like this:
    public function init():void      
    {      
         _video = new Video();          
          
         _connection_nc = new NetConnection();      
         _connection_nc.connect(null);           
          
         _stream_ns = new NetStream(_connection_nc);      
         _client = new Object();      
         _stream_ns.client = _client;      
         _stream_ns.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
                     
         _video.attachNetStream(_stream_ns);
                     
         this.addChild(_video);
      
          if(_filePath)      
         {      
             _stream_ns.play(_filePath);      
         }                 
    }
  8. Create the function to handle status events. In particular, handle those two new status events that you can track in H.264 video:

    private function onStatus(p_evt:NetStatusEvent):void
        {
            if(p_evt.info.code == "NetStream.Play.FileStructureInvalid")
            {
                 Alert.show("The MP4's file structure is invalid.", "Status");
            }
            else if(p_evt.info.code == "NetStream.Play.NoSupportedTrackFound")
            {
                 Alert.show("The MP4 doesn't contain any supported tracks", "Status");
            }
            else if(p_evt.info.level == "error")
            {
                 Alert.show("There was some sort of error with the NetStream", "Error");
            }
        }
  9. Create getter/setter methods for the _filePath property. On setting the filePath, call the play() method on the NetStream instance and pass it the filePath's value. Also add a [Bindable] metadata tag above the getter, like this:

    [Bindable]
          
    public function get filePath():String      
    {      
         return _filePath;      
    }      
                
    public function set filePath(p_path:String):void
          
    {      
         _filePath = p_path;      
         _stream_ns.play(_filePath);      
    } 
  10. Save your file.

You can then bring your video into the Flex application either solely by ActionScript or by using MXML. In your MXML file, you can create a tag on the Stage for your H264Video, and then specify an id, x, y values, etc. If you are using the Adobe AutoComplete Input Flex component to get code hints, Flex will create the namespace for you to use this tag. Also, set the filePath property on the MXML tag, pointing to your video file:

<video:H264Video      
     id="video_h264"       
     x="10" y="10"       
     filePath="myVideo.mov" />