呵呵!临近毕业了,本人选择的毕业设计题目是(基于B/S模式的视频监控软件的设计与实现),对于这个题目,我打算用Flex+FMS(FlashMediaServer)进行开发,从今天起,本人会不定期的把一些成果拿出来与大家分享,有什么描述不妥的地方还请大家批评指正。

 

这次要解决的问题是FMS的视频流共享。问题的大概描述是:我们把被监控的一方叫做Server,对Flex熟悉的同学都知道,Flex中的<mx:VideoDisplay>+AS3.0中的Camera.getCamera()组合可以很容易的捕捉摄像头的视频数据并将其显示在<mx:VideoDisplay>中,但是这里有个问题,这里所谓的显示,只是基于本地机器,而捕捉摄像头的动作也只是捕捉本机的摄像头,我们要设计的视频监控软件是B/S模式,假如我们把编译好的swf文件放到WebAppServer下,用户远程访问,将看不到Server端的实时视频,这样至少从实时监控来说,就完全失去了意义!

 

解决思路:

创建两个文件,一个文件用来捕捉Server端的视频数据,并将其发布到FMS中,假设这段视频流名为wwww。

另一个文件用来显示给客户,其所起的作用就是播放Server端口发布到FMS的wwww视频流。

 

实现步骤:

1  在FMS_HOME/applications/下建立一个example文件夹,用来做本例的FMS工程实例。

2  编写<解决思路>中涉及的第一个文件server.mxml



Xml代码

转发监控视频流 监控视频分享_Flash



    1. <?xml version="1.0" encoding="utf-8"?>
    2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" height="571">
    3.     <mx:Script>  
    4. <![CDATA[ 
    5.             import mx.core.UIComponent; 
    6.             import .Microphone ; 
    7.             import mx.controls.Alert ; 
    8.             import flash.display.Graphics ; 
    9.             //测试网络可行性 
    10.             private var conne:NetConnection = new NetConnection() ; 
    11.             private function xianshi():void { 
    12.                 //必须  在AS3.0中默认的ObjectEncoding为AMF3,但是FMS不支持AMF3,所以 
    13.                 //要显示的声明为AMF0 
    14.                 conne.objectEncoding = ObjectEncoding.AMF0 ; 
    15.                 //FMS所在机器的IP地址 
    16.                 conne.connect("rtmp://172.30.209.75/example") ; 
    17.                 conne.addEventListener(NetStatusEvent.NET_STATUS,chuli) ; 
    18.             } 
    19.              
    20.             private var nnnns:NetStream = null ;//专门用来向连接到服务器的客户端提供共享视频流 
    21.             private var time:String = null ;//定义时间寄存器 
    22.             private function chuli(e:NetStatusEvent):void { 
    23.                 var result:String = e.info.code ; 
    24.                 switch(result) { 
    25.                     case "NetConnection.Connect.Success": 
    26.                     vd.attachCamera(Camera.getCamera()) ; 
    27.                     nnnns = new NetStream(conne) ; 
    28.                     nnnns.attachAudio(Microphone.getMicrophone()) ; 
    29.                     nnnns.attachCamera(Camera.getCamera()) ; 
    30.                     //播放server端的视频流 
    31.                     nnnns.publish("wwww","live") ; 
    32.                     break; 
    33.                     case "NetStream.Play.StreamNotFound": 
    34.                     Alert.show("失败") ; 
    35.                     break; 
    36.                     default : 
    37.                     Alert.show("缺省") ; 
    38.                     break ; 
    39.                 } 
    40.             } 
    41.             //停止播放 
    42.             private function tingzhi():void { 
    43.                 nnnns.close() ; 
    44.                 conne.close() ; 
    45.             } 
    46.              
    47.         ]]>
    48.     </mx:Script>  
    49.     <mx:VideoDisplay x="0" y="0" width="264" height="213" id="vd"/>
    50.        
    51.     <mx:Button label="连接服务器" click="xianshi()" x="10" y="247">
    52.     </mx:Button>  
    53.     <mx:Button click="tingzhi()" x="99" y="247" width="125" height="21" label="断开与服务器连接">
    54.            
    55.     </mx:Button>  
    56.     <mx:VideoDisplay x="285" y="11" width="276" height="202" id="vv"/>
    57. </mx:Application>


    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" height="571">
    	<mx:Script>
    		<![CDATA[
    			import mx.core.UIComponent;
    			import .Microphone ;
    			import mx.controls.Alert ;
    			import flash.display.Graphics ;
    			//测试网络可行性
    			private var conne:NetConnection = new NetConnection() ;
    			private function xianshi():void {
    				//必须  在AS3.0中默认的ObjectEncoding为AMF3,但是FMS不支持AMF3,所以
    				//要显示的声明为AMF0
    				conne.objectEncoding = ObjectEncoding.AMF0 ;
    				//FMS所在机器的IP地址
    				conne.connect("rtmp://172.30.209.75/example") ;
    				conne.addEventListener(NetStatusEvent.NET_STATUS,chuli) ;
    			}
    			
    			private var nnnns:NetStream = null ;//专门用来向连接到服务器的客户端提供共享视频流
    			private var time:String = null ;//定义时间寄存器
    			private function chuli(e:NetStatusEvent):void {
    				var result:String = e.info.code ;
    				switch(result) {
    					case "NetConnection.Connect.Success":
                        vd.attachCamera(Camera.getCamera()) ;
    					nnnns = new NetStream(conne) ;
    					nnnns.attachAudio(Microphone.getMicrophone()) ;
    					nnnns.attachCamera(Camera.getCamera()) ;
    					//播放server端的视频流
    					nnnns.publish("wwww","live") ;
                        break;
                        case "NetStream.Play.StreamNotFound":
                        Alert.show("失败") ;
                        break;
                        default :
                        Alert.show("缺省") ;
                        break ;
    				}
    			}
    			//停止播放
    			private function tingzhi():void {
    				nnnns.close() ;
    				conne.close() ;
    			}
    			
    		]]>
    	</mx:Script>
    	<mx:VideoDisplay x="0" y="0" width="264" height="213" id="vd"/>
    	
    	<mx:Button label="连接服务器" click="xianshi()" x="10" y="247">
    	</mx:Button>
    	<mx:Button click="tingzhi()" x="99" y="247" width="125" height="21" label="断开与服务器连接">
    		
    	</mx:Button>
    	<mx:VideoDisplay x="285" y="11" width="276" height="202" id="vv"/>
    </mx:Application>



     

    3  编写<解决思路>中涉及的第二个文件client.mxml,此文件显示给用户远程观看



    Xml代码

    转发监控视频流 监控视频分享_Flash



    1. <?xml version="1.0" encoding="utf-8"?>
    2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    3.     <mx:Script>  
    4. <![CDATA[ 
    5.             import mx.core.UIComponent; 
    6.             import .Microphone ; 
    7.             import mx.controls.Alert ; 
    8.             //测试网络可行性 
    9.             private var conne:NetConnection = new NetConnection() ; 
    10.             private function xianshi():void { 
    11.                 conne.objectEncoding = ObjectEncoding.AMF0 ; 
    12.                 conne.connect("rtmp://172.30.209.75/example") ; 
    13.                 //网络连接时间处理器 
    14.                 conne.addEventListener(NetStatusEvent.NET_STATUS,chuli) ; 
    15.             } 
    16.              
    17.             private var nnnns:NetStream = null ; 
    18.              
    19.             private function chuli(e:NetStatusEvent):void { 
    20.                 var result:String = e.info.code ; 
    21.                 switch(result) { 
    22.                     case "NetConnection.Connect.Success": 
    23.                     bofang() ; 
    24.                     break; 
    25.                     case "NetStream.Play.StreamNotFound": 
    26.                     Alert.show("失败") ; 
    27.                     break; 
    28.                     default : 
    29.                     Alert.show("缺省") ; 
    30.                     break ; 
    31.                 } 
    32.             } 
    33.              
    34.             private function tingzhi():void { 
    35.                 nnnns.close() ; 
    36.                 conne.close() ; 
    37.             } 
    38.             //网络连接成功时 播放server端发布到FMS的wwww视频流 
    39.             private function bofang():void { 
    40.                 nnnns = new NetStream(conne) ; 
    41.                 var v:Video = new Video() ; 
    42.                 v.attachNetStream(nnnns) ; 
    43.                 v.width = 276 ; 
    44.                 v.height = 202 ; 
    45.                 vv.addChild(v) ; 
    46.                 nnnns.play("wwww") ; 
    47.             } 
    48.         ]]>
    49.     </mx:Script>  
    50.     <mx:VideoDisplay x="0" y="0" width="264" height="213" id="vd"/>
    51.        
    52.     <mx:Button label="连接服务器" click="xianshi()" x="72" y="247">
    53.     </mx:Button>  
    54.     <mx:Button click="tingzhi()" x="190" y="247" width="123" height="21" label="断开与服务器连接">
    55.            
    56.     </mx:Button>  
    57.     <mx:VideoDisplay x="285" y="11" width="276" height="202" id="vv"/>
    58.        
    59. </mx:Application>



    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    	<mx:Script>
    		<![CDATA[
    			import mx.core.UIComponent;
    			import .Microphone ;
    			import mx.controls.Alert ;
    			//测试网络可行性
    			private var conne:NetConnection = new NetConnection() ;
    			private function xianshi():void {
    				conne.objectEncoding = ObjectEncoding.AMF0 ;
    				conne.connect("rtmp://172.30.209.75/example") ;
    				//网络连接时间处理器
    				conne.addEventListener(NetStatusEvent.NET_STATUS,chuli) ;
    			}
    			
    			private var nnnns:NetStream = null ;
    			
    			private function chuli(e:NetStatusEvent):void {
    				var result:String = e.info.code ;
    				switch(result) {
    					case "NetConnection.Connect.Success":
    					bofang() ;
                        break;
                        case "NetStream.Play.StreamNotFound":
                        Alert.show("失败") ;
                        break;
                        default :
                        Alert.show("缺省") ;
                        break ;
    				}
    			}
    			
    			private function tingzhi():void {
    				nnnns.close() ;
    				conne.close() ;
    			}
    			//网络连接成功时 播放server端发布到FMS的wwww视频流
    			private function bofang():void {
    				nnnns = new NetStream(conne) ;
    				var v:Video = new Video() ;
    				v.attachNetStream(nnnns) ;
    				v.width = 276 ;
    				v.height = 202 ;
    				vv.addChild(v) ;
    				nnnns.play("wwww") ;
    			}
    		]]>
    	</mx:Script>
    	<mx:VideoDisplay x="0" y="0" width="264" height="213" id="vd"/>
    	
    	<mx:Button label="连接服务器" click="xianshi()" x="72" y="247">
    	</mx:Button>
    	<mx:Button click="tingzhi()" x="190" y="247" width="123" height="21" label="断开与服务器连接">
    		
    	</mx:Button>
    	<mx:VideoDisplay x="285" y="11" width="276" height="202" id="vv"/>
    	
    </mx:Application>



     

     

    4  启动FMS,打开编译好的server.swf,先点击按钮:连接服务器

     

    5  把编译好的client.swf拷贝到任何客户端,然后点击按钮:连接服务器,即可以看到server端传送过来的视频流。

    如果想要部署swf文件到WebApplication下,可以把FlexBuilder工程目录下的server.html和client.html拷贝到相应的目录,然后通过URL访问。

     

    好了,关于FMS视频流共享的问题到此为止,各位有何疑问,不妨留言一起探讨!下一次我将解决怎样在不切断server端输出流的情况下进行视频录像。