李勇

1.简化了音视频模块的推流和播流接口,收到的音视频消息分为(播放、停止)

2.修改事件消息定义
@@ -34,14 +34,14 @@ let _audio_ape; @@ -34,14 +34,14 @@ let _audio_ape;
34 let _doc_ape; 34 let _doc_ape;
35 let _whiteboard_ape; 35 let _whiteboard_ape;
36 36
37 -//初始化成功回调函数  
38 -let _initSuccessCallBackFun;  
39 -  
40 -//加入会议成功回调函数  
41 -let _joinClassSuccessCallBackFun;  
42 -  
43 -//监听mcu所有错误异常回调函数  
44 -let _mcuErrorCallBackFun; 37 +////初始化成功回调函数
  38 +//let _initSuccessCallBackFun;
  39 +//
  40 +////加入会议成功回调函数
  41 +//let _joinClassSuccessCallBackFun;
  42 +//
  43 +////监听mcu所有错误异常回调函数
  44 +//let _mcuErrorCallBackFun;
45 45
46 //MCUClient 外部实例化主类 46 //MCUClient 外部实例化主类
47 export default class MessageEntrance extends Emiter { 47 export default class MessageEntrance extends Emiter {
@@ -71,7 +71,7 @@ export default class MessageEntrance extends Emiter { @@ -71,7 +71,7 @@ export default class MessageEntrance extends Emiter {
71 // 底层MCU消息层 71 // 底层MCU消息层
72 _mcu = Mcu; 72 _mcu = Mcu;
73 _mcu.on('*', (type, data) => this._emit(type, data)); 73 _mcu.on('*', (type, data) => this._emit(type, data));
74 - _mcu.on(MessageTypes.CLASS_JOIN_SUCCESS, this._mcuJoinClassSuccessHandler.bind(this));//加入MCU会议完成 74 + _mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuJoinMCUClassSuccessHandler.bind(this));//加入MCU会议完成
75 75
76 76
77 // 注册所有应用Ape 77 // 注册所有应用Ape
@@ -89,11 +89,11 @@ export default class MessageEntrance extends Emiter { @@ -89,11 +89,11 @@ export default class MessageEntrance extends Emiter {
89 89
90 _video_ape = new VideoApe(); 90 _video_ape = new VideoApe();
91 _video_ape.on('*', (type, data) => this._emit(type, data)); 91 _video_ape.on('*', (type, data) => this._emit(type, data));
92 - _video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this)); 92 + //_video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this));
93 93
94 _audio_ape= new AudioApe(); 94 _audio_ape= new AudioApe();
95 _audio_ape.on('*', (type, data) => this._emit(type, data)); 95 _audio_ape.on('*', (type, data) => this._emit(type, data));
96 - _audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this)); 96 + //_audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this));
97 97
98 _whiteboard_ape = new WhiteBoardApe(); 98 _whiteboard_ape = new WhiteBoardApe();
99 _whiteboard_ape.on('*', (type, data) => this._emit(type, data)); 99 _whiteboard_ape.on('*', (type, data) => this._emit(type, data));
@@ -109,62 +109,65 @@ export default class MessageEntrance extends Emiter { @@ -109,62 +109,65 @@ export default class MessageEntrance extends Emiter {
109 109
110 //公开外部调用的方法 110 //公开外部调用的方法
111 //class 111 //class
112 - this.init = this._init;  
113 - this.joinClass = this._joinClass;  
114 - this.leaveClass = this._leaveClass;  
115 - this.getMcuClientStatus = this._getMcuClientStatus; 112 + this.init = this._init.bind(this);
  113 + this.joinClass = this._joinClass.bind(this);
  114 + this.leaveClass = this._leaveClass.bind(this);
  115 + this.getMcuClientStatus = this._getMcuClientStatus.bind(this);
116 //this.getClassDetail = this._getClassDetail;//停用 116 //this.getClassDetail = this._getClassDetail;//停用
117 - this.getClassStatusInfo = this._getClassStatusInfo;  
118 - this.sendStartClass = this._sendStartClass;  
119 - this.sendPauseClass = this._sendPauseClass;  
120 - this.sendCloseClass = this._sendCloseClass; 117 + this.getClassStatusInfo = this._getClassStatusInfo.bind(this);
  118 + this.sendStartClass = this._sendStartClass.bind(this);
  119 + this.sendPauseClass = this._sendPauseClass.bind(this);
  120 + this.sendCloseClass = this._sendCloseClass.bind(this);
121 121
122 122
123 //chatApe 123 //chatApe
124 - this.sendChatMsg = this._sendChatMsg; 124 + this.sendChatMsg = this._sendChatMsg.bind(this);
125 125
126 //videoApe 126 //videoApe
127 - this.getVideoPlayPath = this._getVideoPlayPath;  
128 - this.getVideoPublishPath = this._getVideoPublishPath;  
129 - this.publishVideo = this._publishVideo;  
130 - this.stopPublishVideo = this._stopPublishVideo;  
131 - this.sendVideoBroadcastMsg=this._sendVideoBroadcastMsg; 127 + this.getVideoPlayPath = this._getVideoPlayPath.bind(this);
  128 + this.getVideoPublishPath = this._getVideoPublishPath.bind(this);
  129 + this.publishVideo = this._publishVideo.bind(this);
  130 + this.stopPublishVideo = this._stopPublishVideo.bind(this);
  131 + this.sendVideoBroadcastMsg=this._sendVideoBroadcastMsg.bind(this);
132 132
133 133
134 //audioApe 134 //audioApe
135 - this.getAudioPlayPath = this._getPlayAudioPath;  
136 - this.getAudioPublishPath = this._getPublishAudioPath;  
137 - this.publishAudio = this._publishAudio;  
138 - this.stopPublishAudio = this._stopPublishAudio;  
139 - this.sendAudioBroadcastMsg=this.sendAudioCommandMsg; 135 + this.getAudioPlayPath = this._getPlayAudioPath.bind(this);
  136 + this.getAudioPublishPath = this._getPublishAudioPath.bind(this);
  137 + this.publishAudio = this._publishAudio.bind(this);
  138 + this.stopPublishAudio = this._stopPublishAudio.bind(this);
  139 + this.sendAudioBroadcastMsg=this.sendAudioCommandMsg.bind(this);
140 140
141 //whiteBoradApe 141 //whiteBoradApe
142 - this.sendInsertAnnotaion = this._sendInsertAnnotaion; 142 + this.sendInsertAnnotaion = this._sendInsertAnnotaion.bind(this);
143 //this.sendDeleteAnnotaion=this._sendDeleteAnnotaion; 143 //this.sendDeleteAnnotaion=this._sendDeleteAnnotaion;
144 - this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation;  
145 - this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation;  
146 - this.sendGotoPrev = this._sendGotoPrev; 144 + this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation.bind(this);
  145 + this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this);
  146 + this.sendGotoPrev = this._sendGotoPrev.bind(this);
147 147
148 //DocApe 148 //DocApe
149 - this.sendDocumentUpload = this._sendDocumentUpload;//上传文档  
150 - this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc; //切换文档  
151 - this.sendDocumentSwitchPage = this._sendDocumentSwitchPage;//翻页  
152 - this.sendDocumentDelete = this._sassDeleteDocument;//删除文档,先通过Sass删除,sass删除成功之后再同步mcu 149 + this.sendDocumentUpload = this._sendDocumentUpload.bind(this);;//上传文档
  150 + this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this);; //切换文档
  151 + this.sendDocumentSwitchPage = this._sendDocumentSwitchPage.bind(this);;//翻页
  152 + this.sendDocumentDelete = this._sassDeleteDocument.bind(this);;//删除文档,先通过Sass删除,sass删除成功之后再同步mcu
153 //this.sendDocumentDeleteAll= this._documentDeleteAll;//删除所有文档 153 //this.sendDocumentDeleteAll= this._documentDeleteAll;//删除所有文档
154 - this.sendDocumentCommand = this._sendDocumentCommand;//操作文档(翻页、缩放、滚动...)  
155 - this.getDocImageFullPath=this._getDocImageFullPath;//获取文档图片的完整路径  
156 - this.getDocPDFFullPath=this._getDocPDFFullPath;//获取文档的完整路径 154 + this.sendDocumentCommand = this._sendDocumentCommand.bind(this);;//操作文档(翻页、缩放、滚动...)
  155 + this.getDocImageFullPath=this._getDocImageFullPath.bind(this);;//获取文档图片的完整路径
  156 + this.getDocPDFFullPath=this._getDocPDFFullPath.bind(this);;//获取文档的完整路径
157 } 157 }
158 158
159 159
160 //mcu异常监听 160 //mcu异常监听
161 _mcuErrorHandler(_data, _option) { 161 _mcuErrorHandler(_data, _option) {
162 - if (_mcuErrorCallBackFun) {  
163 let option = _option || ""; 162 let option = _option || "";
164 let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option}; 163 let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option};
165 loger.error("MCU_ERROR", errorMessage); 164 loger.error("MCU_ERROR", errorMessage);
  165 +
  166 + this._emit(MessageTypes.ERROR_EVENT,errorMessage);
  167 +
  168 +/* if (_mcuErrorCallBackFun) {
166 _mcuErrorCallBackFun(errorMessage); 169 _mcuErrorCallBackFun(errorMessage);
167 - } 170 + }*/
168 } 171 }
169 172
170 //获取当前的状态 173 //获取当前的状态
@@ -248,12 +251,10 @@ export default class MessageEntrance extends Emiter { @@ -248,12 +251,10 @@ export default class MessageEntrance extends Emiter {
248 251
249 //Sass 252 //Sass
250 //初始化 253 //初始化
251 - _init(_param, _onSuccess, _mcuErrorCallBack) {  
252 - _initSuccessCallBackFun = _onSuccess;  
253 - _mcuErrorCallBackFun = _mcuErrorCallBack; 254 + _init(_param) {
254 //{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0} 255 //{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0}
255 //判断传入的参数是否存在 256 //判断传入的参数是否存在
256 - if (_param == null || EngineUtils.isEmptyObject(_param) || _onSuccess == null || _mcuErrorCallBack == null) { 257 + if (_param == null || EngineUtils.isEmptyObject(_param)) {
257 loger.error('init初始化失败,参数错误'); 258 loger.error('init初始化失败,参数错误');
258 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM); 259 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
259 return; 260 return;
@@ -280,10 +281,10 @@ export default class MessageEntrance extends Emiter { @@ -280,10 +281,10 @@ export default class MessageEntrance extends Emiter {
280 } 281 }
281 282
282 //外部请求加入会议 283 //外部请求加入会议
283 - _joinClass(_param, _onSuccess) {  
284 - _joinClassSuccessCallBackFun = _onSuccess; 284 + _joinClass(_param) {
  285 + //_joinClassSuccessCallBackFun = _onSuccess;
285 //{"userName":"名字","password":""} 286 //{"userName":"名字","password":""}
286 - if (_param == null || EngineUtils.isEmptyObject(_param) || _onSuccess == null) { 287 + if (_param == null || EngineUtils.isEmptyObject(_param)) {
287 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM); 288 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
288 loger.log('不能进入会议,传递的参数不对.', _param); 289 loger.log('不能进入会议,传递的参数不对.', _param);
289 return; 290 return;
@@ -324,8 +325,6 @@ export default class MessageEntrance extends Emiter { @@ -324,8 +325,6 @@ export default class MessageEntrance extends Emiter {
324 325
325 //设置当前的会议状态 326 //设置当前的会议状态
326 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_1); 327 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_1);
327 -  
328 - if (_initSuccessCallBackFun) {  
329 //返回给客户端初始化成功的数据 328 //返回给客户端初始化成功的数据
330 let initSuccessCallBackData = {}; 329 let initSuccessCallBackData = {};
331 initSuccessCallBackData.siteId = GlobalConfig.siteId; 330 initSuccessCallBackData.siteId = GlobalConfig.siteId;
@@ -341,8 +340,12 @@ export default class MessageEntrance extends Emiter { @@ -341,8 +340,12 @@ export default class MessageEntrance extends Emiter {
341 initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired; 340 initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
342 } 341 }
343 342
  343 + this._emit(MessageTypes.CLASS_INIT_SUCCESS,initSuccessCallBackData);
  344 +
  345 +/* if (_initSuccessCallBackFun) {
344 _initSuccessCallBackFun(initSuccessCallBackData); 346 _initSuccessCallBackFun(initSuccessCallBackData);
345 - } 347 + }*/
  348 +
346 } 349 }
347 350
348 // 通过SASS平台验证(密码和MD5) 351 // 通过SASS平台验证(密码和MD5)
@@ -549,10 +552,12 @@ export default class MessageEntrance extends Emiter { @@ -549,10 +552,12 @@ export default class MessageEntrance extends Emiter {
549 552
550 //保存会态信息成功 553 //保存会态信息成功
551 _sassSaveClassStatusInfoSuccessHandler(_data) { 554 _sassSaveClassStatusInfoSuccessHandler(_data) {
552 - loger.log('保存会议状态信息成功.', _data); 555 + loger.log('保存会议状态信息成功.');
  556 + console.log(_data);
553 } 557 }
554 _sassSaveClassRecordInfoSuccessHandler(_data){ 558 _sassSaveClassRecordInfoSuccessHandler(_data){
555 - loger.log('保存会议录制信息成功.', _data); 559 + loger.log('保存会议录制信息成功.');
  560 + console.log(_data);
556 } 561 }
557 562
558 //Sass校验流程结束之后,开始加入MCU 563 //Sass校验流程结束之后,开始加入MCU
@@ -564,12 +569,10 @@ export default class MessageEntrance extends Emiter { @@ -564,12 +569,10 @@ export default class MessageEntrance extends Emiter {
564 } 569 }
565 570
566 // MCU 会议成功 571 // MCU 会议成功
567 - _mcuJoinClassSuccessHandler(_data) { 572 + _mcuJoinMCUClassSuccessHandler(_data) {
568 loger.log('MCU 会议成功.'); 573 loger.log('MCU 会议成功.');
569 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2); 574 GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
570 575
571 - //返回给客户数据  
572 - if (_joinClassSuccessCallBackFun) {  
573 //返回给客户端初始化成功的数据 576 //返回给客户端初始化成功的数据
574 let initSuccessCallBackData = {}; 577 let initSuccessCallBackData = {};
575 578
@@ -606,8 +609,14 @@ export default class MessageEntrance extends Emiter { @@ -606,8 +609,14 @@ export default class MessageEntrance extends Emiter {
606 initSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT; 609 initSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
607 loger.log('加入会议成功'); 610 loger.log('加入会议成功');
608 console.log(initSuccessCallBackData); 611 console.log(initSuccessCallBackData);
  612 +
  613 + //加入会议成功,广播消息
  614 + this._emit(MessageTypes.CLASS_JOIN_SUCCESS,initSuccessCallBackData);
  615 +
  616 +/* //返回给客户数据
  617 + if (_joinClassSuccessCallBackFun) {
609 _joinClassSuccessCallBackFun(initSuccessCallBackData); 618 _joinClassSuccessCallBackFun(initSuccessCallBackData);
610 - } 619 + }*/
611 } 620 }
612 621
613 //Sass删除文档数据 622 //Sass删除文档数据
@@ -42,7 +42,11 @@ class EverSocket extends Emiter { @@ -42,7 +42,11 @@ class EverSocket extends Emiter {
42 42
43 send(data) { 43 send(data) {
44 if (this._connected) { 44 if (this._connected) {
  45 + if(data){
  46 + loger.log('SEND MESSAGE,byteLength---->',data.byteLength);
  47 + }else {
45 loger.log('SEND MESSAGE---->'); 48 loger.log('SEND MESSAGE---->');
  49 + }
46 this.websocket.send(data); 50 this.websocket.send(data);
47 } else { 51 } else {
48 loger.warn('WebSocket未建立连接.消息忽略'); 52 loger.warn('WebSocket未建立连接.消息忽略');
@@ -85,6 +89,7 @@ class EverSocket extends Emiter { @@ -85,6 +89,7 @@ class EverSocket extends Emiter {
85 loger.log('WebSocket,Timers已经销毁'); 89 loger.log('WebSocket,Timers已经销毁');
86 return; 90 return;
87 } 91 }
  92 + this._setConnected(false);//先设置状态
88 this.websocket.onopen = undefined; 93 this.websocket.onopen = undefined;
89 this.websocket.onclose = undefined; 94 this.websocket.onclose = undefined;
90 this.websocket.onerror = undefined; 95 this.websocket.onerror = undefined;
@@ -96,7 +101,6 @@ class EverSocket extends Emiter { @@ -96,7 +101,6 @@ class EverSocket extends Emiter {
96 } 101 }
97 this.websocket = undefined; 102 this.websocket = undefined;
98 this._enableEverSocket = false; 103 this._enableEverSocket = false;
99 - this._setConnected(false);  
100 } 104 }
101 105
102 _onOpen() { 106 _onOpen() {
1 /** 1 /**
2 - *事件定义和错误码定义 2 + *事件消息ID和错误码 定义
3 */ 3 */
4 4
5 function MessageTypes() {} 5 function MessageTypes() {}
6 6
7 //--------------------事件相关的定义-------------------------------------- 7 //--------------------事件相关的定义--------------------------------------
8 //初始化相关事件定义 8 //初始化相关事件定义
9 -//MessageTypes.CLASS_INIT_SUCCESS='class.init.success';//初始化成功 9 +MessageTypes.CLASS_INIT_SUCCESS="class_init_success";//'class.init.success';//初始化成功
10 //MessageTypes.CLASS_INIT_FAILED='class.init.failed';//初始化失败 10 //MessageTypes.CLASS_INIT_FAILED='class.init.failed';//初始化失败
11 11
12 //加入会议相关事件定义 12 //加入会议相关事件定义
13 -MessageTypes.CLASS_JOIN_SUCCESS = 'join.class.success'; 13 +MessageTypes.CLASS_JOIN_MCU_SUCCESS ="class_join_mcu_success"// 'join.mcu.success';
14 //MessageTypes.CLASS_JOIN_FAILED = 'join.class.failed'; 14 //MessageTypes.CLASS_JOIN_FAILED = 'join.class.failed';
15 15
16 //会议信息和操作事件定义 16 //会议信息和操作事件定义
17 //MessageTypes.CLASS_SHOW_DETAIL = 'class_detail.message'; 17 //MessageTypes.CLASS_SHOW_DETAIL = 'class_detail.message';
18 -MessageTypes.CLASS_SHOW_ROSTER_NUM = 'roster_num.message';  
19 -MessageTypes.CLASS_INSERT_ROSTER = 'roster.insert.message';  
20 -MessageTypes.CLASS_DELETE_ROSTER = 'roster.delete.message';  
21 -MessageTypes.CLASS_NONENTITY_ROSTER = 'roster.nonentity.message'; 18 +MessageTypes.CLASS_JOIN_SUCCESS ="class_join_success"// 'join.class.success';
  19 +MessageTypes.CLASS_UPDATE_ROSTER_NUM ="class_update_roster_num";// 'roster_num.message';
  20 +MessageTypes.CLASS_INSERT_ROSTER ="class_insert_roster";// 'roster.insert.message';
  21 +MessageTypes.CLASS_DELETE_ROSTER ="class_delete_roster"// 'roster.delete.message';
  22 +MessageTypes.CLASS_NONENTITY_ROSTER ="class_nonenetity_roster";// 'roster.nonentity.message';
22 23
23 -MessageTypes.CLASS_EXIT = 'class.exit';//退出 关闭会议  
24 -MessageTypes.CLASS_UPTATE_STATUS = 'class.update.status';//更新会议状态信息  
25 -MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态信息发生改变,需要保存数据到sass和同步MCU 24 +MessageTypes.CLASS_EXIT ="class_exit";// 'class.exit';//退出 关闭会议
  25 +MessageTypes.CLASS_UPTATE_STATUS ="class_update_status";// 'class.update.status';//更新会议状态信息
  26 +MessageTypes.CLASS_STATUS_INFO_CHANGE="class_status_info_change";// 'class.status.info.change';//会议状态信息发生改变,需要保存数据到sass和同步MCU
26 27
27 -MessageTypes.CLASS_UPDATE_TIMER='class.update.timer';//更新当前上课的时间 28 +MessageTypes.CLASS_UPDATE_TIMER="class_update_timer";//'class.update.timer';//更新当前上课的时间
28 29
29 -MessageTypes.CLASS_RECORD_START='class.record.start';//开始录制 30 +MessageTypes.CLASS_RECORD_START="class_record_start";//'class.record.start';//开始录制
30 31
31 32
32 33
33 //聊天模块事件定义 34 //聊天模块事件定义
34 -MessageTypes.CHAT_RECEIVE = 'chat.receive'; 35 +MessageTypes.CHAT_RECEIVE ="chat_receive_message";// 'chat.receive';
35 36
36 //视频模块事件定义 37 //视频模块事件定义
37 -MessageTypes.VIDEO_UPDATE = 'video.update';  
38 -MessageTypes.VIDEO_BROADCAST= 'video.broadcast'; 38 +MessageTypes.VIDEO_PLAY ="video_play";// 'video.play';//播放视频
  39 +MessageTypes.VIDEO_STOP ="video_stop"; //'video.stop';//停止视频
  40 +//MessageTypes.VIDEO_UPDATE ="video.update";// 'video.update';//废弃,400、401取代
  41 +MessageTypes.VIDEO_BROADCAST= "video_broadcast";//'video.broadcast';
39 42
40 //音频模块事件定义 43 //音频模块事件定义
41 -MessageTypes.AUDIO_UPDATE = 'audio.update';  
42 -MessageTypes.AUDIO_BROADCAST= 'audio.broadcast'; 44 +MessageTypes.AUDIO_PLAY ="audio_play";// 'audio.play';//播放
  45 +MessageTypes.AUDIO_STOP = "audio_stop";//'audio.stop';//停止
  46 +//MessageTypes.AUDIO_UPDATE = "502";//'audio.update';
  47 +MessageTypes.AUDIO_BROADCAST= "audio_broadcast";//'audio.broadcast';
43 48
44 49
45 //文档模块事件定义 50 //文档模块事件定义
46 -MessageTypes.DOC_DELETE='document.delete';//删除文档  
47 -MessageTypes.DOC_UPDATE = 'document.update';//更新文档(添加、变更) 51 +MessageTypes.DOC_DELETE="document_delete";//'document.delete';//删除文档
  52 +MessageTypes.DOC_UPDATE ="document_update";// 'document.update';//更新文档(添加、变更)
48 //MessageTypes.DOC_SHOW = 'document.show'; 53 //MessageTypes.DOC_SHOW = 'document.show';
49 //MessageTypes.DOC_UPLOAD='document.upload';//上传文档 54 //MessageTypes.DOC_UPLOAD='document.upload';//上传文档
50 //MessageTypes.DOC_COMMAND='document.command';//操作文档 55 //MessageTypes.DOC_COMMAND='document.command';//操作文档
@@ -55,18 +60,15 @@ MessageTypes.DOC_UPDATE = 'document.update';//鏇存柊鏂囨。(娣诲姞銆佸彉鏇) @@ -55,18 +60,15 @@ MessageTypes.DOC_UPDATE = 'document.update';//鏇存柊鏂囨。(娣诲姞銆佸彉鏇)
55 60
56 61
57 //白板笔记事件定义 62 //白板笔记事件定义
58 -MessageTypes.WHITEBOARD_ANNOTATION_UPDATE = 'whiteboard.annotation.update'; 63 +MessageTypes.WHITEBOARD_ANNOTATION_UPDATE ="whiteboard_annotation_update";// 'whiteboard.annotation.update';
59 //MessageTypes.WHITEBOARD_ANNOTAION_INSERT = 'whiteboard.annotation.insert'; 64 //MessageTypes.WHITEBOARD_ANNOTAION_INSERT = 'whiteboard.annotation.insert';
60 //MessageTypes.WHITEBOARD_ANNOTAION_DELETE = 'whiteboard.annotation.delete'; 65 //MessageTypes.WHITEBOARD_ANNOTAION_DELETE = 'whiteboard.annotation.delete';
61 //MessageTypes.WHITEBOARD_ANNOTATION_CLEAR = 'whiteboard.annotation.clear'; 66 //MessageTypes.WHITEBOARD_ANNOTATION_CLEAR = 'whiteboard.annotation.clear';
62 67
63 68
64 -//音频  
65 -MessageTypes.AUDIO_RECEIVE='audio.receive';  
66 -  
67 -  
68 //错误事件定义 69 //错误事件定义
69 -MessageTypes.MCU_ERROR ="mcuError";//MCU错误 70 +MessageTypes.MCU_ERROR ="mcu_error";//"mcuError";//MCU错误(内部使用)
  71 +MessageTypes.ERROR_EVENT="error_event";//外部监听错误的消息ID(外部使用)
70 72
71 73
72 //---------------错误消息 ErrorCode 定义------------------------------------------------- 74 //---------------错误消息 ErrorCode 定义-------------------------------------------------
@@ -103,6 +105,11 @@ MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG=501;//APE鍦ㄦ帴鍙h皟鐢ㄦ椂鍙傛暟閿欒 @@ -103,6 +105,11 @@ MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG=501;//APE鍦ㄦ帴鍙h皟鐢ㄦ椂鍙傛暟閿欒
103 MessageTypes.ERR_DOC_DELETE_FAILED=600;//删除文档失败 105 MessageTypes.ERR_DOC_DELETE_FAILED=600;//删除文档失败
104 MessageTypes.ERR_DOC_DELETE_FAILED_PARAM=601;//删除文档失败,参数错误 106 MessageTypes.ERR_DOC_DELETE_FAILED_PARAM=601;//删除文档失败,参数错误
105 107
  108 +
  109 +MessageTypes.ERR_SDK_FAILED=700;// sdk还没初始化
  110 +MessageTypes.ERR_INTERFACE_NONE=701;//调用的接口不存在
  111 +MessageTypes.ERR_INTERFACE_PARAMS_ERROR=702;//调用的接口,传递的参数不正确
  112 +
106 MessageTypes.ERR_NETWORK=10000;//网络错误 113 MessageTypes.ERR_NETWORK=10000;//网络错误
107 MessageTypes.ERR_UNKNOWN=10001;//未知错误 114 MessageTypes.ERR_UNKNOWN=10001;//未知错误
108 115
@@ -143,6 +150,9 @@ MessageTypes.ErrorReson[MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG]="APE鍦ㄦ帴鍙 @@ -143,6 +150,9 @@ MessageTypes.ErrorReson[MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG]="APE鍦ㄦ帴鍙
143 MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED]="删除文档失败"; 150 MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED]="删除文档失败";
144 MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED_PARAM]="删除文档失败,参数错误"; 151 MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED_PARAM]="删除文档失败,参数错误";
145 152
  153 +MessageTypes.ErrorReson[MessageTypes.ERR_SDK_FAILED]="sdk还没初始化";
  154 +MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_NONE]="调用的接口不存在";
  155 +MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_PARAMS_ERROR]="调用的接口,传递的参数不正确";
146 156
147 MessageTypes.ErrorReson[MessageTypes.ERR_NETWORK]="网络错误"; 157 MessageTypes.ErrorReson[MessageTypes.ERR_NETWORK]="网络错误";
148 MessageTypes.ErrorReson[MessageTypes.ERR_UNKNOWN]="未知错误"; 158 MessageTypes.ErrorReson[MessageTypes.ERR_UNKNOWN]="未知错误";
@@ -431,14 +431,14 @@ class Sass extends Emiter { @@ -431,14 +431,14 @@ class Sass extends Emiter {
431 431
432 } 432 }
433 433
434 -Sass.prototype.SUCCESS = Sass.SUCCESS = 'Sass.success';  
435 -Sass.prototype.CLASS_INIT_SUCCESS = Sass.CLASS_INIT_SUCCESS = 'sass.class.init.success';  
436 -Sass.prototype.CLASS_GET_CLASS_PARAM = Sass.CLASS_GET_CLASS_PARAM = 'class.getClassParam.message';  
437 -Sass.prototype.CLASS_GET_CLASS_DETAIL = Sass.CLASS_GET_CLASS_DETAIL = 'class.getClassDetail.message';  
438 -Sass.prototype.DELETE_DOCUMENT_SUCCESS = Sass.DELETE_DOCUMENT_SUCCESS = 'class.deleteDocumentSuccess.message';//删除文档成功 434 +Sass.prototype.SUCCESS = Sass.SUCCESS = 'Sass_success';
  435 +Sass.prototype.CLASS_INIT_SUCCESS = Sass.CLASS_INIT_SUCCESS = 'sass_class_init_success';
  436 +Sass.prototype.CLASS_GET_CLASS_PARAM = Sass.CLASS_GET_CLASS_PARAM = 'sass_class_getClassParam.message';
  437 +Sass.prototype.CLASS_GET_CLASS_DETAIL = Sass.CLASS_GET_CLASS_DETAIL = 'sass_class_getClassDetail_message';
  438 +Sass.prototype.DELETE_DOCUMENT_SUCCESS = Sass.DELETE_DOCUMENT_SUCCESS = 'sass_class_deleteDocumentSuccess_message';//删除文档成功
439 439
440 -Sass.prototype.CLASS_SAVE_STATUS_INFO_SUCCESS = Sass.CLASS_SAVE_STATUS_INFO_SUCCESS = 'class.saveClassStatusInfoSuccess.message';//保存会议状态信息  
441 -Sass.prototype.CLASS_SAVE_RECORD_INFO_SUCCESS = Sass.CLASS_SAVE_RECORD_INFO_SUCCESS = 'class.saveClassRecordInfoSuccess.message';//保存录制会议信息 440 +Sass.prototype.CLASS_SAVE_STATUS_INFO_SUCCESS = Sass.CLASS_SAVE_STATUS_INFO_SUCCESS = 'sass_class_saveClassStatusInfoSuccess_message';//保存会议状态信息
  441 +Sass.prototype.CLASS_SAVE_RECORD_INFO_SUCCESS = Sass.CLASS_SAVE_RECORD_INFO_SUCCESS = 'sass_class_saveClassRecordInfoSuccess_message';//保存录制会议信息
442 442
443 443
444 export default new Sass; 444 export default new Sass;
@@ -54,7 +54,7 @@ export default class Ape extends Emiter { @@ -54,7 +54,7 @@ export default class Ape extends Emiter {
54 54
55 // 监听底层MCU会议 55 // 监听底层MCU会议
56 this.mcu = mcu; 56 this.mcu = mcu;
57 - this.mcu.on(MessageTypes.CLASS_JOIN_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this)); 57 + this.mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
58 this.mcu.registerApe(this); 58 this.mcu.registerApe(this);
59 } 59 }
60 60
@@ -57,15 +57,21 @@ class AudioApe extends Ape { @@ -57,15 +57,21 @@ class AudioApe extends Ape {
57 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; 57 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
58 } 58 }
59 59
60 - if (_param == null||_param.channelId == null||  
61 - _param.classId == null||_param.userId == null||_param.userId==""||  
62 - _param.siteId == null|| _param.timestamp==null) 60 + if (_param == null||_param.publishUrl == null)
63 { 61 {
64 loger.warn('publishAudio,参数错误', _param); 62 loger.warn('publishAudio,参数错误', _param);
65 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 63 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
66 return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"}; 64 return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};
67 } 65 }
68 66
  67 + //根据推流的地址获取对应的频道信息
  68 + let needPublishChannelInfo=this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);
  69 + if(needPublishChannelInfo==null){
  70 + loger.warn('publishVideo,推流数据已经无效', _param);
  71 + return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};
  72 + }
  73 +
  74 +
69 //同一个nodeId只允许推一个流,如果已经推了就不能再推 75 //同一个nodeId只允许推一个流,如果已经推了就不能再推
70 if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){ 76 if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){
71 loger.warn("publishAudio,已经存在一个流,不能再推"); 77 loger.warn("publishAudio,已经存在一个流,不能再推");
@@ -80,20 +86,20 @@ class AudioApe extends Ape { @@ -80,20 +86,20 @@ class AudioApe extends Ape {
80 } 86 }
81 87
82 //判断当前的频道是否已经占用 88 //判断当前的频道是否已经占用
83 - if(this.mediaModule.checkChannelIsOpening(_param.channelId)){  
84 - loger.warn(_param.channelId,"频道已经被占用"); 89 + if(this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)){
  90 + loger.warn(needPublishChannelInfo.channelId,"频道已经被占用");
85 return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"}; 91 return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"};
86 } 92 }
87 93
88 let channelInfo={}; 94 let channelInfo={};
89 channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING; 95 channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
90 channelInfo.fromNodeId=GlobalConfig.nodeId; 96 channelInfo.fromNodeId=GlobalConfig.nodeId;
91 - channelInfo.channelId=_param.channelId;//freeChannel  
92 - channelInfo.timestamp=_param.timestamp;//EngineUtils.creatTimestamp();  
93 - channelInfo.classId=_param.classId;//GlobalConfig.classId;  
94 - channelInfo.siteId=_param.siteId;//GlobalConfig.siteId; 97 + channelInfo.channelId=needPublishChannelInfo.channelId;//freeChannel
  98 + channelInfo.streamId=needPublishChannelInfo.streamId;//按规则拼接的流名称
  99 + channelInfo.timestamp=needPublishChannelInfo.timestamp;//EngineUtils.creatTimestamp();
  100 + channelInfo.classId=GlobalConfig.classId;//GlobalConfig.classId;
  101 + channelInfo.siteId=GlobalConfig.siteId;//GlobalConfig.siteId;
95 channelInfo.toNodeId=0; 102 channelInfo.toNodeId=0;
96 - channelInfo.userId=_param.userId;  
97 channelInfo.mediaType=ApeConsts.MEDIA_TYPE_AUDIO; 103 channelInfo.mediaType=ApeConsts.MEDIA_TYPE_AUDIO;
98 this.sendTableUpdateHandler(channelInfo); 104 this.sendTableUpdateHandler(channelInfo);
99 return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"} 105 return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"}
@@ -106,9 +112,9 @@ class AudioApe extends Ape { @@ -106,9 +112,9 @@ class AudioApe extends Ape {
106 loger.warn(GlobalConfig.getCurrentStatus()); 112 loger.warn(GlobalConfig.getCurrentStatus());
107 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; 113 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
108 } 114 }
109 - //_param如果为空,那么默认就是当前自己的nodeId,否则用_param 115 + //_param如果为空或者0,那么默认就是当前自己的nodeId,否则用_param
110 let nodeId; 116 let nodeId;
111 - if(_param&&parseInt(_param.nodeId)>=0){ 117 + if(_param&&parseInt(_param.nodeId)>0){
112 nodeId=parseInt(_param.nodeId); 118 nodeId=parseInt(_param.nodeId);
113 }else { 119 }else {
114 nodeId=GlobalConfig.nodeId; 120 nodeId=GlobalConfig.nodeId;
@@ -116,8 +122,8 @@ class AudioApe extends Ape { @@ -116,8 +122,8 @@ class AudioApe extends Ape {
116 122
117 let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); 123 let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId);
118 if (openingChannel == 0) { 124 if (openingChannel == 0) {
119 - loger.warn(nodeId,"stopPublishAudio,没有占用channel,不需要关闭");  
120 - return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel,不需要关闭"}; 125 + loger.warn(nodeId,"没有占用channel不需要处理");
  126 + return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};
121 } 127 }
122 128
123 let channelInfo={}; 129 let channelInfo={};
@@ -244,11 +250,47 @@ class AudioApe extends Ape { @@ -244,11 +250,47 @@ class AudioApe extends Ape {
244 250
245 tableUpdateHandler(owner, itemIdx, itemData) { 251 tableUpdateHandler(owner, itemIdx, itemData) {
246 // debugger; 252 // debugger;
247 - let updateChannelInfo = this.unPackPdu(owner, itemIdx, itemData); 253 + /* let updateChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
248 254
249 this.mediaModule.mediaChannels[itemIdx] = updateChannelInfo; 255 this.mediaModule.mediaChannels[itemIdx] = updateChannelInfo;
250 256
251 - this._emit(MessageTypes.AUDIO_UPDATE, updateChannelInfo); 257 + this._emit(MessageTypes.AUDIO_UPDATE, updateChannelInfo);*/
  258 + let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
  259 + this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;
  260 +
  261 + if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){
  262 + let receiveChannelInfo={};
  263 + receiveChannelInfo.mediaId=unpackChannelInfo.channelId;
  264 +
  265 + //消息不是自己同步的,需要处理
  266 + if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){
  267 + //正在推流
  268 + receiveChannelInfo.m3u8Url="";
  269 + receiveChannelInfo.rtmpUrl="";
  270 + let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
  271 + let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});
  272 +
  273 + if(m3u8Stream.code==0){
  274 + receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;
  275 + }
  276 + if(rtmpStream.code==0){
  277 + receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;
  278 + }
  279 + loger.log("AUDIO_PLAY");
  280 + console.log(receiveChannelInfo);
  281 + //广播播放视频的消息
  282 + this._emit(MessageTypes.AUDIO_PLAY, receiveChannelInfo);
  283 + }else {
  284 + loger.log("AUDIO_STOP");
  285 + console.log(receiveChannelInfo);
  286 + //流已经停止
  287 + this._emit(MessageTypes.AUDIO_STOP, receiveChannelInfo);
  288 + }
  289 + }else {
  290 + loger.warn("消息是自己发送的或者是消息无效,不需要处理,消息内容如下:");
  291 + console.log(unpackChannelInfo);
  292 +
  293 + }
252 } 294 }
253 295
254 ///////数据的封包和解包///////////////////////////////////////// 296 ///////数据的封包和解包/////////////////////////////////////////
@@ -264,6 +306,7 @@ class AudioApe extends Ape { @@ -264,6 +306,7 @@ class AudioApe extends Ape {
264 let packPduModel = new pdu['RCAudioChannelInfoPdu']; 306 let packPduModel = new pdu['RCAudioChannelInfoPdu'];
265 packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED; 307 packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;
266 packPduModel.channelId = _itemIdx; 308 packPduModel.channelId = _itemIdx;
  309 + packPduModel.streamId = _param.streamId||"";
267 packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId; 310 packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId;
268 packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId); 311 packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);
269 packPduModel.userId =_param.userId||"0"; 312 packPduModel.userId =_param.userId||"0";
@@ -283,7 +326,7 @@ class AudioApe extends Ape { @@ -283,7 +326,7 @@ class AudioApe extends Ape {
283 } 326 }
284 try { 327 try {
285 let packChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(itemData); 328 let packChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(itemData);
286 - loger.log("unPackPdu",packChannelInfo); 329 + console.log(packChannelInfo);
287 return packChannelInfo; 330 return packChannelInfo;
288 } catch (err) { 331 } catch (err) {
289 loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message); 332 loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);
@@ -548,7 +548,7 @@ class ConferApe extends Ape { @@ -548,7 +548,7 @@ class ConferApe extends Ape {
548 548
549 //广播当前的人数 549 //广播当前的人数
550 emitRosterChange() { 550 emitRosterChange() {
551 - this._emit(MessageTypes.CLASS_SHOW_ROSTER_NUM, Object.keys(this.rosters).length); 551 + this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length);
552 } 552 }
553 553
554 ///////数据的封包和解包///////////////////////////////////////// 554 ///////数据的封包和解包/////////////////////////////////////////
@@ -171,6 +171,7 @@ class DocApe extends Ape { @@ -171,6 +171,7 @@ class DocApe extends Ape {
171 if(lastIndex>0){ 171 if(lastIndex>0){
172 let newPath=fullPath.substr(0,lastIndex); 172 let newPath=fullPath.substr(0,lastIndex);
173 let pathArr=[]; 173 let pathArr=[];
  174 + //页数从1开始
174 for(let i=1;i<=_param.pageNum;i++){ 175 for(let i=1;i<=_param.pageNum;i++){
175 pathArr.push(newPath+"/"+i+"."+fileType); 176 pathArr.push(newPath+"/"+i+"."+fileType);
176 } 177 }
@@ -210,6 +211,8 @@ class DocApe extends Ape { @@ -210,6 +211,8 @@ class DocApe extends Ape {
210 211
211 //切换文档 212 //切换文档
212 documentSwitchDoc(paramInfo){ 213 documentSwitchDoc(paramInfo){
  214 + loger.log('切换文档,documentSwitchDoc');
  215 + console.log(paramInfo);
213 if(paramInfo==null||paramInfo.itemIdx==null){ 216 if(paramInfo==null||paramInfo.itemIdx==null){
214 loger.warn('documentSwitch失败,参数错误',paramInfo); 217 loger.warn('documentSwitch失败,参数错误',paramInfo);
215 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 218 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
@@ -257,6 +260,8 @@ class DocApe extends Ape { @@ -257,6 +260,8 @@ class DocApe extends Ape {
257 260
258 //文档翻页 261 //文档翻页
259 documentSwitchPage(paramInfo){ 262 documentSwitchPage(paramInfo){
  263 + loger.log('文档翻页,documentSwitchPage');
  264 + console.log(paramInfo);
260 //console.log(this.docList); 265 //console.log(this.docList);
261 //获取已经存在的数据 266 //获取已经存在的数据
262 let docDataModel= this.docList[paramInfo.itemIdx]; 267 let docDataModel= this.docList[paramInfo.itemIdx];
@@ -12,6 +12,7 @@ let loger = Loger.getLoger('MediaModule'); @@ -12,6 +12,7 @@ let loger = Loger.getLoger('MediaModule');
12 12
13 class MediaModule { 13 class MediaModule {
14 constructor() { 14 constructor() {
  15 + this.needPublishMediaChannel={};//记录准备推流的频道信息
15 this.mediaChannels = {}; 16 this.mediaChannels = {};
16 this.maxMediaChannel=0; 17 this.maxMediaChannel=0;
17 this.MEDIA_OBJ_TABLE_ID=0; 18 this.MEDIA_OBJ_TABLE_ID=0;
@@ -20,9 +21,7 @@ class MediaModule { @@ -20,9 +21,7 @@ class MediaModule {
20 //获取播流地址 21 //获取播流地址
21 getMediaPlayPath(_param) { 22 getMediaPlayPath(_param) {
22 loger.log('getMediaPlayPath'); 23 loger.log('getMediaPlayPath');
23 - if (_param == null||_param.siteId == null||  
24 - _param.classId == null||_param.userId == null||  
25 - _param.channelId == null|| _param.timestamp==null) 24 + if (_param == null||_param.streamId == null)
26 { 25 {
27 loger.warn('getMediaPlayPath,参数错误', _param); 26 loger.warn('getMediaPlayPath,参数错误', _param);
28 //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 27 //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
@@ -37,21 +36,13 @@ class MediaModule { @@ -37,21 +36,13 @@ class MediaModule {
37 port = (GlobalConfig.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort; 36 port = (GlobalConfig.RSServerPort == "" || GlobalConfig.RSServerPort == null) ? "":":" + GlobalConfig.RSServerPort;
38 path = "http://" + GlobalConfig.RSServerIP 37 path = "http://" + GlobalConfig.RSServerIP
39 + port + "/live/" 38 + port + "/live/"
40 - + _param.siteId  
41 - + "_" + _param.classId  
42 - + "_" + _param.userId  
43 - + "_" + _param.channelId  
44 - + "_" + _param.timestamp 39 + + _param.streamId
45 + "/index.m3u8"; 40 + "/index.m3u8";
46 } else { 41 } else {
47 port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort; 42 port = (GlobalConfig.MSServerPort == "" || GlobalConfig.MSServerPort == null) ? "":":" + GlobalConfig.MSServerPort;
48 path = "rtmp://" + GlobalConfig.MSServerIP 43 path = "rtmp://" + GlobalConfig.MSServerIP
49 + port + "/live/" 44 + port + "/live/"
50 - + _param.siteId  
51 - + "_" + _param.classId  
52 - + "_" + _param.userId  
53 - + "_" + _param.channelId  
54 - + "_" + _param.timestamp; 45 + + _param.streamId;
55 } 46 }
56 return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path}; 47 return {"code": ApeConsts.RETURN_SUCCESS, "data": "","playUrl": path};
57 } 48 }
@@ -77,18 +68,21 @@ class MediaModule { @@ -77,18 +68,21 @@ class MediaModule {
77 //时间戳 68 //时间戳
78 let timestamp = EngineUtils.creatTimestamp(); 69 let timestamp = EngineUtils.creatTimestamp();
79 70
80 - //生成推流地址和推流数据(同步数据的时候用)  
81 - let publishUrl = "rtmp://" + GlobalConfig.MSServerIP  
82 - + port + "/"+pubType+"/" +GlobalConfig.siteId+"_" 71 + let streamId=GlobalConfig.siteId+"_"
83 + GlobalConfig.classId + "_"+GlobalConfig.userId 72 + GlobalConfig.classId + "_"+GlobalConfig.userId
84 +"_" + freeChannel + "_" + timestamp; 73 +"_" + freeChannel + "_" + timestamp;
  74 +
  75 + //生成推流地址和推流数据(同步数据的时候用)
  76 + let publishUrl = "rtmp://" + GlobalConfig.MSServerIP
  77 + + port + "/"+pubType+"/" +streamId;
  78 +
  79 + this.needPublishMediaChannel[publishUrl]={
  80 + "channelId":freeChannel,
  81 + "publishUrl":publishUrl,
  82 + "streamId":streamId
  83 + };
85 return {"code": ApeConsts.RETURN_SUCCESS, 84 return {"code": ApeConsts.RETURN_SUCCESS,
86 "data":"", 85 "data":"",
87 - "siteId":GlobalConfig.siteId,  
88 - "classId":GlobalConfig.classId,  
89 - "userId":GlobalConfig.userId,  
90 - "channelId": freeChannel,  
91 - "timestamp": timestamp,  
92 "publishUrl": publishUrl 86 "publishUrl": publishUrl
93 }; 87 };
94 } 88 }
@@ -111,6 +105,11 @@ class MediaModule { @@ -111,6 +105,11 @@ class MediaModule {
111 return 0;//没有空闲的 105 return 0;//没有空闲的
112 } 106 }
113 107
  108 + //获取准备推流的频道信息
  109 + getNeedPublishMediaChannel(_publishUrl){
  110 + return this.needPublishMediaChannel[_publishUrl];
  111 + }
  112 +
114 //获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId 113 //获取当前属于nodeId的已经打开的的channel,返回值为0代表没有打开的,否则返回的就是打开的channelId
115 getOpeningMediaChannel(_nodeId){ 114 getOpeningMediaChannel(_nodeId){
116 if(_nodeId==null||_nodeId==0){ 115 if(_nodeId==null||_nodeId==0){
@@ -58,16 +58,19 @@ class VideoApe extends Ape { @@ -58,16 +58,19 @@ class VideoApe extends Ape {
58 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"}; 58 return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};
59 } 59 }
60 60
61 - if (_param == null||_param.channelId == null||  
62 - _param.classId == null||_param.userId == null||_param.userId == ""||  
63 - _param.siteId == null|| _param.timestamp==null) 61 + if (_param == null||_param.publishUrl == null)
64 { 62 {
65 loger.warn('publishVideo,参数错误', _param); 63 loger.warn('publishVideo,参数错误', _param);
66 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG); 64 this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
67 return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"}; 65 return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};
68 } 66 }
69 67
70 - loger.log('publishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels); 68 + //根据推流的地址获取对应的频道信息
  69 + let needPublishChannelInfo=this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);
  70 + if(needPublishChannelInfo==null){
  71 + loger.warn('publishVideo,推流数据已经无效', _param);
  72 + return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};
  73 + }
71 74
72 //同一个nodeId只允许推一个流,如果已经推了就不能再推 75 //同一个nodeId只允许推一个流,如果已经推了就不能再推
73 if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){ 76 if(this.mediaModule.getOpeningMediaChannel(GlobalConfig.nodeId)!=0){
@@ -82,23 +85,22 @@ class VideoApe extends Ape { @@ -82,23 +85,22 @@ class VideoApe extends Ape {
82 return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"}; 85 return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备"};
83 } 86 }
84 87
  88 +
85 //判断当前的频道是否已经占用 89 //判断当前的频道是否已经占用
86 - if(this.mediaModule.checkChannelIsOpening(_param.channelId)){  
87 - loger.warn(_param.channelId,"频道已经被占用"); 90 + if(this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)){
  91 + loger.warn(needPublishChannelInfo.channelId,"频道已经被占用");
88 return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"}; 92 return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!"};
89 } 93 }
90 94
91 let channelInfo={}; 95 let channelInfo={};
92 channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING; 96 channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;
93 channelInfo.fromNodeId=GlobalConfig.nodeId; 97 channelInfo.fromNodeId=GlobalConfig.nodeId;
94 - channelInfo.channelId=_param.channelId;//freeChannel  
95 - channelInfo.timestamp=_param.timestamp;//EngineUtils.creatTimestamp();  
96 - channelInfo.classId=_param.classId;//GlobalConfig.classId;  
97 - channelInfo.siteId=_param.siteId;//GlobalConfig.siteId; 98 + channelInfo.channelId=needPublishChannelInfo.channelId;
  99 + channelInfo.streamId=needPublishChannelInfo.streamId;//按规则拼接的流名称
  100 + channelInfo.classId=GlobalConfig.classId;
  101 + channelInfo.siteId=GlobalConfig.siteId;
98 channelInfo.toNodeId=0; 102 channelInfo.toNodeId=0;
99 channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO; 103 channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;
100 - channelInfo.userId=_param.userId;  
101 -  
102 this.sendTableUpdateHandler(channelInfo); 104 this.sendTableUpdateHandler(channelInfo);
103 return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"} 105 return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!"}
104 } 106 }
@@ -113,7 +115,7 @@ class VideoApe extends Ape { @@ -113,7 +115,7 @@ class VideoApe extends Ape {
113 loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels); 115 loger.log('stopPublishVideo -> maxVideoChannels', GlobalConfig.maxVideoChannels);
114 //_param如果为空,那么默认就是当前自己的nodeId,否则用_param 116 //_param如果为空,那么默认就是当前自己的nodeId,否则用_param
115 let nodeId; 117 let nodeId;
116 - if(_param&&parseInt(_param.nodeId)>=0){ 118 + if(_param&&parseInt(_param.nodeId)>0){
117 nodeId=parseInt(_param.nodeId); 119 nodeId=parseInt(_param.nodeId);
118 }else { 120 }else {
119 nodeId=GlobalConfig.nodeId; 121 nodeId=GlobalConfig.nodeId;
@@ -121,8 +123,8 @@ class VideoApe extends Ape { @@ -121,8 +123,8 @@ class VideoApe extends Ape {
121 123
122 let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId); 124 let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId);
123 if (openingChannel == 0) { 125 if (openingChannel == 0) {
124 - loger.warn(nodeId,"stopPublishVideo,没有占用channel,不需要关闭");  
125 - return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel,不需要关闭"}; 126 + loger.warn(nodeId,"没有占用channel不需要处理");
  127 + return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};
126 } 128 }
127 129
128 let channelInfo={}; 130 let channelInfo={};
@@ -267,9 +269,44 @@ class VideoApe extends Ape { @@ -267,9 +269,44 @@ class VideoApe extends Ape {
267 269
268 tableUpdateHandler(owner, itemIdx, itemData) { 270 tableUpdateHandler(owner, itemIdx, itemData) {
269 // debugger; 271 // debugger;
270 - let videoChannelInfo = this.unPackPdu(owner, itemIdx, itemData);  
271 - this.mediaModule.mediaChannels[itemIdx] = videoChannelInfo;  
272 - this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo); 272 + let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);
  273 + this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;
  274 +
  275 + if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){
  276 + let receiveChannelInfo={};
  277 + receiveChannelInfo.mediaId=unpackChannelInfo.channelId;
  278 +
  279 + //消息不是自己同步的,需要处理
  280 + if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){
  281 + //正在推流
  282 + receiveChannelInfo.m3u8Url="";
  283 + receiveChannelInfo.rtmpUrl="";
  284 + let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});
  285 + let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});
  286 +
  287 + if(m3u8Stream.code==0){
  288 + receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;
  289 + }
  290 + if(rtmpStream.code==0){
  291 + receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;
  292 + }
  293 + loger.log("VIDEO_PLAY");
  294 + console.log(receiveChannelInfo);
  295 + //广播播放视频的消息
  296 + this._emit(MessageTypes.VIDEO_PLAY, receiveChannelInfo);
  297 + }else {
  298 + loger.log("VIDEO_STOP");
  299 + console.log(receiveChannelInfo);
  300 + //流已经停止
  301 + this._emit(MessageTypes.VIDEO_STOP, receiveChannelInfo);
  302 + }
  303 + }else {
  304 + loger.warn("视频消息是自己发送的或者是视频消息无效,不需要处理,消息内容如下:");
  305 + console.log(unpackChannelInfo);
  306 +
  307 + }
  308 +
  309 + //this._emit(MessageTypes.VIDEO_UPDATE, videoChannelInfo);
273 } 310 }
274 311
275 ///////数据的封包和解包///////////////////////////////////////// 312 ///////数据的封包和解包/////////////////////////////////////////
@@ -285,6 +322,7 @@ class VideoApe extends Ape { @@ -285,6 +322,7 @@ class VideoApe extends Ape {
285 let packPduModel = new pdu['RCVideoChannelInfoPdu']; 322 let packPduModel = new pdu['RCVideoChannelInfoPdu'];
286 packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED; 323 packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;
287 packPduModel.channelId = _itemIdx; 324 packPduModel.channelId = _itemIdx;
  325 + packPduModel.streamId = _param.streamId||"";
288 packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId; 326 packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId;
289 packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId); 327 packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);
290 packPduModel.userId =_param.userId||"0"; 328 packPduModel.userId =_param.userId||"0";
@@ -305,7 +343,7 @@ class VideoApe extends Ape { @@ -305,7 +343,7 @@ class VideoApe extends Ape {
305 try { 343 try {
306 344
307 let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData); 345 let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);
308 - loger.log("unPackPdu",videoChannelInfo); 346 + console.log(videoChannelInfo);
309 return videoChannelInfo; 347 return videoChannelInfo;
310 } catch (err) { 348 } catch (err) {
311 loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message); 349 loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);
@@ -98,7 +98,7 @@ class MCU extends Emiter { @@ -98,7 +98,7 @@ class MCU extends Emiter {
98 case PduConsts.RET_SUCCESS: 98 case PduConsts.RET_SUCCESS:
99 //加入成功 99 //加入成功
100 this._updateMCUConfInfoDescription(joinConfPdu.classDescription); 100 this._updateMCUConfInfoDescription(joinConfPdu.classDescription);
101 - this._emit(MessageTypes.CLASS_JOIN_SUCCESS, this.classInfo); 101 + this._emit(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this.classInfo);
102 break; 102 break;
103 case PduConsts.RET_FULL_CAPACITY: 103 case PduConsts.RET_FULL_CAPACITY:
104 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FULL); 104 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_CLASS_JOIN_FULL);
@@ -776,6 +776,7 @@ message RCAudioChannelInfoPdu { @@ -776,6 +776,7 @@ message RCAudioChannelInfoPdu {
776 optional uint32 class_id = 7;//课堂号 776 optional uint32 class_id = 7;//课堂号
777 optional string site_id = 8;//站点号 777 optional string site_id = 8;//站点号
778 optional string user_id = 9;//用户的userId 778 optional string user_id = 9;//用户的userId
  779 + optional string stream_id = 10;//流名称
779 } 780 }
780 781
781 message RCVideoChannelInfoPdu { 782 message RCVideoChannelInfoPdu {
@@ -788,6 +789,7 @@ message RCVideoChannelInfoPdu { @@ -788,6 +789,7 @@ message RCVideoChannelInfoPdu {
788 optional uint32 class_id = 7;//课堂号 789 optional uint32 class_id = 7;//课堂号
789 optional string site_id = 8;//站点号 790 optional string site_id = 8;//站点号
790 optional string user_id = 9;//用户的userId 791 optional string user_id = 9;//用户的userId
  792 + optional string stream_id = 10;//流名称
791 } 793 }
792 794
793 message RCVideoChannelInfoRecordPdu { 795 message RCVideoChannelInfoRecordPdu {