呵呵!临近毕业了,本人选择的毕业设计题目是(基于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
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,此文件显示给用户远程观看
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端输出流的情况下进行视频录像。

















