2010-10-03 37 views
1

到目前爲止,我找到了解決辦法需要一個crossdomain.xml工作,但這不是一個可用的IP攝像機:如何通過actionscript呈現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); 
     } 

    } 

} 

回答

0

也許我不理解你的問題,但如果我們在談論同樣的事情...在我的閃存(這是用AS2寫的,所以你可能需要查看它在AS3中的不同,我注意到你沒有使用系統的安全類...他們可能已經刪除了) ,我有這條線...

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

我很確定這只是從我的服務器的docroot中提取靜態crossdomain.xml。

在服務器端,您的套接字代碼(用什麼寫的?)可以直接提供跨域策略。

下面是我的Perl套接字中的一部分,它響應Flash套接字的初始請求。我很久以前寫過這篇文章,但是看起來套接字將這個微小的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中。

+0

但我沒有控制服務器端,它是IP攝像機本身的內部。 – ollydbg 2010-10-03 07:36:03

+0

啊。我現在明白了。我不得不查看一臺IP攝像機是什麼......從來沒有聽過這種表達。我認爲處理這個最簡單的方法是通過服務器創建一箇中繼,並讓你的Flash套接字連接到該套接字。讓我們談談在不同的套接字端口上的攝像頭,所以... IP攝像頭 - >服務器套接字 - > Flash。服務器套接字不關心安全性,可以與相機通話,並且可以爲Flash提供所需的安全性。假設您的IP攝像機與您的計算機位於同一網絡上,您可以輕鬆地在其上運行該套接字。 – 2010-10-03 07:37:46

+0

非常像USB攝像頭,但可以通過URL訪問。 – ollydbg 2010-10-03 07:41:30

相關問題