Archive for the ‘Flash Media Server’ Category

Recording and streaming video with FM2 and AS3

Friday, October 12th, 2007
For some reason all of the code examples for using FM2 are in AS2. Converting the examples to AS3 can be a bit challenging, especially since there is one really key piece of information that is left out that is new to AS3 and specific to the use of FM2. The problem is the that FM2 only supports AMF0, but in AS3 the default setting for the NetConnection class' defaultObjectEncoding property is AMF3. Without changing this setting to AMF0, your code will seem to be correct, but will fail to connect without really telling you why. Check out the class that I created from the Adobe example and the MXML to use it.
package
{
    import flash.events.*;
    import flash.media.Microphone;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;
    import mx.controls.VideoDisplay;

    public class StreamingFLV extends EventDispatcher {
        private var cam:Camera;
        private var mic:Microphone;
        private var rtmp:String;
        private var nc:NetConnection;
        private var ns:NetStream;
        private var local_video:VideoDisplay;
        private var _rtmp:String;
        private var _source:String;

        public function StreamingFLV(_lv:VideoDisplay,_r:String,_s:String) {
            _rtmp = _r;
            _source = _s;

            cam = Camera.getCamera();
            cam.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
            cam.addEventListener(StatusEvent.STATUS, handleCameraStatus);

            mic = Microphone.getMicrophone();
            mic.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
            mic.addEventListener(StatusEvent.STATUS, handleCameraStatus);

            local_video = _lv;

            NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
            nc = new NetConnection();
            nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
            nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            nc.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
            nc.connect(_rtmp);
        }

        public function startRecordFLV():void {
            local_video.attachCamera(cam);
            ns.attachAudio(mic);
            ns.attachCamera(cam);
            ns.publish(_source, "record");
        }

        public function stopRecordFLV():void {
            ns.close();
            local_video.close();
        }

        public function startPlayback():void {
            local_video.source = _rtmp +"/"+ _source + ".flv";
        }

        public function stopPlayback():void {
            local_video.close();
        }

        private function connectStream():void {
            ns = new NetStream(nc);
            ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
            ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
            ns.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            ns.client = this;

            dispatchEvent(new Event("onVideoReady"));
        }

        private function handleCameraStatus(event:StatusEvent):void {
            trace("handleCameraStatus: " + event);
        }

        private function activityHandler(event:ActivityEvent):void {
            trace("activityHandler: " + event);
        }

        private function netStatusHandler(event:NetStatusEvent):void {
            trace(event.info.code);
            switch (event.info.code) {
                case "NetConnection.Connect.Success":
                    connectStream();
                    trace("Connected");
                    break;
                case "NetStream.Play.StreamNotFound":
                    trace("No Connection!");
                    break;
            }
        }
        private function securityErrorHandler(event:SecurityErrorEvent):void {
            trace("securityErrorHandler: " + event);
        }
        private function ioErrorHandler(event:AsyncErrorEvent):void {
            trace("ioErrorHandler: " + event);
        }
        private function asyncErrorHandler(event:AsyncErrorEvent):void {
            trace("asyncErrorHandler: " + event);
        }
        private function onMetaData(info:Object):void {
            trace("metadata: duration=" + info.duration + " width=" + info.width + " height=" + info.height + " framerate=" + info.framerate);
        }
        private function onCuePoint(info:Object):void {
            trace("cuepoint: time=" + info.time + " name=" + info.name + " type=" + info.type);
        }
        private function onPlayStatus(info:Object):void {
            trace(info.toString());
        }

    }
}
And now the MXML:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    paddingTop="0"
    paddingLeft="0"
    paddingBottom="0"
    paddingRight="0"
    horizontalAlign="center"
    verticalAlign="middle"
    backgroundGradientAlphas="[0,0]"
    backgroundColor="#CCCCCC"
    applicationComplete="init();">
    <mx:Script>
        <![CDATA[
            import StreamingFLV;
            import flash.media.Camera;
            import flash.display.StageAlign;
            import flash.display.StageScaleMode;

            private var rFLV:StreamingFLV;
            private var pFLV:StreamingFLV;
            private var isPlaying:Boolean = false;
            private var isRecording:Boolean = false;

            private function init():void {
                stage.scaleMode = StageScaleMode.NO_SCALE;
                stage.align = StageAlign.TOP_LEFT;
            }

            private function initRecordStream():void {
                rFLV = new StreamingFLV(video_record,"rtmp://los1aps-flash/zflv/test","recordSample");
                rFLV.addEventListener("onVideoReady",initUI);
            }

            private function initPlayStream():void {
                pFLV = new StreamingFLV(video_play,"rtmp://los1aps-flash/zflv/test","recordSample");
                pFLV.addEventListener("onVideoReady",initUI);
            }

            private function recordToggle():void {
                if (!isPlaying) {
                    record.label = "RECORDING";
                    rFLV.startRecordFLV();
                } else {
                    record.label = "RECORD";
                    rFLV.stopRecordFLV();
                }
                isPlaying = !isPlaying;
            }

            private function playToggle():void {
                if (!isPlaying) {
                    play.label = "PLAYING";
                    pFLV.startPlayback();
                } else {
                    play.label = "PLAY";
                    pFLV.stopPlayback();
                }
                isPlaying = !isPlaying;
            }

            private function initUI(evt:Event):void {
                record.enabled = true;
                play.enabled = true;
            }
        ]]>
    </mx:Script>
    <mx:VBox horizontalAlign="center">
        <mx:HBox>
            <mx:VBox horizontalAlign="right">
                <mx:VideoDisplay id="video_record" width="320" height="240" creationComplete="initRecordStream();" />
                <mx:Button id="record" label="record" enabled="false" click="recordToggle();" />
            </mx:VBox>
            <mx:VBox horizontalAlign="left">
                <mx:VideoDisplay id="video_play" width="320" height="240" creationComplete="initPlayStream();" />
                <mx:Button id="play" label="play" enabled="false" click="playToggle();" />
            </mx:VBox>
        </mx:HBox>
    </mx:VBox>
</mx:Application>
Enjoy!

WebOrb Standard, FMS developer, etc…
No excuse not to learn

Tuesday, July 24th, 2007
Did you know that some of the most amazing server-side software for Flash is available for free? Most sever software products are available to developers for free with a 5 IP connection limit, but are full featured. Even with this limitation there are more than enough connections to be useful for learning how to take advantage of protocols like AMF and RTMP in your Flash applications.

You’ll probably want to set up a server as well, so re-purpose that old PC and install Linux on it to provide a separate server environment from your local development environment. Red Hat offers the latest version of it’s OS as Fedora Core, it’s easy to install, set-up and manage without having to do to much command-line.

Get your free software here:
Fedora Core
Flash Media Server
LiveCycle Data Services ES Express
WebOrb

Now there are no more excuses for not knowing how to use these tools to make your Flash as awesome as it can be. Having the skills to uses these tools is what could get you hired on my team! Good luck and happy coding.