【问题标题】:How to render IP camera video with socket by actionscript?如何通过 actionscript 使用套接字渲染 IP 摄像机视频?
【发布时间】:2011-12-20 03:26:03
【问题描述】:

到目前为止,我找到的解决方案需要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);  
        }  

    }  

}  

【问题讨论】:

    标签: flash actionscript ip-camera


    【解决方案1】:

    也许我不明白你的问题,但如果我们谈论的是同一件事......

    在我的闪存中(它是用 AS2 编写的,因此您可能需要查看它在 AS3 中的不同之处,我注意到您没有使用 System 的安全类......他们可能已经删除了它),我有这个线...

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

    我很确定这只是从我的服务器的 docroot 中获取静态 crossdomain.xml。

    在服务器端,您的套接字代码(用什么编写的?)可以直接传递跨域策略。

    这是我的 Perl 套接字中响应闪存套接字初始请求的部分。我很久以前写过这个,但似乎套接字将这个微小的 xml 片段作为其初始通信发送到套接字“”,以响应您想要执行以下操作...

    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
    

    确保这确实是您需要的。有时您只需要让服务器将 crossdomain.xml 策略文件放在 docroot 中即可。

    【讨论】:

    • 但是我无法控制服务器端,它是IP摄像机本身的内部。
    • 啊。我现在明白了。我不得不查一下 IP Camera 是什么……以前从未听过这种说法。我认为处理这个问题的最简单方法是通过服务器创建一个中继并让您的 Flash 套接字连接到该中继。让它与不同套接字端口上的摄像机对话,所以... IP 摄像机 -> 服务器套接字 -> 闪存。服务器套接字不关心安全性,可以与摄像头对话,并可以为 Flash 提供所需的安全性。假设您的 IP 摄像机与您的计算机在同一网络上,您可以轻松地在其上运行套接字。
    • 很像USB摄像头,但可以通过url访问。
    猜你喜欢
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多