fms里cs的一个例子

    技术2022-05-11  48

    idPool = ["guest_1", "guest_2", "guest_3", "guest_4"];//数组,当堆栈用.全局的 application.onAppStart = function(){    users_so = SharedObject.get("users");//获取本地共享对象users.注意,这是在服务端.不需要远程,而是本地 } application.onConnect = function(client, name){//client为带协议的地址串的连接表示,name为输入的参数    if (idPool.length <= 0){//如果对象池满       application.rejectConnection(client, {msg:"Too many users."});//拒绝连接请求,给出信息,指明原因    }    client.id = idPool.pop();//从堆栈顶部弹出一个.并且给client多安个id属性。现在client有id属性了,后面可以使用了    application.acceptConnection(client);//接受连接请求    client.call("setID", null, client.id);//调用client的setID,给client发消息,将id传过去,null说明没有指定返回信息处理器    users_so.setProperty(client.id, name); //将id:name值对保存到共享对象里。注意,这是服务器端 } application.onDisconnect = function(client){    idPool.push(client.id);//将要回收的id压回堆栈    users_so.setProperty(client.id, null); //在共享对象里,将与id对应的值对设置为空,即删除。 } myID = ""; //每个客户端都有一个id,表示自己,独一无二 nc = new NetConnection(); //连接对象。全局使用 /**  * setID is a remote method that will be called by the server  * after the client connects. Once we get our unique ID from the  * server we can use it to publish our stream.  */ nc.setID = function(id){ //setID方法,绑到连接上.如此,服务端就可以用client调用,给客户端发送消息了.这里,发送了id信息     myID = id; //事实上,"我"的id是服务器分配的.     statusInput.text = "Online. Your client's ID is: " + myID;//在状态栏显示在线信息及id     ns = new NetStream(nc);//建立流     ns.attachAudio(Microphone.get());//将流管道接到麦克音频源上     var cam = Camera.get();//打开摄像头     ns.attachVideo(cam);//将同一管道流接到摄像头上.这样,音频视频都接到同一管道上了.也可以使用上面接麦克的写法,一个         //语句即可.因为下面还要用到,所以把引用拿出来了.     ns.publish(id);//发布id信息     _root[id].video.attachVideo(cam);//将摄像头同时连到自己的视频播放窗口.就能自拍了.同时有4个剪辑对象(被拖到)在舞台         //上,形成数组.每个剪辑里有嵌入式视频与文本输入框.现在要访问剪辑里的视频对象,使用这种方式.video是剪辑里视频对象     init();//开始初始化工作 }//这个方法在客户端执行,因此可以使用客户端的资源,如麦克和摄像头等.它被服务端调用,因此又可得到(传递)消息. /**  * onStatus is called whenever the status of the network  * connection changes. It is how we know if we are connected  * or not.  */ nc.onStatus = function(info){//状态事件处理器.一旦网络连接状态改变,就调用它.诸如连接成功,失败等.info是服务器返回的    connectButton.label = "Connect";    connectButton.enabled = true;    switch(info.code){        case "NetConnection.Connect.Success":// 成功状态           connectButton.label = "Disconnect";//标签改为"断开"           statusInput.text = "Online";//标识"在线"                  break;        case "NetConnection.Connect.Failed": //失败状态           statusInput.text = "Cannot reach server. Possible network error.";        break;        case "NetConnection.Connect.Rejected"://连接拒绝            statusInput.text = info.application.msg;//显示原因        break;        case "NetConnection.Connect.Closed"://连接关闭            statusInput.text += " Connection closed.";        break;    } } connectButton.addEventListener("click", this);//给按钮注册事件监听器.this代表谁? /**  * click() is called when the connectButton is pressed.  * Depending on the label of the button either a  * connection is attempted or the current connection is  * closed.  */ function click(ev){//点击事件处理器.传入事件对象     var button = ev.target;//取事件源     var command = button.label;//取按钮的文字标签     switch(command){         case "Connect"://连接命令            nc.connect("rtmp:/helloVideo", userNameInput.text);//连接,到服务端应用,传递用户名            button.label = "Wait...";            button.enabled = false;//按钮不可用         break;         case "Disconnect"://断开            nc.close();//关闭连接            button.label = "Connect";         break;     } } /**  * init() is called after the server calls the setID method  * It initializes the shared users object and then connects it.  */ function init(){//服务端调用setID后,执行本初始化函数     users_so = SharedObject.getRemote("users", nc.uri);//获取远程共享对象,到uri,连接到users上     users_so.onSync = function(infoList){//共享对象同步事件处理器.共享对象里发生任何状态变化,都执行.信息列表里有具体信息         for (var i in infoList){//逐条检测信息列表             var info = infoList[i];//一条信息             switch(info.code){//检测信息码                 case "change": //数据改变                    var id = info.name;//取出名字,为id.name是信息的一个属性吗?规范在哪里?                    var mc = _root[id];//找对应的剪辑对象                    mc.nameInput.text = users_so.data[id];//还记得存入共享对象里的值对吗?现在按名字把值取出来.剪辑将它显示出来                    if (myID != id){//判断数据变化的id与播放窗口是不是同一个。                        var ns = new NetStream(nc);//建立管道流                        mc.video.attachVideo(ns);//连到剪辑的播放窗口里                        ns.play(id);//播放流, guest_1,                        mc.ns = ns;//mc有ns属性吗?这里是新加的,还是已有的?在什么时候用到?还是已经用到了?                    }//事实上,有4个窗口对象,只有一个是自己的,其余3个id都不一样.这样,就给3个窗口分别连到自己的流了.关键是                         //每个窗口播放自己的流. 当然了,前提是数据流要变化.数据不变化,就不需要播放,因为没数据嘛                 break;                 case "delete"://有人离开了,就删除之                    var id = info.name; //这个人离开了                    var mc = _root[id];//取它的剪辑                    mc.ns.close();//将剪辑里的流关闭.上面新加的属性,这里用上了                    mc.nameInput.text = "";                    mc.video.clear();//视频窗口处理                 break;             }         }//上面,info只有两个属性出现过:info.code和info.name.进一步查资料     }     users_so.connect(nc);    //共享对象连接. 注意:1)连接放在同步处理后面;2)有连接,就有状态变化,这都是服务端调用的 }  

    最新回复(0)