李勇

1.视频模块增加推流播流接口的逻辑判断;

2.用户退出会议的时候,如果当前自己正在推流,需要停止推流并且同步数据
@@ -41,6 +41,7 @@ let _joinClassSuccessCallBackFun; @@ -41,6 +41,7 @@ let _joinClassSuccessCallBackFun;
41 //监听mcu所有错误异常回调函数 41 //监听mcu所有错误异常回调函数
42 let _mcuErrorCallBackFun; 42 let _mcuErrorCallBackFun;
43 43
  44 +let leaveDelay;
44 45
45 //MCUClient 外部实例化主类 46 //MCUClient 外部实例化主类
46 export default class MessageEntrance extends Emiter { 47 export default class MessageEntrance extends Emiter {
@@ -311,6 +312,14 @@ export default class MessageEntrance extends Emiter { @@ -311,6 +312,14 @@ export default class MessageEntrance extends Emiter {
311 GlobalConfig.MCUServerPort = server.split(":")[1]; 312 GlobalConfig.MCUServerPort = server.split(":")[1];
312 } 313 }
313 314
  315 + //视频推流播流地址
  316 + if (_data.ms) {
  317 + //MS地址默认使用第一个
  318 + let server = _data.ms.split(";")[0];
  319 + GlobalConfig.MSServerIP = server.split(":")[0];
  320 + GlobalConfig.MSServerPort = server.split(":")[1];
  321 + }
  322 +
314 GlobalConfig.docServer = _data.doc; 323 GlobalConfig.docServer = _data.doc;
315 GlobalConfig.h5_mcu_list = _data.h5_mcu_list; 324 GlobalConfig.h5_mcu_list = _data.h5_mcu_list;
316 GlobalConfig.h5Module = _data.h5Module; 325 GlobalConfig.h5Module = _data.h5Module;
@@ -606,6 +615,9 @@ export default class MessageEntrance extends Emiter { @@ -606,6 +615,9 @@ export default class MessageEntrance extends Emiter {
606 } 615 }
607 // 离开会议 616 // 离开会议
608 _leaveClass() { 617 _leaveClass() {
  618 + if(_video_ape){
  619 + _video_ape.stopPublishVideo();
  620 + }
609 if(_confer_ape){ 621 if(_confer_ape){
610 _confer_ape.leaveClass(); 622 _confer_ape.leaveClass();
611 } 623 }
@@ -637,7 +649,7 @@ export default class MessageEntrance extends Emiter { @@ -637,7 +649,7 @@ export default class MessageEntrance extends Emiter {
637 649
638 sendVideoCommandMsg(_param){ 650 sendVideoCommandMsg(_param){
639 if(_video_ape){ 651 if(_video_ape){
640 - _video_ape.sendVideoCommandMsg(_param); 652 + return _video_ape.sendVideoCommandMsg(_param);
641 } 653 }
642 } 654 }
643 655
@@ -141,7 +141,9 @@ class EverSocket extends Emiter { @@ -141,7 +141,9 @@ class EverSocket extends Emiter {
141 if (this._lastActiveTime && 141 if (this._lastActiveTime &&
142 this._lastActiveTime >= pongTime - EverSocket.PONG_INTERVAL && 142 this._lastActiveTime >= pongTime - EverSocket.PONG_INTERVAL &&
143 this._lastActiveTime <= pongTime 143 this._lastActiveTime <= pongTime
144 - ) {} else { 144 + ) {
  145 +
  146 + } else {
145 loger.warn('---服务器PINGPONG超时-----'); 147 loger.warn('---服务器PINGPONG超时-----');
146 this._reConnection(); 148 this._reConnection();
147 } 149 }
@@ -244,7 +244,7 @@ GlobalConfig.statusCode_3={"code":3,message:"已经离开会议"}; @@ -244,7 +244,7 @@ GlobalConfig.statusCode_3={"code":3,message:"已经离开会议"};
244 GlobalConfig.statusCode_4={"code":4,message:"未知状态"}; 244 GlobalConfig.statusCode_4={"code":4,message:"未知状态"};
245 245
246 GlobalConfig.md5=""; 246 GlobalConfig.md5="";
247 -GlobalConfig.msType=1; 247 +GlobalConfig.msType=1;//目前固定用这个
248 GlobalConfig.mcuDelay=3000;//默认的延迟时间 248 GlobalConfig.mcuDelay=3000;//默认的延迟时间
249 GlobalConfig.docDelay=1600;//文档模块加入成功之后延迟发送送成功的消息给主模块 249 GlobalConfig.docDelay=1600;//文档模块加入成功之后延迟发送送成功的消息给主模块
250 GlobalConfig.portal="112.126.80.182:80"; 250 GlobalConfig.portal="112.126.80.182:80";
@@ -253,6 +253,10 @@ GlobalConfig.port="80"; @@ -253,6 +253,10 @@ GlobalConfig.port="80";
253 GlobalConfig.MCUServerIP="114.215.195.70"; 253 GlobalConfig.MCUServerIP="114.215.195.70";
254 GlobalConfig.docServer="";//当前的文档地址加载的服务器地址 254 GlobalConfig.docServer="";//当前的文档地址加载的服务器地址
255 GlobalConfig.MCUServerPort=9003; 255 GlobalConfig.MCUServerPort=9003;
  256 +
  257 +GlobalConfig.MSServerIP = "";//推流 播流的地址
  258 +GlobalConfig.MSServerPort ="";
  259 +
256 GlobalConfig.maxVideoChannels=0; 260 GlobalConfig.maxVideoChannels=0;
257 GlobalConfig.maxAudioChannels=0; 261 GlobalConfig.maxAudioChannels=0;
258 GlobalConfig.maxMediaChannels=0; 262 GlobalConfig.maxMediaChannels=0;
@@ -29,8 +29,6 @@ class VideoChat extends Ape { @@ -29,8 +29,6 @@ class VideoChat extends Ape {
29 ApeConsts.VIDEO_SESSION_ID, 29 ApeConsts.VIDEO_SESSION_ID,
30 ApeConsts.VIDEO_SESSION_NAME, 30 ApeConsts.VIDEO_SESSION_NAME,
31 ApeConsts.VIDEO_SESSION_TAG 31 ApeConsts.VIDEO_SESSION_TAG
32 -  
33 -  
34 ); 32 );
35 33
36 //Attributes 34 //Attributes
@@ -41,149 +39,120 @@ class VideoChat extends Ape { @@ -41,149 +39,120 @@ class VideoChat extends Ape {
41 this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer); 39 this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer);
42 40
43 // videoApe 监听视频控制消息,用户之间的消息传递 41 // videoApe 监听视频控制消息,用户之间的消息传递
44 - this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.videoCommandHandler.bind(this)); 42 + this.on(pdu.RCPDU_VIDEO_SEND_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this));
45 } 43 }
46 - /////////////发送数据操作////////////////////////////////////////////////////// 44 +
  45 + /////////////发送数据操作////////////////////////////////////////////
47 //获取播流地址 46 //获取播流地址
48 - getPlayVideoPath(_param){ 47 + getPlayVideoPath(_param) {
49 loger.log('getPlayVideoPath'); 48 loger.log('getPlayVideoPath');
50 - return {"code":0,"data":"播放流地址XXXXXXXXXXXXXXXXXXXXX"}; 49 + if (_param == null||_param.classId == null||_param.channelId == null|| _param.timestamp==null) {
  50 + loger.warn('getPlayVideoPath,参数错误', _param);
  51 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  52 + return {"code": 1, "data": "getPlayVideoPath,参数错误"};
  53 + }
  54 + let path = "";
  55 + if (_param.type == "m3u8") {
  56 + path = "http://" + GlobalConfig.MSServerIP + ":80" + "/hls/" + _param.classId + "_" + _param.channelId + "_" + _param.timestamp + ".m3u8";
  57 + } else {
  58 + let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort;
  59 + path = "rtmp://" + GlobalConfig.MSServerIP + port + "/live/" + _param.classId + "_" + _param.channelId + "_" + _param.timestamp;
  60 + }
  61 + return {"code": 0, "data": path};
51 } 62 }
  63 +
52 //获取推流地址 64 //获取推流地址
53 - getPublishVideoPath(_param){ 65 + getPublishVideoPath(_param) {
54 loger.log('getPublishVideoPath'); 66 loger.log('getPublishVideoPath');
  67 + //if(_param==null){
  68 + // loger.warn('getPublishVideoPath,参数错误',_param);
  69 + // this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  70 + // return {"code":1,"data":"getPublishVideoPath,参数错误"};;
  71 + //}
55 //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启 72 //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
  73 + let freeChannel = this.getFreeVideoChannel();
  74 + if (freeChannel == 0) {
  75 + return {"code": 1, "data": "不能再打开更多的设备"};
  76 + }
56 77
57 - return {"code":0,"data":"推流地址XXXXXXXXXXXXXXXXXXXXXXX"}; 78 + let port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "" : ":" + GlobalConfig.MSServerPort;
  79 + let timestamp = EngineUtils.creatTimestamp();
  80 + let publishUrl = "rtmp://" + GlobalConfig.MSServerIP + port + "/live/" + GlobalConfig.classId + "_" + freeChannel + "_" + timestamp;
  81 + return {"code": 0, "data": {"channelId": freeChannel, "timestamp": timestamp, "publishUrl": publishUrl}};
58 } 82 }
59 83
60 //推流 84 //推流
61 - publishVideo(_param){  
62 - loger.log('publishVideo -> maxVideoChannels',GlobalConfig.maxVideoChannels);  
63 - this.sendTableUpdateHandler();  
64 - /* protected function startPushMessageFlash():void  
65 - {  
66 - if((!Config.enableCDNServer && !Config.isH5Moudle) ||  
67 - Config.customer == Config.customerTaobao ||  
68 - Config.msType == Config.MS_TYPE_FMS  
69 - )  
70 - return;  
71 -  
72 - var obj:Object = new Object;  
73 - obj.confID = Config.confID;  
74 - obj.streamType = RCNetStream.PRT_CAM_SOUND_FLASH;  
75 - obj.uriPush = "rtmp://" + Config.liveServerAddr + ":" + Config.liveServerPort + "/3m/" + streamName;  
76 - _streamPublished.send("startPush", obj);  
77 - log.info("startPushMessageFlash,startPush streamType:" + obj.streamType);  
78 - }*/ 85 + publishVideo(_param) {
  86 + loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
79 87
80 -/* var rtmpUrl:String = "";  
81 - if(Config.msType == Config.MS_TYPE_DEFAULT)  
82 - {  
83 - rtmpUrl = "rtmp://" + mediaServerAddr + ":" + mediaServerPort;  
84 - }  
85 - else if(Config.msType == Config.MS_TYPE_FMS)//fms下链接地址 pzm+ 2016.4.12  
86 - {  
87 - if(Config.clientType == Config.CT_RECORDPLAYER)  
88 - {  
89 - rtmpUrl = "rtmp://" + mediaServerAddr + ":" + mediaServerPort + "/vod"; 88 + //同一个nodeId只允许推一个流,如果已经推了就不能再推
  89 + if(this.getOpeningVideoChannel(GlobalConfig.nodeId)!=0){
  90 + loger.warn("publishVideo,已经存在一个流,不能再推");
  91 + return;
90 } 92 }
91 - else  
92 - {  
93 - rtmpUrl = "rtmp://" + mediaServerAddr + ":" + mediaServerPort + "/live/" + Config.confID; 93 +
  94 + let freeChannel = this.getFreeVideoChannel();
  95 + if (freeChannel == 0) {
  96 + loger.warn("publishVideo,没有空闲的channel ");
  97 + return {"code": 1, "data": "不能再打开更多的设备"};
94 } 98 }
95 - }*/ 99 + let channelInfo={};
  100 + channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
  101 + channelInfo.fromNodeId=GlobalConfig.nodeId;
  102 + channelInfo.channelId=freeChannel;
  103 + channelInfo.timestamp=EngineUtils.creatTimestamp();
  104 + channelInfo.classId=GlobalConfig.classId;
  105 + channelInfo.toNodeId=0;
  106 + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;
  107 + this.sendTableUpdateHandler(channelInfo);
96 } 108 }
  109 +
97 //停止推流 110 //停止推流
98 - stopPublishVideo(_param){  
99 - loger.log('stopPublishVideo -> maxVideoChannels',GlobalConfig.maxVideoChannels);  
100 - this.sendTableUpdateHandler();  
101 - }  
102 -  
103 - //  
104 - //aaaa(){  
105 - // if (event.cmd == ApplicationFacade.OPEN_MIC)  
106 - // {  
107 - // if (audioDeviceOpenedUsers() >= Config.maxAudioChannels)  
108 - // {  
109 - // item.closeAudioDevice();  
110 - // Alert.show(resourceManager.getString('meeting', 'CannotOpenDeviceAnyMore'),  
111 - // resourceManager.getString('meeting', 'AlertWarning'), Alert.OK, item);  
112 - // event.stopImmediatePropagation();  
113 - // }  
114 - // else  
115 - // {  
116 - // super.updateCamMicStatus(event.camOpened, event.micOpened, event.node_id);  
117 - // }  
118 - // }  
119 - // else if (event.cmd == ApplicationFacade.OPEN_CAMERA)  
120 - // {  
121 - // if (videoDeviceOpenedUsers() >= Config.maxVideoChannels)  
122 - // {  
123 - // item.closeVideoDevice();  
124 - // Alert.show(resourceManager.getString('meeting', 'CannotOpenDeviceAnyMore'),  
125 - // resourceManager.getString('meeting', 'AlertWarning'), Alert.OK, item);  
126 - // event.stopImmediatePropagation();  
127 - // }  
128 - // else  
129 - // {  
130 - // super.updateCamMicStatus(event.camOpened, event.micOpened, event.node_id);  
131 - // }  
132 - // }  
133 - //} 111 + stopPublishVideo(_param) {
  112 + loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
  113 + let openingChannel = this.getOpeningVideoChannel(GlobalConfig.nodeId);
  114 + if (openingChannel == 0) {
  115 + loger.warn("stopPublishVideo,没有打开的channel");
  116 + return {"code": 1, "data": "没有打开的设备channel"};
  117 + }
134 118
135 - curAudioDeviceOpenedUsers()  
136 - {  
137 - //var openedUsers:int = 0;  
138 - //var index:int = 0;  
139 - //  
140 - //for(index = 0; index < _userArray.length; index++)  
141 - //{  
142 - // var tmpNode:RCNodeInfoRecordPdu = RCNodeInfoRecordPdu(_userArray.getItemAt(index));  
143 - // if(tmpNode.status & RCNodeStatus_E.NR_MIC_OPEN)  
144 - // {  
145 - // openedUsers++;  
146 - // }  
147 - //}  
148 - //  
149 - //return openedUsers;  
150 - }  
151 -  
152 - curVideoDeviceOpenedUsers()  
153 - {  
154 - //var openedUsers:int = 0;  
155 - //var index:int = 0;  
156 - //  
157 - //for(index = 0; index < _userArray.length; index++)  
158 - //{  
159 - // var tmpNode:RCNodeInfoRecordPdu = RCNodeInfoRecordPdu(_userArray.getItemAt(index));  
160 - // if(tmpNode.status & RCNodeStatus_E.NR_CAMERA_OPEN)  
161 - // {  
162 - // openedUsers++;  
163 - // }  
164 - //}  
165 - //return openedUsers; 119 + let channelInfo={};
  120 + channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
  121 + channelInfo.fromNodeId=0;
  122 + channelInfo.channelId=openingChannel;
  123 + channelInfo.timestamp=0;
  124 + channelInfo.classId=GlobalConfig.classId;
  125 + channelInfo.toNodeId=0;
  126 + channelInfo.mediaType=ApeConsts.MEDIA_TYPE_DEFAULT;
  127 + this.sendTableUpdateHandler(channelInfo);
166 } 128 }
167 129
168 sendVideoCommandMsg(_param) { 130 sendVideoCommandMsg(_param) {
169 - if(this._classInfo===null||EngineUtils.isEmptyObject(this._classInfo)){ 131 + if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {
170 loger.log('不能发送Video消息.McuClient还未初始化数据!'); 132 loger.log('不能发送Video消息.McuClient还未初始化数据!');
171 - if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){  
172 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);  
173 - return ; 133 + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
  134 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
  135 + return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"};
174 } 136 }
175 - return 1; 137 + return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"};
176 } 138 }
177 - if(_param==null){  
178 - loger.warn('sendVideoCommandMsg失败,参数错误',paramInfo);  
179 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
180 - return 1; 139 + if (_param == null) {
  140 + loger.warn('sendVideoCommandMsg失败,参数错误', _param);
  141 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  142 + return {"code": 1, "data": "sendVideoCommandMsg失败,参数错误"};
  143 + ;
181 } 144 }
182 // to, message 145 // to, message
183 loger.log('发送Video消息.', _param); 146 loger.log('发送Video消息.', _param);
184 147
185 -  
186 - 148 + if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {
  149 + //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启
  150 + let freeChannel = this.getFreeVideoChannel();
  151 + if (freeChannel == 0) {
  152 + loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param);
  153 + return {"code": 1, "data": "不能再打开更多的设备"};
  154 + }
  155 + }
187 /* message RCVideoSendDataRequestPdu { 156 /* message RCVideoSendDataRequestPdu {
188 required uint32 from_node_id = 1;//发起人 157 required uint32 from_node_id = 1;//发起人
189 optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收 158 optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收
@@ -196,12 +165,12 @@ class VideoChat extends Ape { @@ -196,12 +165,12 @@ class VideoChat extends Ape {
196 videoSendPdu.isPublic = true; 165 videoSendPdu.isPublic = true;
197 166
198 videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人 167 videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人
199 - videoSendPdu.toNodeId = parseInt(_param.toNodeID)||0;//接收者,0就是所有人  
200 - videoSendPdu.actionType = parseInt(_param.actionType)||ApeConsts.MEDIA_ACTION_DEFAULT; 168 + videoSendPdu.toNodeId = parseInt(_param.toNodeID) || 0;//接收者,0就是所有人
  169 + videoSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT;
201 170
202 - videoSendPdu.data=this._rCArrayBufferUtil.strToUint8Array("h5" + _param.data);//开头两个字会乱码 171 + videoSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" + _param.data);//开头两个字会乱码
203 172
204 - if (!videoSendPdu.isPublic && 0!=videoSendPdu.toNodeId) { 173 + if (!videoSendPdu.isPublic && 0 != videoSendPdu.toNodeId) {
205 //发送给制定的人 174 //发送给制定的人
206 loger.log('发送私聊Video消息.'); 175 loger.log('发送私聊Video消息.');
207 this.send(videoSendPdu); 176 this.send(videoSendPdu);
@@ -210,26 +179,28 @@ class VideoChat extends Ape { @@ -210,26 +179,28 @@ class VideoChat extends Ape {
210 loger.log('发送公聊Video消息.'); 179 loger.log('发送公聊Video消息.');
211 this.sendChatUniform(videoSendPdu); 180 this.sendChatUniform(videoSendPdu);
212 } 181 }
213 - return 0; 182 + return {"code": 0, "data": ""};
214 } 183 }
215 184
216 - sendTableUpdateHandler(){ 185 + sendTableUpdateHandler(_channelInfo) {
217 loger.log("video===sendTableUpdateHandler "); 186 loger.log("video===sendTableUpdateHandler ");
218 /* //验证坐标点集合数组是否合法 187 /* //验证坐标点集合数组是否合法
219 if(_docDataModel==null||_itemIdx==null){ 188 if(_docDataModel==null||_itemIdx==null){
220 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 189 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
221 return null; 190 return null;
222 }*/ 191 }*/
223 - loger.log("video===sendTableUpdateHandler ");  
224 -  
225 - let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);  
226 -  
227 192
  193 + //let freeChannel=this.getFreeVideoChannel();
  194 + //if(freeChannel==0){
  195 + // loger.warn("sendTableUpdateHandler,没有空闲的channel ");
  196 + // return;
  197 + //}
  198 + let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);
228 199
229 let tableItemPdu = new pdu['RCRegistryTableItemPdu']; 200 let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
230 - tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;//直接用时间戳作为id 201 + tableItemPdu.itemIdx = _channelInfo.channelId;//tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;
231 tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定 202 tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
232 - tableItemPdu.itemData =updateModelPdu.toArrayBuffer(); 203 + tableItemPdu.itemData = updateModelPdu.toArrayBuffer();
233 204
234 //insert 205 //insert
235 let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu']; 206 let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];
@@ -252,40 +223,41 @@ class VideoChat extends Ape { @@ -252,40 +223,41 @@ class VideoChat extends Ape {
252 adapterPdu.type = pdu.RCPDU_REG_ADAPTER; 223 adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
253 adapterPdu.item.push(adapterItemPdu); 224 adapterPdu.item.push(adapterItemPdu);
254 225
255 - loger.log("发送更新文档.itemIdx="+tableItemPdu.itemIdx);  
256 - this.sendUniform(adapterPdu,true); 226 + loger.log("发送更新VIDEO.itemIdx=" + tableItemPdu.itemIdx);
  227 + this.sendUniform(adapterPdu, true);
257 } 228 }
258 - /////收到消息处理///////////////////////////////////////////////////////////////////////////////// 229 +
  230 + /////收到消息处理//////////////////////////////////////////////////
259 231
260 // 视频消息处理,内部处理,不需要告诉应用层 232 // 视频消息处理,内部处理,不需要告诉应用层
261 - videoCommandHandler(_data) { 233 + receiveVideoCommandHandler(_data) {
262 let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data); 234 let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data);
263 - if(videoReceivePdu==null) { 235 + if (videoReceivePdu == null) {
264 loger.warn("视频消息处理,收到的消息为null,不做处理"); 236 loger.warn("视频消息处理,收到的消息为null,不做处理");
265 return; 237 return;
266 } 238 }
267 - videoReceivePdu.data=this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data,2);//开头两个字会乱码  
268 - loger.log('视频消息处理 videoCommandHandler.', videoReceivePdu); 239 + videoReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码
  240 + loger.log('视频消息处理 receiveVideoCommandHandler.', videoReceivePdu);
269 241
270 //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理 242 //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
271 - if(videoReceivePdu.toNodeId!=0&&videoReceivePdu.toNodeId!=GlobalConfig.nodeId){  
272 - loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId,"my nodeId=",GlobalConfig.nodeId);  
273 - }else {  
274 - this._emit(MessageTypes.VIDEO_COMMAND,videoReceivePdu); 243 + if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) {
  244 + loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId);
  245 + } else {
  246 + this._emit(MessageTypes.VIDEO_COMMAND, videoReceivePdu);
275 } 247 }
276 } 248 }
277 249
278 tableUpdateHandler(owner, itemIdx, itemData) { 250 tableUpdateHandler(owner, itemIdx, itemData) {
279 // debugger; 251 // debugger;
280 - let videoChannelInfo =this.unPackPdu(owner, itemIdx, itemData); 252 + let videoChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
281 //videoChannelInfo.owner = owner; 253 //videoChannelInfo.owner = owner;
282 //videoChannelInfo.channelId = itemIdx; 254 //videoChannelInfo.channelId = itemIdx;
283 //videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status; 255 //videoChannelInfo.status = owner === 0 ? ApeConsts.CHANNEL_STATUS_RELEASED : videoChannelInfo.status;
284 //loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo); 256 //loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo);
285 this.videoChannels[itemIdx] = videoChannelInfo; 257 this.videoChannels[itemIdx] = videoChannelInfo;
286 258
287 - this._emit(MessageTypes.VIDEO_UPDATE,videoChannelInfo);  
288 -/* switch (videoChannelInfo.status) { 259 + this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo);
  260 + /* switch (videoChannelInfo.status) {
289 case ApeConsts.CHANNEL_STATUS_RELEASED: 261 case ApeConsts.CHANNEL_STATUS_RELEASED:
290 // 只能关闭自己的流 262 // 只能关闭自己的流
291 if (this.activeChannelId === videoChannelInfo.channelId) { 263 if (this.activeChannelId === videoChannelInfo.channelId) {
@@ -312,20 +284,12 @@ class VideoChat extends Ape { @@ -312,20 +284,12 @@ class VideoChat extends Ape {
312 }*/ 284 }*/
313 } 285 }
314 286
315 - emitVideoChange() {  
316 - this._emit(MessageTypes.VIDEO_UPDATE, {  
317 - activeChannelId: this.activeChannelId,  
318 - HLSURL: this.activeURL,  
319 - });  
320 - };  
321 -  
322 -  
323 ///////数据的封包和解包///////////////////////////////////////// 287 ///////数据的封包和解包/////////////////////////////////////////
324 - packPdu(_param,_itemIdx){  
325 - loger.log("VIDEO===packPdu "); 288 + packPdu(_param, _itemIdx) {
  289 + loger.log("packPdu ");
326 //验证坐标点集合数组是否合法 290 //验证坐标点集合数组是否合法
327 - if(_param==null||_itemIdx==null){  
328 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 291 + if (_param == null || _itemIdx == null) {
  292 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
329 return null; 293 return null;
330 } 294 }
331 295
@@ -338,36 +302,66 @@ class VideoChat extends Ape { @@ -338,36 +302,66 @@ class VideoChat extends Ape {
338 }*/ 302 }*/
339 303
340 //判断type类型,根据type设置不同的参数 304 //判断type类型,根据type设置不同的参数
341 - let packPduModel =new pdu['RCVideoChannelInfoPdu'];  
342 - packPduModel.status=ApeConsts.CHANNEL_STATUS_OPENING;  
343 - packPduModel.channelId=_itemIdx;  
344 - packPduModel.classId=parseInt(GlobalConfig.classId);  
345 - packPduModel.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;  
346 - packPduModel.timestamp=EngineUtils.creatTimestamp();  
347 - packPduModel.fromNodeId =GlobalConfig.nodeId; 305 + let packPduModel = new pdu['RCVideoChannelInfoPdu'];
  306 + packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;
  307 + packPduModel.channelId = _itemIdx;
  308 + packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);
  309 + packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_VIDEO;
  310 + packPduModel.timestamp =_param.timestamp||EngineUtils.creatTimestamp();
  311 + packPduModel.fromNodeId = GlobalConfig.nodeId;
348 packPduModel.toNodeId = 0; 312 packPduModel.toNodeId = 0;
349 console.log(packPduModel); 313 console.log(packPduModel);
350 return packPduModel; 314 return packPduModel;
351 } 315 }
352 316
353 - unPackPdu(owner, itemIdx,itemData){  
354 - loger.log("VIDEO==unPackPdu ");  
355 - if(owner==null||itemIdx==null||itemData==null){  
356 - this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 317 + unPackPdu(owner, itemIdx, itemData) {
  318 + loger.log("unPackPdu ");
  319 + if (owner == null || itemIdx == null || itemData == null) {
  320 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
357 return null; 321 return null;
358 } 322 }
359 - try{ 323 + try {
360 324
361 let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData); 325 let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);
362 - loger.log(videoChannelInfo); 326 + loger.log("unPackPdu",videoChannelInfo);
363 return videoChannelInfo; 327 return videoChannelInfo;
364 - }catch (err){  
365 - loger.log("VIDEO收到数据 unPackPdu Pdu解析错误,itemIdx="+itemIdx+" err:"+err.message); 328 + } catch (err) {
  329 + loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);
366 } 330 }
367 return null; 331 return null;
368 } 332 }
369 333
  334 + //获取当前空闲的channel,返回值为0代表没有空闲的,否则返回的就是空闲的channelId
  335 + getFreeVideoChannel() {
  336 + loger.log("getFreeVideoChannel");
  337 + console.log(this.videoChannels);
  338 + let counter = 0;
  339 + for (let key in this.videoChannels) {
  340 + let item = this.videoChannels[key];
  341 + if (item && item.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
  342 + return item.channelId;
  343 + }
  344 + counter++;
  345 + }
  346 + if (counter < GlobalConfig.maxVideoChannels) {
  347 + return ApeConsts.VIDEO_OBJ_TABLE_ID + (counter);
  348 + }
  349 + return 0;//没有空闲的
  350 + }
370 351
  352 + //获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId
  353 + getOpeningVideoChannel(_nodeId){
  354 + if(_nodeId==null||_nodeId==0){
  355 + return 0;
  356 + }
  357 + for (let key in this.videoChannels) {
  358 + let item = this.videoChannels[key];
  359 + if (item && item.status == ApeConsts.CHANNEL_STATUS_OPENING&&item.fromNodeId==_nodeId) {
  360 + return item.channelId;
  361 + }
  362 + }
  363 + return 0;
  364 + }
371 } 365 }
372 366
373 export default VideoChat; 367 export default VideoChat;