views:

110

answers:

1

So far the solution I found requires a crossdomain.xml to work,but this is not available on an IP camera:

<?xml version="1.0" encoding="utf-8"?>  
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="init()">  
    <mx:Script>  
        <![CDATA[  
            import utils.video.mjpeg.MJPEG;  
            public function init():void{  
                Security.loadPolicyFile("xmlsocket:http://10.8.0.54/crossdomain.xml");  
                trace("xmlsocket:http://10.8.0.54/crossdomain.xml")  
                var vid:MJPEG = new MJPEG("10.8.0.54", "", 8081);  
                video.rawChildren.addChild(vid);  
            }  
        ]]>  
    </mx:Script>  
    <mx:VBox id="video"></mx:VBox>  
</mx:Application>  
//////////////////////////  
package  utils.video.mjpeg  
{  
    import flash.display.Loader;  
    import flash.events.Event;  
    import flash.events.ProgressEvent;  
    import flash.net.Socket;  
    import flash.utils.ByteArray;  

    import mx.utils.Base64Encoder;  

    /** 
     * This is a class used to view a MJPEG 
     * @author Josh Chernoff | GFX Complex 
     *  
     */  
    public class  MJPEG extends Loader  
    {  
        private var _user:String;                                   //Auth user name  
        private var _pass:String;                                   //Auth user password  

        private var _host:String;                                   //host server of stream  
        private var _port:int;                                      //port of stream          
        private var _file:String;                                   //Location of MJPEG  
        private var _start:int = 0;                                 //marker for start of jpg  

        private var webcamSocket:Socket = new Socket();             //socket connection  
        private var imageBuffer:ByteArray = new ByteArray();        //image holder  

        /** 
         * Create's a new instance of the MJPEG class. Note that due a sandbox security problem, unless you can place a crossdomain.xml  
         * on the host server you will only be able to use this class in your AIR applications. 
         *  
         * @example import MJPEG; 
         *          var cam:MJPEG = new MJPEG("192.168.0.100", "/img/video.mjpeg", 80); 
         *          addChild(cam); 
         *           
         * @param   host:String | Host of the server. Do not include protocol  
         * @param   file:String | Path to the file on the server. Start with a forward slash 
         * @param   port:int    | Port of the host server; 
         * @param   user:String | User name for Auth 
         * @param   pass:String | User password for Auth 
         */  
        public function MJPEG (host:String, file:String, port:int = 80, user:String = null, pass:String = null )  
        {  
            _host = host;  
            _file = file;  
            _port = port;  
            _user = user;  
            _pass = pass;  

            webcamSocket.addEventListener(Event.CONNECT, handleConnect);  
            webcamSocket.addEventListener(ProgressEvent.SOCKET_DATA, handleData);  
            webcamSocket.connect(host, port);  

        }  

        private function handleConnect(e:Event):void   
        {  
            // we're connected send a request  
            var httpRequest:String = "GET "+_file+" HTTP/1.1\r\n";  
            httpRequest+= "Host: localhost:80\r\n";  
            /*  
            if(_user != null && _pass != null){ 
                            var source:String = String(_user + ":" + _pass); 
                            var auth:String = Base64.encode(source); 
                            httpRequest += "Authorization: Basic " + auth.toString()+ "\r\n";   //NOTE THIS MAY NEEED TO BE EDITED TO WORK WITH YOUR CAM 
            } 
             */  
            httpRequest+="Connection: keep-alive\r\n\r\n";  
            webcamSocket.writeMultiByte(httpRequest, "us-ascii");  
        }  

        private function handleData(e:ProgressEvent):void {  
            //trace("Got Data!" + e);  
            // get the data that we received.  

            // append the data to our imageBuffer  
            webcamSocket.readBytes(imageBuffer, imageBuffer.length);  
            //trace(imageBuffer.length);  
            while(findImages()){  
            //donothing  
            }  


        }  


        private function findImages():Boolean  
        {  

            var x:int = _start;  
            var startMarker:ByteArray = new ByteArray();      
            var end:int = 0;  
            var image:ByteArray;  

            if (imageBuffer.length > 1) {  
                if(_start == 0){  
                    //Check for start of JPG  
                    for (x; x < imageBuffer.length - 1; x++) {  

                        // get the first two bytes.  
                        imageBuffer.position = x;  
                        imageBuffer.readBytes(startMarker, 0, 2);  

                        //Check for end of JPG  
                        if (startMarker[0] == 255 && startMarker[1] == 216) {  
                            _start = x;  
                            break;                    
                        }  
                    }  
                }  
                for (x; x < imageBuffer.length - 1; x++) {  
                    // get the first two bytes.  
                    imageBuffer.position = x;  
                    imageBuffer.readBytes(startMarker, 0, 2);  
                    if (startMarker[0] == 255 && startMarker[1] == 217){  

                        end = x;  

                        image = new ByteArray();  
                        imageBuffer.position = _start;  
                        imageBuffer.readBytes(image, 0, end - _start);  

                        displayImage(image);  

                        // truncate the imageBuffer  
                        var newImageBuffer:ByteArray = new ByteArray();  

                        imageBuffer.position = end;  
                        imageBuffer.readBytes(newImageBuffer, 0);  
                        imageBuffer = newImageBuffer;  

                        _start = 0;  
                        x = 0;  
                        return true;  
                    }  
                }  
            }  

            return false;  
        }  

        private function displayImage(image:ByteArray):void  
        {  
            this.loadBytes(image);  
        }  

    }  

}  
A: 

Maybe I'm not understanding your question, but if we're talking about the same thing...

In my flash (which was written in AS2 so you may need to look up how it's different in AS3, I notice you're not using the security class of System... they may have removed that), I have this line... System.security.loadPolicyFile("xml_root.socket://" + _root.HOST + ":" +_root.GAME_PORT );

I'm pretty sure this simply goes and fetches the static crossdomain.xml from the docroot of my server.

On the server side of things your socket code (what is that written in?) can deliver the crossdomain policy directly.

Here's the piece from my Perl socket that responds to the flash socket's initial request. I wrote this a long time ago but it would appear that the socket sends this tiny xml fragment as its initial communication to the socket "<policy-file-request/>" in response to which you want to do the following...

if($input eq "<policy-file-request/>"){ #if the string arriving on the socket == <policy-file-request>"

  #assemble the printed response to look just like a crossdomain policy file. Set permissions as you normally would.
  #if you don't know perl, the qq~ is just a way to provide a chunk of multiline code in one fragment.  But note the \0 at the end. All socket messages have to be null terminated manually by you.
  $MESSAGE =      qq~<?xml version="1.0"?>
                      <cross-domain-policy>
                      <allow-access-from domain="*" to-ports="*"/>
                      </cross-domain-policy>\0~;
}
print "$MESSAGE"; #send the string back on the socket

Make sure this is actually what you need. Sometimes all you need is for the server to just have the crossdomain.xml policy file sitting at the docroot.

Dr.Dredel
But I've no control over the server side,it's internal of IP camera itself.
ollydbg
Ah. I see now. I had to look up what an IP Camera was... never heard that expression before. I think the easiest way to handle this is to create a relay through the server and have your Flash socket connect to that. Let that talk to the camera on a different socket port, so... IP Camera -> server socket -> Flash. The server socket doesn't care about security and can talk to the camera and can provide Flash with the security it requires. Assuming your IP camera is on the same network as your computer you can easily run the socket on that.
Dr.Dredel
Pretty much like USB cameras,but can be accessed by a url.
ollydbg