Chapter 5. Video and Audio Enhancements

Adobe AIR has always supported the decoding and playback of industry standard H.264 alongside other codecs such as VP6 and Spark. With AIR 3, developers now have the ability to encode captured video to H.264 in the runtime itself, opening up a lot more possibilities for video capture and distribution applications for the desktop. Along with H.264 encoding, we also get another audio codec to work with in the form of G.711.

H.264/AVC Software Encoding

With AIR 3, developers now have the ability to encode H.264 video streams within the runtime itself. Prior versions of AIR were able to decode H.264 and with the additional encoding functionality, a whole other set of applications can be built to record and broadcast in this industry standard format.

Warning

H.264/AVC software encoding is only available on the desktop. Mobile devices cannot utilize this feature due to the amount of CPU it takes to encode the streams.

To compile and run the examples included below effectively, it is recommended that you install Flash Media Server.

Note

Note that if you do not have access to a commercial license for Flash Media Server, Adobe does offer a free developer edition with which you can test this and other examples. When doing any serious work through FMS, it is encouraged that you begin with a local development instance such as this.

Flash Media Server developer edition can be acquired from Adobe via http://www.adobe.com/products/flashmediaserver/

Warning

Flash Media Server is available for either Windows or Linux.

Encoding H.264 within AIR 3

To encode a video stream using H.264 within AIR 3, we must employ the new H264VideoStreamSettings class and associated objects. When constructing a H264VideoStreamSettings instance for use in our project, we can set the particular profile and level of the encoding. This is useful for targeting certain specific devices which may only support something like baseline encoding. Once we have configured our H264VideoStreamSettings instance, we assign it to the videoStreamSettings property of a NetStream instance and then process the stream as normal.

package {
    import flash.display.Sprite;
    import flash.events.NetStatusEvent;
    import flash.media.Camera;
    import flash.media.H264Level;
    import flash.media.H264Profile;
    import flash.media.H264VideoStreamSettings;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.text.TextField;
    import flash.text.TextFormat;

    [SWF(width="600", height="500", backgroundColor="#CCCCCC")]

    public class AVCEncode extends Sprite {

        private var traceField:TextField;
        private var video:Video;
        private var camera:Camera;
        private var connection:NetConnection;
        private var stream:NetStream;
        private var streamClient:Object;

        public function AVCEncode() {
            generateDisplayObjects();
            performOperations();
        }

        protected function generateDisplayObjects():void {
            video = new Video(stage.stageWidth, stage.stageHeight);
            addChild(video);

            var defaultFormat:TextFormat = new TextFormat();
            defaultFormat.font = "Arial";
            defaultFormat.size = 24;
            defaultFormat.color = 0xFFFFFF;

            traceField = new TextField();
            traceField.backgroundColor = 0x000000;
            traceField.alpha = 0.7;
            traceField.autoSize = "left";
            traceField.background = true;
            traceField.defaultTextFormat = defaultFormat;
            addChild(traceField);
        }

        protected function performOperations():void {
            camera = Camera.getCamera();
            camera.setMode(stage.stageWidth, stage.stageHeight, 30);
            camera.setQuality(60000, 80);
            video.attachCamera(camera);

            streamClient = new Object();
            streamClient.onBWDone = onBWDone;

            connection = new NetConnection();
            connection.client = streamClient;
            connection.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus);
            connection.connect("rtmp://localhost/live");
        }

        protected function monitorStatus(e:NetStatusEvent):void {
            traceField.appendText(e.info.code + "
");
            if(e.info.code == "NetConnection.Connect.Success"){
                beginStreaming();
            }else if(e.info.code == "NetStream.Publish.Start"){
                traceField.appendText("
" + e.info.description + "
");
                traceField.appendText("codec: " + stream.videoStreamSettings.codec);
            }
        }

        protected function beginStreaming():void {
            var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings();
            h264Settings.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_2);

            stream = new NetStream(connection);
            stream.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus);
            stream.videoStreamSettings = h264Settings;
            stream.attachCamera(camera);
            stream.publish("mp4:h264livestream.f4v", "live");
        }

        public function onBWDone():void {}

    }
}

So long as we have Flash Media Server installed and running on our local machine, we will receive a message stating that the stream is being published and that the codec being used to encode the video is H.264, along with a preview of the camera feed. In this example, we are simply viewing the raw camera output and not the encoded stream.

H.264 Encoding within AIR

Figure 5-1. H.264 Encoding within AIR

Reading an H.264 Stream into AIR 3

The ability to decode H.264 has been available since the initial release of AIR. To play back a stream or file encoded to H.264 with AIR 3, we employ the same procedure we would normally use. First, create a NetConnection and establish a connection to Flash Media Server. In this case, we use rtmp://localhost/live, as the server exists on the same machine. We then hook in a NetStream object and request to play the previously published stream.

package {
    import flash.display.Sprite;
    import flash.events.NetStatusEvent;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import flash.text.TextField;
    import flash.text.TextFormat;

    [SWF(width="600", height="500", backgroundColor="#CCCCCC")]

    public class AVCPlayback extends Sprite {

        private var traceField:TextField;
        private var video:Video;
        private var connection:NetConnection;
        private var stream:NetStream;
        private var streamClient:Object;

        public function AVCPlayback() {
            generateDisplayObjects();
            performOperations();
        }

        protected function generateDisplayObjects():void {
            video = new Video(stage.stageWidth, stage.stageHeight);
            addChild(video);

            var defaultFormat:TextFormat = new TextFormat();
            defaultFormat.font = "Arial";
            defaultFormat.size = 24;
            defaultFormat.color = 0xFFFFFF;

            traceField = new TextField();
            traceField.backgroundColor = 0x000000;
            traceField.alpha = 0.7;
            traceField.autoSize = "left";
            traceField.background = true;
            traceField.defaultTextFormat = defaultFormat;
            addChild(traceField);
        }

        protected function performOperations():void {
            streamClient = new Object();
            streamClient.onBWDone = onBWDone;

            connection = new NetConnection();
            connection.client = streamClient;
            connection.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus);
            connection.connect("rtmp://localhost/live");
        }

        protected function monitorStatus(e:NetStatusEvent):void {
            traceField.appendText(e.info.code + "
");
            if(e.info.code == "NetConnection.Connect.Success"){
                beginStreaming();
            }
        }

        protected function beginStreaming():void {
            stream = new NetStream(connection);
            stream.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus);
            stream.play("mp4:h264livestream.f4v");
            video.attachNetStream(stream);
        }

        public function onBWDone():void {}
    }
}

When this class is compiled to AIR, so long as we have the encoded stream successfully published to Flash Media Server through the previous code example, we will see the published, natively-encoded H.264 stream render through a Video object similar to Figure 5-2.

Decoded H.264 from Flash Player 11 encoded stream

Figure 5-2. Decoded H.264 from Flash Player 11 encoded stream

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset