1

これまでのところ、私が見つけた解決策を実行するには が必要crossdomain.xmlですが、これは IP カメラでは利用できません。

<?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);  
        }  

    }  

}  
4

1 に答える 1

0

私はあなたの質問を理解していないかもしれませんが、もし私たちが同じことを話しているなら...

私のフラッシュ(AS2で書かれたので、AS3での違いを調べる必要があるかもしれません。システムのセキュリティクラスを使用していないことに気づきました...彼らはそれを削除した可能性があります)、私はこの行を持っています.. .

System.security.loadPolicyFile("xml_root.socket://" + _root.HOST + ":" +_root.GAME_PORT );

これは単純に、サーバーの docroot から静的な crossdomain.xml をフェッチするだけだと確信しています。

サーバー側では、ソケット コード (これは何に記述されていますか?) がクロスドメイン ポリシーを直接配信できます。

これは、フラッシュ ソケットの最初の要求に応答する Perl ソケットの一部です。私はこれをずっと前に書きましたが、ソケットはこの小さな xml フラグメントをソケット "<policy-file-request/>" への最初の通信として送信するように見えます。

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

これが実際に必要なものであることを確認してください。サーバーの docroot に crossdomain.xml ポリシー ファイルを配置するだけでよい場合もあります。

于 2010-10-03T07:08:59.073 に答える