2010-06-17

使用 Adobe AIR 建立 RTMP Proxy

在此使用 Adobe AIR 建立 RTMP Proxy 的目的是去查看 RTMP 傳送的內容。雖然 Adobe 已經釋出 RTMP Specification,但是在 Flash Player 10.0.32.18 後還是有變動()。
注意事項:
A) Fla 檔記得使用 Flash CS5 開 AIR 2。
B) 在桌面建立個空的 rtmp_proxy 目錄,用來存放執行時的資料存檔。
C) 在 Flash Media Server,開個名為「test」的 Application,並啟動 Server。
D) 先執行 RTMPProxy 再執行 VideoTest,
E) 跑一下子就關掉 VideoTest,否則檔案會越來越多,硬碟可能會爆。

以下是 兩個 Document Classes 的內容,Fla 就不附了:

RTMPProxy.as
package {
 import flash.display.MovieClip;
 import fl.controls.TextArea;
 import flash.net.ServerSocket;
 import flash.net.Socket;
 import flash.events.ServerSocketConnectEvent;
 import flash.events.ProgressEvent;
 import flash.utils.ByteArray;
 import flash.events.Event;
 import flash.filesystem.File;
 import flash.filesystem.FileStream;
 import flash.filesystem.FileMode;
 import flash.utils.getTimer;

 public class RTMPProxy extends MovieClip {
  public var info_txt:TextArea;
  private var server:ServerSocket;
  private var forClient:Socket;
  private var forServer:Socket;
  private var file:File;
  private var fileStream:FileStream;
  private var count:int;

  public function RTMPProxy() {
   info_txt.text = "";
   server = new ServerSocket();
   server.addEventListener(ServerSocketConnectEvent.CONNECT, connectHandler);
   server.bind( 1936 );
   server.listen();
  }

  private function connectHandler(event:ServerSocketConnectEvent):void {
   forClient = event.socket;
   forClient.addEventListener(ProgressEvent.SOCKET_DATA, clientDataHandler);
   forClient.addEventListener(Event.CLOSE, closeHandler);
   forServer = new Socket('localhost',1935);
   forServer.addEventListener(ProgressEvent.SOCKET_DATA, serverDataHandler);
  }

  private function clientDataHandler(event:ProgressEvent):void {
   count++;
   var ba:ByteArray = new ByteArray();
   forClient.readBytes( ba );
   forServer.writeBytes( ba );

   file = File.desktopDirectory.resolvePath("rtmp_proxy/proxy_" + count + "_c.data");
   fileStream = new FileStream();
   fileStream.open(file, FileMode.WRITE);
   fileStream.writeBytes( ba );
   fileStream.close();
   info_txt.appendText("\n proxy_client:"+ba.length );
   forServer.flush();
  }

  private function serverDataHandler(event:ProgressEvent):void {
   count++;
   var ba:ByteArray = new ByteArray();
   forServer.readBytes( ba );
   forClient.writeBytes( ba );

   file = File.desktopDirectory.resolvePath("rtmp_proxy/proxy_" + count + "_s.data");
   fileStream = new FileStream();
   fileStream.open(file, FileMode.WRITE);
   fileStream.writeBytes( ba );
   fileStream.close();
   info_txt.appendText("\n proxy_server:"+ba.length );
   forClient.flush();
  }

  private function closeHandler(event:Event):void {
   info_txt.appendText("\n client_close" );
   forServer.close();
  }
 }
}
VideoTest.as (客戶端)
package {
 import flash.display.MovieClip;
 import flash.media.Video;
 import flash.media.Camera;
 import flash.net.NetConnection;
 import flash.net.NetStream;
 import flash.display.SimpleButton;
 import flash.events.MouseEvent;
 import flash.events.NetStatusEvent;
 import flash.events.Event;
 import flash.events.AsyncErrorEvent;
 import flash.events.IOErrorEvent;
 import flash.events.SecurityErrorEvent;
 import com.adobe.serialization.json.JSON;

 public class VideoTest extends MovieClip {
  public var video:Video;
  public var camera:Camera;
  public var btn:SimpleButton;
  private var connection:NetConnection;
  private var stream:NetStream;

  public function VideoTest() {
   connection = new NetConnection();
   connection.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);
   connection.connect("rtmp://localhost:1936/test/");

   video = new Video();
   camera = Camera.getCamera();
   video.width = camera.width;
   video.height = camera.height;
   this.addChild( video );
   video.attachCamera( camera );
   btn.addEventListener(MouseEvent.CLICK, clickHandler);
  }

  private function clickHandler(event:MouseEvent):void {
   stream = new NetStream(connection);
   stream.attachCamera( camera );
   stream.publish("lin");
  }

  private function statusHandler(event:Event):void {
   trace( event.toString() );
   trace( JSON.encode( event['info'] ) );
   trace('connection.connected:'+connection.connected);
  }
 }
}

沒有留言:

FB 留言