flex4+fms3.5+cs4开发实时音视频直播及点播详解

开发工具及环境:

1)flash builder4

2)flash cs4

3)flash media server3.5

fms部分

fms是adobe的流媒体服务器,不过是收费的,价格大概是oracle的一半,不过还是觉得挺贵的。adobe提供控制连接数的开发人员版,除了这点具体和完全版一样。服务器的配置网上很多,大家一搜就一大把。

其中关键的是:

由于需求是不仅要提供直播,而且还能点播历史音视频。而as的NetStream的publish方法提供的录制功能是将录制的视频放在直播的同一个文件夹下,所以要需要改一下fms配置。

1)fms的dvr默认是关闭的,需要修改C:/Program Files/Adobe/Flash Media Server 3.5/applications/live/main.far里的Application.xml,将文件中的
<StreamManager>
<StreamRecord override="no">false</StreamRecord>
</StreamManager>

改为
<StreamManager>
<StreamRecord override="yes">true</StreamRecord>
</StreamManager>

修改后重新加入main.far中

2)fms默认是将直播与点播文件目录分开的(live和vod),但是视频录制是在live文件加下,所以我们要修改点播目录

C:/Program Files/Adobe/Flash Media Server 3.5/conf/fms.ini文件中将
VOD_DIR 设置为 C:/Program Files/Adobe/Flash Media Server 3.5/applications/live
这样就可以实现直播点播同文件夹共存了

3)配置虚拟目录

打开C:/Program Files/Adobe/Flash Media Server 3.5/applications/live/Application.xml在<VirtualDirectory>中加入
<Streams>/;${VOD_COMMON_DIR}</Streams>
<Streams>/;${VOD_DIR}</Streams>

补充:如果在flex中直播视频时抛出noAccess错误,请在服务器上给录制机分配写入的权限。
通过以上配置fms就完成了

 

flex部分

<?xml version="1.0" encoding="utf-8"?> 
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"   
                       xmlns:s="library://ns.adobe.com/flex/spark"   
                       xmlns:mx="library://ns.adobe.com/flex/mx" width="430" height="340"   
                       creationComplete="init_creationCompleteHandler(event)"   
                       closing="unonload()"> 
    <s:layout> 
        <s:BasicLayout/> 
    </s:layout> 
    <fx:Style source="media.css"/> 
 
    <fx:Script> 
        <!--[CDATA[  
            import flash.events.NetStatusEvent;  
            import flash.net.NetConnection;  
            import flash.net.NetStream;  
              
            import mx.collections.ArrayCollection;  
            import mx.controls.Alert;  
            import mx.controls.Text;  
            import mx.events.FlexEvent;  
              
            private var nc:NetConnection;     
            private var ns:NetStream;     
            private var vi:Video;  
            private var cam:Camera;     
            private var microphone:Microphone;  
            private var fmsArr:ArrayCollection=new ArrayCollection([]);  
            private var sharedObject:SharedObject=SharedObject.getLocal("com.ue");   
              
            /**  
             * 初始化  
             */  
            protected function init_creationCompleteHandler(event:FlexEvent):void{  
                var loader:URLLoader = new URLLoader();  
                loader.dataFormat=URLLoaderDataFormat.VARIABLES;  
                loader.addEventListener(Event.COMPLETE, loader_complete);  
                loader.load(new URLRequest("global.txt"));  
                  
                function loader_complete(e:Event):void {  
                    var variables:URLVariables=new URLVariables(loader.data);                 
                    trace(variables["servers"]);  
                                          
                    var serversArr:Array = variables["servers"].toString().split("@#@");  
                    for(var i:int=0;i<serversArr.length;i++){  
                        var server:String = serversArr[i];  
                        var sArr:Array = server.toString().split("$#$");  
                          
                        fmsArr.addItem({label:sArr[0], value:sArr[1]});  
                    }  
                }  
                  
                getCookie();  
            }  
              
            public function getCookie():void{  
                if(sharedObject.data["pmhidh"]!=null){  
                    pmhID.text = sharedObject.data["pmhidh"];  
                }  
                if(sharedObject.data["spfwq"]!=null){  
                    trace(sharedObject.data["spfwq"]);  
                    fms.selectedItem = sharedObject.data["spfwq"];  
                }  
                if(sharedObject.data["yl"]!=null){  
                    slider.value = sharedObject.data["yl"];  
                }  
                  
            }  
              
            /**  
             * 开始直播  
             */  
            protected function startButton_clickHandler(event:MouseEvent):void{  
                  
                startButton.enabled=false;  
                stopButton.enabled=true;  
                nc = new NetConnection();     
                nc.addEventListener(NetStatusEvent.NET_STATUS,connectServerHander);     
                nc.client  = this;  
                  
                trace(fms.selectedItem.label);  
                nc.connect(fms.selectedItem.value);    
                  
                slider.enabled=true;  
            }             
            /**  
             * 回调函数  
             */  
            public function connectServerHander(evt:NetStatusEvent):void{  
                cam = Camera.getCamera();     
                microphone = Microphone.getMicrophone();  
                  
                if(microphone!=null){  
                    microphone.setSilenceLevel(0);//总是收集音频  
                    microphone.rate=44;  
                }else{  
                    Alert.show("无法链接到麦克风!");   
                }  
                  
                if(cam != null){     
                    cam.setMode(176,144,25);     
                    cam.setQuality(0,90);     
                    ns = new NetStream(nc);      
                    ns.attachCamera(cam);     
                    ns.attachAudio(microphone);  
                    ns.publish(pmhID.text,"append");     
                      
                    vi = new Video();     
                    vi.width = player.width;     
                    vi.height = player.height;     
                    vi.attachCamera(cam);     
                    player.addChild(vi);     
                                          
                }else{     
                    Alert.show("无法链接到摄像头!");     
                }     
            }  
            /**  
             * NetConnection回调函数  
             */  
            public function onBWDone():void{}   
              
              
            /**  
             * 保存音视频文件  
             */       
//          protected function browse_clickHandler(event:MouseEvent):void{  
//              var file:File = new File();   
//              file.addEventListener(Event.SELECT,dirSelected);   
//              file.browseForSave("另存为");   
//              function dirSelected(e:Event):void {   
//                  trace(file.nativePath);   
//                  filefilePath.text = file.nativePath;  
//              }   
//          }  
 
            /**  
             * 音量控制  
             */  
            protected function slider_changeHandler(event:Event):void{  
                microphone.gain = slider.value;  
            }  
 
 
            /**  
             * 停止发布  
             */  
            protected function stopButton_clickHandler(event:MouseEvent):void{  
                ns.close();  
                vi.visible=false;  
                startButton.enabled=true;  
                stopButton.enabled=false;  
            }  
              
            /**  
             * 关闭窗口触发事件,保存配置  
             */  
            public function unonload():void{  
                if(sharedObject!=null){   
                    sharedObject.clear();   
                }   
                if(sharedObject.data["pmhidh"]==null){  
                    sharedObject.data["pmhidh"] = pmhID.text;  
                }  
                if(sharedObject.data["spfwq"]==null){  
                    sharedObject.data["spfwq"] = fms.selectedItem;  
                }  
                if(sharedObject.data["yl"]==null){  
                    sharedObject.data["yl"] = slider.value;  
                }     
                sharedObject.flush();  
            }  
 
        ]]--> 
    </fx:Script> 
 
    <fx:Declarations> 
        <!-- 将非可视元素(例如服务、值对象)放在此处 --> 
    </fx:Declarations> 
    <s:Panel width="100%" height="100%" x="0" y="0" id="panel1"> 
        <s:layout> 
            <s:VerticalLayout paddingLeft="0" paddingRight="0" paddingBottom="0" paddingTop="0" requestedRowCount="7"/> 
        </s:layout> 
        <s:VGroup width="430" height="272" paddingTop="10" paddingBottom="0" paddingRight="0" paddingLeft="0"> 
            <s:HGroup width="430" height="220" paddingLeft="5" paddingTop="2" paddingBottom="0" paddingRight="5"> 
                <s:BorderContainer width="206" height="215"> 
                    <s:VideoDisplay width="193" height="202" scaleMode="letterbox" id="player" x="5" y="5"/> 
                </s:BorderContainer> 
                <s:BorderContainer width="206" height="215"> 
                    <s:VGroup width="193" height="208" paddingLeft="5" paddingTop="0" paddingBottom="0"   
 
paddingRight="5" gap="9" x="5" y="5"> 
                        <s:Label text="拍卖会ID号:" height="14" id="pmhIDLabel"/> 
                        <s:TextInput id="pmhID"/> 
                        <s:Label text="视频服务器:" height="14"/> 
                        <s:ComboBox id="fms" dataProvider="{fmsArr}"/> 
                        <s:Label text="音量" height="14"/> 
                        <s:HSlider id="slider" enabled="false" change="slider_changeHandler(event)" minimum="0"   
 
maximum="100" stepSize="10"/> 
                    </s:VGroup> 
                </s:BorderContainer> 
            </s:HGroup> 
            <s:HGroup width="430" height="35" paddingTop="0" paddingBottom="0" paddingRight="5" paddingLeft="145"   
 
verticalAlign="middle" textAlign="center"> 
                <s:Button id="startButton" label="开始发布" click="startButton_clickHandler(event)"/> 
                <s:Button label="停止发布" id="stopButton" enabled="false" click="stopButton_clickHandler(event)"/> 
            </s:HGroup> 
        </s:VGroup> 
    </s:Panel> 
</s:WindowedApplication> 

效果如下:

flash部分/点播代码

import flash.net.*;  
import flash.events.*;  
 
var loader:URLLoader = new URLLoader();  
loader.dataFormat=URLLoaderDataFormat.VARIABLES;  
loader.addEventListener(Event.COMPLETE, loader_complete);  
loader.load(new URLRequest("media2.txt"));  
 
function loader_complete(e:Event):void {  
    var variables:URLVariables=new URLVariables(loader.data);  
 
    myVideo2.source=variables["source"];  
}  
myVideo2.isLive=false; 

效果如下:

flash部分/直播代码

import flash.net.*;  
import flash.events.*;  
 
var loader:URLLoader = new URLLoader();  
loader.dataFormat=URLLoaderDataFormat.VARIABLES;  
loader.addEventListener(Event.COMPLETE, loader_complete);  
loader.load(new URLRequest("media.txt"));  
 
function loader_complete(e:Event):void {  
    var variables:URLVariables=new URLVariables(loader.data);  
 
    myVideo.source=variables["source"];  
}  
 
myVideo.isLive=true; 

效果如下:

posted @ 2015-10-08 07:49  coolsundy  阅读(593)  评论(0编辑  收藏  举报