AlexWang

实际内部Confer内部处理用户禁言及全局禁言

PDU新增字段
@@ -18,956 +18,994 @@ import Sass from 'Sass'; @@ -18,956 +18,994 @@ import Sass from 'Sass';
18 let loger = Loger.getLoger('ConferApe'); 18 let loger = Loger.getLoger('ConferApe');
19 19
20 class ConferApe extends Ape { 20 class ConferApe extends Ape {
21 - constructor() {  
22 - super(  
23 - ApeConsts.CONFERENCE_SESSION_ID,  
24 - ApeConsts.CONFERENCE_SESSION_NAME,  
25 - ApeConsts.CONFERENCE_SESSION_TAG  
26 - ); 21 + constructor() {
  22 + super(
  23 + ApeConsts.CONFERENCE_SESSION_ID,
  24 + ApeConsts.CONFERENCE_SESSION_NAME,
  25 + ApeConsts.CONFERENCE_SESSION_TAG
  26 + );
27 27
28 - this.rosters = {};//用户列表  
29 - this.timerCounter = new TimerCounter();//计时器 28 + this.rosters = {}; //用户列表
  29 + this.timerCounter = new TimerCounter(); //计时器
30 30
31 - //第三方消息控制 parent和Iframe直接的通讯  
32 - this.thirdMessage=new ThirdMessage();  
33 - this.thirdMessage.on(ThirdMessage.RECIVE_MESSAGE,this.onThirdReciveParentMessage.bind(this)); 31 + //第三方消息控制 parent和Iframe直接的通讯
  32 + this.thirdMessage = new ThirdMessage();
  33 + this.thirdMessage.on(ThirdMessage.RECIVE_MESSAGE, this.onThirdReciveParentMessage.bind(this));
34 34
35 - // Ape Models  
36 - this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); 35 + // Ape Models
  36 + this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
37 37
38 - this.registerObj(pdu.RCPDU_REG_REGISTER_ROSTER, ApeConsts.CONFERENCE_OBJ_ROSTER_ID,  
39 - ApeConsts.CONFERENCE_OBJ_ROSTER_NAME, ApeConsts.CONFERENCE_OBJ_ROSTER_TAG, 0, new ArrayBuffer); 38 + this.registerObj(pdu.RCPDU_REG_REGISTER_ROSTER, ApeConsts.CONFERENCE_OBJ_ROSTER_ID,
  39 + ApeConsts.CONFERENCE_OBJ_ROSTER_NAME, ApeConsts.CONFERENCE_OBJ_ROSTER_TAG, 0, new ArrayBuffer);
40 40
41 - this.registerObj(pdu.RCPDU_REG_REGISTER_QUEUE, ApeConsts.CONFERENCE_OBJ_QUEUE_ID,  
42 - ApeConsts.CONFERENCE_OBJ_QUEUE_NAME, ApeConsts.CONFERENCE_OBJ_QUEUE_TAG, 0, new ArrayBuffer); 41 + this.registerObj(pdu.RCPDU_REG_REGISTER_QUEUE, ApeConsts.CONFERENCE_OBJ_QUEUE_ID,
  42 + ApeConsts.CONFERENCE_OBJ_QUEUE_NAME, ApeConsts.CONFERENCE_OBJ_QUEUE_TAG, 0, new ArrayBuffer);
43 43
44 - this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CONFERENCE_OBJ_TABLE_ID,  
45 - ApeConsts.CONFERENCE_OBJ_TABLE_NAME, ApeConsts.CONFERENCE_OBJ_TABLE_TAG, 0, new ArrayBuffer); 44 + this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CONFERENCE_OBJ_TABLE_ID,
  45 + ApeConsts.CONFERENCE_OBJ_TABLE_NAME, ApeConsts.CONFERENCE_OBJ_TABLE_TAG, 0, new ArrayBuffer);
46 46
47 - this.registerObj(pdu.RCPDU_REG_REGISTER_COUNTER, ApeConsts.CONFERENCE_OBJ_COUNTER_ID,  
48 - ApeConsts.CONFERENCE_OBJ_COUNTER_NAME, ApeConsts.CONFERENCE_OBJ_COUNTER_TAG, 0, new ArrayBuffer); 47 + this.registerObj(pdu.RCPDU_REG_REGISTER_COUNTER, ApeConsts.CONFERENCE_OBJ_COUNTER_ID,
  48 + ApeConsts.CONFERENCE_OBJ_COUNTER_NAME, ApeConsts.CONFERENCE_OBJ_COUNTER_TAG, 0, new ArrayBuffer);
49 49
50 - this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this)); 50 + this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
51 51
52 - this.on(pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是课堂消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理  
53 - this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST, this.onSendConferRecordRequestHandler.bind(this));//发送录制和停止录制消息  
54 - this.on(pdu.RCPDU_THIRD_BROADCAST_DATA_REQUEST, this.onThirdBroadcastDataHandler.bind(this));//第三方广播消息  
55 - } 52 + this.on(pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST, this.conferMsgComingHandler.bind(this)); //这个是课堂消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
  53 + this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST, this.onSendConferRecordRequestHandler.bind(this)); //发送录制和停止录制消息
  54 + this.on(pdu.RCPDU_THIRD_BROADCAST_DATA_REQUEST, this.onThirdBroadcastDataHandler.bind(this)); //第三方广播消息
  55 + }
56 56
57 - //加入课堂  
58 - _joinSessionHandler(_data) {  
59 - //let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;  
60 - let nodeInfoRecordPdu = this.getNodeInfo(); 57 + //加入课堂
  58 + _joinSessionHandler(_data) {
  59 + //let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
  60 + let nodeInfoRecordPdu = this.getNodeInfo();
61 61
62 - let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];  
63 - userDataPdu.qq = '';  
64 - userDataPdu.skype = ''; 62 + let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
  63 + userDataPdu.qq = '';
  64 + userDataPdu.skype = '';
65 65
66 - nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();  
67 - nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType;//设备类型 66 + nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
  67 + nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType; //设备类型
68 68
69 - loger.log('开始加入->',nodeInfoRecordPdu); 69 + loger.log('开始加入->', nodeInfoRecordPdu);
70 70
71 - let item = new pdu['RCRegistryRosterItemPdu'];  
72 - item.nodeId = nodeInfoRecordPdu.nodeId;  
73 - item.nodeData = nodeInfoRecordPdu.toArrayBuffer(); 71 + let item = new pdu['RCRegistryRosterItemPdu'];
  72 + item.nodeId = nodeInfoRecordPdu.nodeId;
  73 + item.nodeData = nodeInfoRecordPdu.toArrayBuffer();
74 74
75 - let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];  
76 - rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;  
77 - rosterUpdateItem.items.push(item); 75 + let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];
  76 + rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;
  77 + rosterUpdateItem.items.push(item);
78 78
79 - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];  
80 - updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;  
81 - updateObjPdu.subType = rosterUpdateItem.type;  
82 - updateObjPdu.userData = rosterUpdateItem.toArrayBuffer(); 79 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  80 + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
  81 + updateObjPdu.subType = rosterUpdateItem.type;
  82 + updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();
83 83
84 - //同步  
85 - let adapterItemPdu = new pdu['RCAdapterItemPdu'];  
86 - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;  
87 - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer(); 84 + //同步
  85 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  86 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  87 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
88 88
89 - let adapterPdu = new pdu['RCAdapterPdu'];  
90 - adapterPdu.type = pdu.RCPDU_REG_ADAPTER;  
91 - adapterPdu.item.push(adapterItemPdu);  
92 - this.sendUniform(adapterPdu, true); 89 + let adapterPdu = new pdu['RCAdapterPdu'];
  90 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  91 + adapterPdu.item.push(adapterItemPdu);
  92 + this.sendUniform(adapterPdu, true);
93 } 93 }
94 //获取角色信息 94 //获取角色信息
95 - getNodeInfo(){  
96 - let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu'];  
97 - nodeInfoRecordPdu.nodeId= GlobalConfig.nodeId;  
98 - nodeInfoRecordPdu.name= GlobalConfig.userName;  
99 - nodeInfoRecordPdu.role= ApeConsts.userTypesToId[GlobalConfig.userRole] || 1; //NR_NORMAL用户的身份,根据用户登录时的身份设置;  
100 - nodeInfoRecordPdu.level= GlobalConfig.level;  
101 - //nodeInfoRecordPdu.audioRecords= GlobalConfig.audioRecords;  
102 - //nodeInfoRecordPdu.videoRecords= GlobalConfig.videoRecords;  
103 - //nodeInfoRecordPdu.status= GlobalConfig.status;  
104 - nodeInfoRecordPdu.userData= GlobalConfig.userData;  
105 - nodeInfoRecordPdu.userId= GlobalConfig.userId;  
106 - nodeInfoRecordPdu.handUpTime= GlobalConfig.handUpTime;  
107 - //nodeInfoRecordPdu.deviceType= GlobalConfig.deviceType;  
108 - //nodeInfoRecordPdu.mobileDirection= GlobalConfig.mobileDirection;  
109 - nodeInfoRecordPdu.microphones= GlobalConfig.microphones;  
110 - nodeInfoRecordPdu.cameras= GlobalConfig.cameras;  
111 - nodeInfoRecordPdu.openCamera= GlobalConfig.openCamera;  
112 - nodeInfoRecordPdu.openMicrophones= GlobalConfig.openMicrophones;  
113 - nodeInfoRecordPdu.videoQuality= GlobalConfig.videoQuality;  
114 - nodeInfoRecordPdu.userIp= GlobalConfig.userIp;  
115 -  
116 - nodeInfoRecordPdu.curVideoQuality=GlobalConfig.curVideoQuality;  
117 - nodeInfoRecordPdu.micGain= GlobalConfig.micGain;  
118 - nodeInfoRecordPdu.speakerVolume=GlobalConfig.speakerVolume;  
119 - nodeInfoRecordPdu.micCode= GlobalConfig.micCode;  
120 - nodeInfoRecordPdu.curCamera=GlobalConfig.curCamera;  
121 - nodeInfoRecordPdu.curMicrophone=GlobalConfig.curMicrophone;  
122 -  
123 -  
124 - nodeInfoRecordPdu.country=GlobalConfig.country ;//国家  
125 - nodeInfoRecordPdu.city=GlobalConfig.city ;//城市  
126 - nodeInfoRecordPdu.province= GlobalConfig.province;//服务商  
127 - nodeInfoRecordPdu.isp=GlobalConfig.isp;//服务商  
128 -  
129 - //用户的MS列表  
130 - let msListAll=GlobalConfig.msListAll;  
131 - for(let k=0;k<msListAll.length;k++){  
132 - let msItem=msListAll[k];  
133 - if(msItem){  
134 - let msListItemPdu = new pdu['MsListItemPdu'];  
135 - msListItemPdu.ip=msItem.ip||"";  
136 - msListItemPdu.port=msItem.port||"";  
137 - msListItemPdu.country=msItem.country||"";  
138 - msListItemPdu.province=msItem.province||"";  
139 - msListItemPdu.city=msItem.city||"";  
140 - nodeInfoRecordPdu.msList.push(msListItemPdu);  
141 - }  
142 - }  
143 - return nodeInfoRecordPdu;  
144 - }  
145 -  
146 - //更新角色数据  
147 - updateUserInfo(){  
148 - let nodeInfoRecordPdu = this.getNodeInfo();  
149 - loger.log('更新用户信息->',nodeInfoRecordPdu);  
150 - let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];  
151 - userDataPdu.qq = '';  
152 - userDataPdu.skype = '';  
153 -  
154 - nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();  
155 - nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType;//设备类型  
156 -  
157 - let item = new pdu['RCRegistryRosterItemPdu'];  
158 - item.nodeId = nodeInfoRecordPdu.nodeId;  
159 - item.nodeData = nodeInfoRecordPdu.toArrayBuffer();  
160 -  
161 - let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];  
162 - rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;  
163 - rosterUpdateItem.items.push(item);  
164 -  
165 - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];  
166 - updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;  
167 - updateObjPdu.subType = rosterUpdateItem.type;  
168 - updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();  
169 -  
170 - //同步  
171 - let adapterItemPdu = new pdu['RCAdapterItemPdu'];  
172 - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;  
173 - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();  
174 -  
175 - let adapterPdu = new pdu['RCAdapterPdu'];  
176 - adapterPdu.type = pdu.RCPDU_REG_ADAPTER;  
177 - adapterPdu.item.push(adapterItemPdu);  
178 - this.sendUniform(adapterPdu, true);  
179 - }  
180 -  
181 - sendConferMsg(_messageInfo) {  
182 - if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) {  
183 - loger.log('不能发送课堂消息.McuClient还未初始化数据!');  
184 - if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {  
185 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);  
186 - return;  
187 - }  
188 - return;  
189 - }  
190 -  
191 - // to, message  
192 - loger.log('发送课堂控制消息.', _messageInfo);  
193 -  
194 - let conferSendPdu = new pdu['RCConferenceSendDataRequestPdu'];  
195 - conferSendPdu.type = pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST;  
196 - conferSendPdu.initiator = this._classInfo.nodeId;//发起人  
197 - conferSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id  
198 -  
199 - conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);  
200 - //conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);  
201 - conferSendPdu.isPublic = true;  
202 - conferSendPdu.actionType = _messageInfo.actionType;  
203 - // if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {  
204 - if (!conferSendPdu.isPublic && 0 != conferSendPdu.peer) {  
205 - //发送给制定的人  
206 - //loger.log('发送私聊课堂消息.');  
207 - this.send(conferSendPdu);  
208 - } else {  
209 - //发送给所有人  
210 - // loger.log('发送公聊课堂消息.');  
211 - this.sendChatUniform(conferSendPdu);  
212 - }  
213 - }  
214 -  
215 - //发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制  
216 - sendConferRecordMsg(_param) {  
217 - if (!this.mcu.connected) {  
218 - loger.warn(GlobalConfig.getCurrentStatus());  
219 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
220 - }  
221 - if (_param == null) {  
222 - loger.warn("控制录制状的消息发送失败,参数错误", _param);  
223 - return;  
224 - }  
225 -  
226 - /* message RCConferenceRecordRequestPdu {  
227 - optional uint32 initiator = 1; // 发起录像指令的node id  
228 - optional bool record = 2; // 录像指令 true:开始录像, false:停止录像  
229 - optional uint32 class_time = 3; // 课堂进行时间(秒)  
230 - optional string filename = 4; // 录像文件名称,filename中增加目录部分  
231 - }*/  
232 -  
233 - //保存当前的录制状态  
234 - GlobalConfig.recordStatus = _param.recordStatus || false;  
235 -  
236 - let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu'];  
237 - conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST;  
238 - conferRecordSendPdu.peer = 0;//channel 为0  
239 - conferRecordSendPdu.isPublic = true;  
240 -  
241 - conferRecordSendPdu.initiator = this._classInfo.nodeId;//发起人  
242 - conferRecordSendPdu.record = GlobalConfig.recordStatus;  
243 - //conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;//不能使用课堂进行时间,这个时间结束课堂的时候会被清除  
244 - conferRecordSendPdu.classTime = GlobalConfig.recordTimestamp;//课堂录制的累积时间,不会被清除  
245 - conferRecordSendPdu.filename = GlobalConfig.recordFileName || GlobalConfig.classId + "_" + EngineUtils.creatTimestampYMD() + ".rec";  
246 - this.sendChatUniform(conferRecordSendPdu);  
247 - // to, message  
248 - loger.warn('发送录制消息-》', _param);  
249 - }  
250 -  
251 - //开启录制  
252 - startRecord() {  
253 - //如果录制的时间长超出设定的最大录制时间就不再录制  
254 - if(GlobalConfig.recordTimestamp>=GlobalConfig.allowRecordMaxTime){  
255 - loger.warn('不能再录制,录制时间已经达到最大限制',GlobalConfig.recordTimestamp);  
256 - return;  
257 - }  
258 -  
259 - loger.log('startRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);  
260 - //如果是host  
261 - if (GlobalConfig.isHost) {  
262 - GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();  
263 - this.sendConferRecordMsg({"recordStatus": true});  
264 - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);  
265 - this._emit(MessageTypes.CLASS_RECORD_START);//课堂开始录制  
266 - }  
267 - }  
268 -  
269 - //停止录制  
270 - stopRecord(isForce) {  
271 - loger.log('stopRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);  
272 - if(isForce&&isForce==true){  
273 - //强制停止,可以是host之外的身份(比如当前课堂老师异常退出,没有老师,会随机选择一个人来做释放操作)  
274 - if (GlobalConfig.recordStatus) {  
275 - GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();  
276 - this.sendConferRecordMsg({"recordStatus": false});  
277 - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);  
278 - }  
279 - }else {  
280 - //身份是host,并且当前正在录制中  
281 - if (GlobalConfig.isHost && GlobalConfig.recordStatus) {  
282 - GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();  
283 - this.sendConferRecordMsg({"recordStatus": false});  
284 - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);  
285 - }  
286 - }  
287 - }  
288 -  
289 -  
290 - //主动离开课堂,发送通知到服务器  
291 - leaveClass() {  
292 - let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;  
293 - let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];  
294 - userDataPdu.qq = '';  
295 - userDataPdu.skype = '';  
296 -  
297 - nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();  
298 - nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType;  
299 -  
300 - let item = new pdu['RCRegistryRosterItemPdu'];  
301 - item.nodeId = nodeInfoRecordPdu.nodeId;  
302 - item.nodeData = nodeInfoRecordPdu.toArrayBuffer();  
303 -  
304 - let rosterUpdateItem = new pdu['RCRegistryRosterDeleteItemPdu'];  
305 - rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_DELETE_PDU;  
306 - rosterUpdateItem.nodeId = GlobalConfig.nodeId;  
307 -  
308 - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];  
309 - updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;  
310 - updateObjPdu.subType = rosterUpdateItem.type;  
311 - updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();  
312 -  
313 - let adapterItemPdu = new pdu['RCAdapterItemPdu'];  
314 - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;  
315 - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();  
316 -  
317 - let adapterPdu = new pdu['RCAdapterPdu'];  
318 - adapterPdu.type = pdu.RCPDU_REG_ADAPTER;  
319 - adapterPdu.item.push(adapterItemPdu);  
320 -  
321 - this.sendUniform(adapterPdu, true);  
322 - }  
323 -  
324 - //还原课堂状态  
325 - restorClass() {  
326 - GlobalConfig.classTimestamp = 0;  
327 - GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_WAIT; 95 + getNodeInfo() {
  96 + let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu'];
  97 + nodeInfoRecordPdu.nodeId = GlobalConfig.nodeId;
  98 + nodeInfoRecordPdu.selfSilence = JSON.stringify(GlobalConfig.selfSilence);
  99 + nodeInfoRecordPdu.name = GlobalConfig.userName;
  100 + nodeInfoRecordPdu.role = ApeConsts.userTypesToId[GlobalConfig.userRole] || 1; //NR_NORMAL用户的身份,根据用户登录时的身份设置;
  101 + nodeInfoRecordPdu.level = GlobalConfig.level;
  102 + //nodeInfoRecordPdu.audioRecords= GlobalConfig.audioRecords;
  103 + //nodeInfoRecordPdu.videoRecords= GlobalConfig.videoRecords;
  104 + //nodeInfoRecordPdu.status= GlobalConfig.status;
  105 + nodeInfoRecordPdu.userData = GlobalConfig.userData;
  106 + nodeInfoRecordPdu.userId = GlobalConfig.userId;
  107 + nodeInfoRecordPdu.handUpTime = GlobalConfig.handUpTime;
  108 + //nodeInfoRecordPdu.deviceType= GlobalConfig.deviceType;
  109 + //nodeInfoRecordPdu.mobileDirection= GlobalConfig.mobileDirection;
  110 + nodeInfoRecordPdu.microphones = GlobalConfig.microphones;
  111 + nodeInfoRecordPdu.cameras = GlobalConfig.cameras;
  112 + nodeInfoRecordPdu.openCamera = GlobalConfig.openCamera;
  113 + nodeInfoRecordPdu.openMicrophones = GlobalConfig.openMicrophones;
  114 + nodeInfoRecordPdu.videoQuality = GlobalConfig.videoQuality;
  115 + nodeInfoRecordPdu.userIp = GlobalConfig.userIp;
  116 +
  117 + nodeInfoRecordPdu.curVideoQuality = GlobalConfig.curVideoQuality;
  118 + nodeInfoRecordPdu.micGain = GlobalConfig.micGain;
  119 + nodeInfoRecordPdu.speakerVolume = GlobalConfig.speakerVolume;
  120 + nodeInfoRecordPdu.micCode = GlobalConfig.micCode;
  121 + nodeInfoRecordPdu.curCamera = GlobalConfig.curCamera;
  122 + nodeInfoRecordPdu.curMicrophone = GlobalConfig.curMicrophone;
  123 +
  124 + nodeInfoRecordPdu.country = GlobalConfig.country; //国家
  125 + nodeInfoRecordPdu.city = GlobalConfig.city; //城市
  126 + nodeInfoRecordPdu.province = GlobalConfig.province; //服务商
  127 + nodeInfoRecordPdu.isp = GlobalConfig.isp; //服务商
  128 +
  129 + //用户的MS列表
  130 + let msListAll = GlobalConfig.msListAll;
  131 + for (let k = 0; k < msListAll.length; k++) {
  132 + let msItem = msListAll[k];
  133 + if (msItem) {
  134 + let msListItemPdu = new pdu['MsListItemPdu'];
  135 + msListItemPdu.ip = msItem.ip || "";
  136 + msListItemPdu.port = msItem.port || "";
  137 + msListItemPdu.country = msItem.country || "";
  138 + msListItemPdu.province = msItem.province || "";
  139 + msListItemPdu.city = msItem.city || "";
  140 + nodeInfoRecordPdu.msList.push(msListItemPdu);
  141 + }
  142 + }
  143 + return nodeInfoRecordPdu;
  144 + }
  145 +
  146 + //更新角色数据
  147 + updateUserInfo() {
  148 + let nodeInfoRecordPdu = this.getNodeInfo();
  149 + loger.log('更新用户信息->', nodeInfoRecordPdu);
  150 + let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
  151 + userDataPdu.qq = '';
  152 + userDataPdu.skype = '';
  153 +
  154 + nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
  155 + nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType; //设备类型
  156 +
  157 + let item = new pdu['RCRegistryRosterItemPdu'];
  158 + item.nodeId = nodeInfoRecordPdu.nodeId;
  159 + item.nodeData = nodeInfoRecordPdu.toArrayBuffer();
  160 +
  161 + let rosterUpdateItem = new pdu['RCRegistryRosterUpdateItemPdu'];
  162 + rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_UPDATE_PDU;
  163 + rosterUpdateItem.items.push(item);
  164 +
  165 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  166 + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
  167 + updateObjPdu.subType = rosterUpdateItem.type;
  168 + updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();
  169 +
  170 + //同步
  171 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  172 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  173 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  174 +
  175 + let adapterPdu = new pdu['RCAdapterPdu'];
  176 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  177 + adapterPdu.item.push(adapterItemPdu);
  178 + this.sendUniform(adapterPdu, true);
  179 + }
  180 +
  181 + sendConferMsg(_messageInfo) {
  182 + if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) {
  183 + loger.log('不能发送课堂消息.McuClient还未初始化数据!');
  184 + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
  185 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
  186 + return;
  187 + }
  188 + return;
  189 + }
  190 +
  191 + // to, message
  192 + loger.log('发送课堂控制消息.', _messageInfo);
  193 +
  194 + let conferSendPdu = new pdu['RCConferenceSendDataRequestPdu'];
  195 + conferSendPdu.type = pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST;
  196 + conferSendPdu.initiator = this._classInfo.nodeId; //发起人
  197 + conferSendPdu.peer = parseInt(_messageInfo.to); //发送给谁,公聊的时候是0,私聊的时候是指定的用户id
  198 +
  199 + conferSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);
  200 + //conferSendPdu.userData =UTF8.setBytesFromString(_messageInfo.message);
  201 + conferSendPdu.isPublic = true;
  202 + conferSendPdu.actionType = _messageInfo.actionType;
  203 + // if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {
  204 + if (!conferSendPdu.isPublic && 0 != conferSendPdu.peer) {
  205 + //发送给制定的人
  206 + //loger.log('发送私聊课堂消息.');
  207 + this.send(conferSendPdu);
  208 + } else {
  209 + //发送给所有人
  210 + // loger.log('发送公聊课堂消息.');
  211 + this.sendChatUniform(conferSendPdu);
  212 + }
  213 + }
  214 +
  215 + //发送录制或停止录制的消息,{"recordStatus":true};true为开始录制,false为停止录制
  216 + sendConferRecordMsg(_param) {
  217 + if (!this.mcu.connected) {
  218 + loger.warn(GlobalConfig.getCurrentStatus());
  219 + return { "code": ApeConsts.RETURN_FAILED, "data": "已经断开连接" };
  220 + }
  221 + if (_param == null) {
  222 + loger.warn("控制录制状的消息发送失败,参数错误", _param);
  223 + return;
  224 + }
  225 +
  226 + /* message RCConferenceRecordRequestPdu {
  227 + optional uint32 initiator = 1; // 发起录像指令的node id
  228 + optional bool record = 2; // 录像指令 true:开始录像, false:停止录像
  229 + optional uint32 class_time = 3; // 课堂进行时间(秒)
  230 + optional string filename = 4; // 录像文件名称,filename中增加目录部分
  231 + }*/
  232 +
  233 + //保存当前的录制状态
  234 + GlobalConfig.recordStatus = _param.recordStatus || false;
  235 +
  236 + let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu'];
  237 + conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST;
  238 + conferRecordSendPdu.peer = 0; //channel 为0
  239 + conferRecordSendPdu.isPublic = true;
  240 +
  241 + conferRecordSendPdu.initiator = this._classInfo.nodeId; //发起人
  242 + conferRecordSendPdu.record = GlobalConfig.recordStatus;
  243 + //conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;//不能使用课堂进行时间,这个时间结束课堂的时候会被清除
  244 + conferRecordSendPdu.classTime = GlobalConfig.recordTimestamp; //课堂录制的累积时间,不会被清除
  245 + conferRecordSendPdu.filename = GlobalConfig.recordFileName || GlobalConfig.classId + "_" + EngineUtils.creatTimestampYMD() + ".rec";
  246 + this.sendChatUniform(conferRecordSendPdu);
  247 + // to, message
  248 + loger.warn('发送录制消息-》', _param);
  249 + }
  250 +
  251 + //开启录制
  252 + startRecord() {
  253 + //如果录制的时间长超出设定的最大录制时间就不再录制
  254 + if (GlobalConfig.recordTimestamp >= GlobalConfig.allowRecordMaxTime) {
  255 + loger.warn('不能再录制,录制时间已经达到最大限制', GlobalConfig.recordTimestamp);
  256 + return;
  257 + }
  258 +
  259 + loger.log('startRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
  260 + //如果是host
  261 + if (GlobalConfig.isHost) {
  262 + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
  263 + this.sendConferRecordMsg({ "recordStatus": true });
  264 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  265 + this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制
  266 + }
  267 + }
  268 +
  269 + //停止录制
  270 + stopRecord(isForce) {
  271 + loger.log('stopRecord', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
  272 + if (isForce && isForce == true) {
  273 + //强制停止,可以是host之外的身份(比如当前课堂老师异常退出,没有老师,会随机选择一个人来做释放操作)
  274 + if (GlobalConfig.recordStatus) {
328 GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); 275 GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
329 - this.stopRecord(); 276 + this.sendConferRecordMsg({ "recordStatus": false });
330 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 277 this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
331 - this.sendUpdaterClassStatusInfo({"actionType": 0,isStopAllPublishMedia:true});  
332 - loger.log('restorClass');  
333 - }  
334 -  
335 - //开始上课  
336 - startClass(_param) {  
337 - if (GlobalConfig.isHost) {  
338 -  
339 - let timestamp = EngineUtils.creatTimestampStr();  
340 - GlobalConfig.classStopTime = timestamp;  
341 -  
342 - //如果录制的文件名不存在,需要创建一个名字  
343 - let timestampYMD = EngineUtils.creatTimestampYMD();  
344 - GlobalConfig.recordFileName = GlobalConfig.recordFileName ||  
345 - GlobalConfig.siteId + "/" + timestampYMD + "/"  
346 - + GlobalConfig.classId + "_" + timestampYMD + ".rec";//4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename`  
347 -  
348 - if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {  
349 - //之前是为开始状态,第一次点开始  
350 - GlobalConfig.classStartTime = timestamp;  
351 - }  
352 -  
353 - GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_STARTED;  
354 - //开始录制  
355 - this.startRecord();  
356 - //课堂状态改变  
357 - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);  
358 - //同步课堂状态  
359 - this.sendUpdaterClassStatusInfo({"actionType": 1,isStopAllPublishMedia:true});  
360 -  
361 - //开始计时  
362 - this.startTimerCounter();  
363 - } else {  
364 - loger.warn('没有开始课堂的权限');  
365 - }  
366 - }  
367 -  
368 - //暂停上课 {isForce:true} isForce->是否强制提交(true为是)  
369 - pauseClass(_param) {  
370 - if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {  
371 - loger.warn('还没有开始,不能点暂停');  
372 - return;  
373 - }  
374 - GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_PAUSE; 278 + }
  279 + } else {
  280 + //身份是host,并且当前正在录制中
  281 + if (GlobalConfig.isHost && GlobalConfig.recordStatus) {
375 GlobalConfig.classStopTime = EngineUtils.creatTimestampStr(); 282 GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
376 -  
377 - this.stopRecord();  
378 - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE,_param);  
379 - this.sendUpdaterClassStatusInfo({"actionType": 2,isStopAllPublishMedia:true});  
380 - this.stopTimerCounter();  
381 - }  
382 -  
383 - //关闭课堂  
384 - closeClass(_param) {  
385 - if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {  
386 - loger.warn('还没有开始,不能点关闭');  
387 - return;  
388 - }  
389 -  
390 - this.stopTimerCounter();  
391 - this.restorClass();  
392 - //把所有人都踢出课堂  
393 - this.sendConferMsg({"to": 0, "message": "所有人退出课堂", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL}); 283 + this.sendConferRecordMsg({ "recordStatus": false });
  284 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  285 + }
  286 + }
  287 + }
  288 +
  289 + //主动离开课堂,发送通知到服务器
  290 + leaveClass() {
  291 + let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
  292 + let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
  293 + userDataPdu.qq = '';
  294 + userDataPdu.skype = '';
  295 +
  296 + nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
  297 + nodeInfoRecordPdu.deviceType = GlobalConfig.deviceType;
  298 +
  299 + let item = new pdu['RCRegistryRosterItemPdu'];
  300 + item.nodeId = nodeInfoRecordPdu.nodeId;
  301 + item.nodeData = nodeInfoRecordPdu.toArrayBuffer();
  302 +
  303 + let rosterUpdateItem = new pdu['RCRegistryRosterDeleteItemPdu'];
  304 + rosterUpdateItem.type = pdu.RCPDU_REG_ROSTER_DELETE_PDU;
  305 + rosterUpdateItem.nodeId = GlobalConfig.nodeId;
  306 +
  307 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  308 + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_ROSTER_ID;
  309 + updateObjPdu.subType = rosterUpdateItem.type;
  310 + updateObjPdu.userData = rosterUpdateItem.toArrayBuffer();
  311 +
  312 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  313 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  314 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  315 +
  316 + let adapterPdu = new pdu['RCAdapterPdu'];
  317 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  318 + adapterPdu.item.push(adapterItemPdu);
  319 +
  320 + this.sendUniform(adapterPdu, true);
  321 + }
  322 +
  323 + //还原课堂状态
  324 + restorClass() {
  325 + GlobalConfig.classTimestamp = 0;
  326 + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_WAIT;
  327 + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
  328 + this.stopRecord();
  329 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  330 + this.sendUpdaterClassStatusInfo({ "actionType": 0, isStopAllPublishMedia: true });
  331 + loger.log('restorClass');
  332 + }
  333 +
  334 + // 全局禁言
  335 + silenceClass(isSilence) {
  336 + if (GlobalConfig.isHost) {
  337 + GlobalConfig.silence = !!isSilence;
  338 +
  339 + //禁言状态改变
  340 + this._emit(MessageTypes.CLASS_SILENCE_CHANGE, GlobalConfig.silence);
  341 +
  342 + //同步禁言状态
  343 + this.sendUpdaterClassStatusInfo();
  344 + } else {
  345 + loger.warn('没有开始课堂的权限');
  346 + }
  347 + }
  348 +
  349 + //开始上课
  350 + startClass(_param) {
  351 + if (GlobalConfig.isHost) {
  352 +
  353 + let timestamp = EngineUtils.creatTimestampStr();
  354 + GlobalConfig.classStopTime = timestamp;
  355 +
  356 + //如果录制的文件名不存在,需要创建一个名字
  357 + let timestampYMD = EngineUtils.creatTimestampYMD();
  358 + GlobalConfig.recordFileName = GlobalConfig.recordFileName ||
  359 + GlobalConfig.siteId + "/" + timestampYMD + "/" + GlobalConfig.classId + "_" + timestampYMD + ".rec"; //4、文件名称 $RECORD_HOME/`site id`/`日期`/`filename` 例:/data/record/su/20161216/`filename`
  360 +
  361 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
  362 + //之前是为开始状态,第一次点开始
  363 + GlobalConfig.classStartTime = timestamp;
  364 + }
  365 +
  366 + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_STARTED;
  367 + //开始录制
  368 + this.startRecord();
  369 + //课堂状态改变
  370 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  371 + //同步课堂状态
  372 + this.sendUpdaterClassStatusInfo({ "actionType": 1, isStopAllPublishMedia: true });
  373 +
  374 + //开始计时
  375 + this.startTimerCounter();
  376 + } else {
  377 + loger.warn('没有开始课堂的权限');
  378 + }
  379 + }
  380 +
  381 + //暂停上课 {isForce:true} isForce->是否强制提交(true为是)
  382 + pauseClass(_param) {
  383 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
  384 + loger.warn('还没有开始,不能点暂停');
  385 + return;
  386 + }
  387 + GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_PAUSE;
  388 + GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
  389 +
  390 + this.stopRecord();
  391 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE, _param);
  392 + this.sendUpdaterClassStatusInfo({ "actionType": 2, isStopAllPublishMedia: true });
  393 + this.stopTimerCounter();
  394 + }
  395 +
  396 + //关闭课堂
  397 + closeClass(_param) {
  398 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT) {
  399 + loger.warn('还没有开始,不能点关闭');
  400 + return;
  401 + }
  402 +
  403 + this.stopTimerCounter();
  404 + this.restorClass();
  405 + //把所有人都踢出课堂
  406 + this.sendConferMsg({ "to": 0, "message": "所有人退出课堂", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL });
394 } 407 }
395 //更新设备信息 408 //更新设备信息
396 - updateDeviceInfo(_param){  
397 - loger.log('更新用户的设备信息->',_param);  
398 - this.updateUserInfo();  
399 - }  
400 -  
401 - //控制举手状态  
402 - controlHandUpStatus(_param){  
403 - //控制用户的举手状态  
404 - if(!_param||!_param.nodeId){  
405 - loger.log('控制举手状态->失败->参数错误',_param);  
406 - return;  
407 - }  
408 - let msgObj={};  
409 - msgObj.nodeId=_param.nodeId;  
410 - msgObj.isHandUp=false;  
411 - if(_param&&_param.isHandUp==true){  
412 - msgObj.isHandUp=true;  
413 - }  
414 - this.sendConferMsg({"to":_param.nodeId, "message":JSON.stringify(msgObj), "actionType": ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE});  
415 - }  
416 - //切换举手状态  
417 - changeHandUpStatus(_param){  
418 - loger.log('切换举手状态->',_param);  
419 - if(_param&&_param.isHandUp==true){  
420 - //举手  
421 - GlobalConfig.handUpTime=EngineUtils.creatTimestamp();  
422 - }else {  
423 - GlobalConfig.handUpTime=0;//默认0是没有举手的状态(大于0就是举手)  
424 - }  
425 - this.updateUserInfo(); 409 + updateDeviceInfo(_param) {
  410 + loger.log('更新用户的设备信息->', _param);
  411 + this.updateUserInfo();
  412 + }
  413 +
  414 + // 禁言控制
  415 + controlSilenceStatus(_param) {
  416 + //控制用户的禁言状态
  417 + if (!_param || !_param.nodeId) {
  418 + loger.log('控制禁言状态->失败->参数错误', _param);
  419 + return;
  420 + }
  421 + let msgObj = {};
  422 + msgObj.nodeId = _param.nodeId;
  423 + msgObj.silence = _param.silence || '';
  424 + this.sendConferMsg({ "to": _param.nodeId, "message": JSON.stringify(msgObj), "actionType": ApeConsts.USER_ACTION_SILENCE_STATUS_CHANGE });
  425 + }
  426 +
  427 + changeSilenceStatus(_param) {
  428 + loger.log('切换禁言状态->', _param);
  429 + GlobalConfig.selfSilence = _param.silence;
  430 + this.updateUserInfo();
  431 + }
  432 +
  433 + //控制举手状态
  434 + controlHandUpStatus(_param) {
  435 + //控制用户的举手状态
  436 + if (!_param || !_param.nodeId) {
  437 + loger.log('控制举手状态->失败->参数错误', _param);
  438 + return;
  439 + }
  440 + let msgObj = {};
  441 + msgObj.nodeId = _param.nodeId;
  442 + msgObj.isHandUp = false;
  443 + if (_param && _param.isHandUp == true) {
  444 + msgObj.isHandUp = true;
  445 + }
  446 + this.sendConferMsg({ "to": _param.nodeId, "message": JSON.stringify(msgObj), "actionType": ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE });
  447 + }
  448 +
  449 + //切换举手状态
  450 + changeHandUpStatus(_param) {
  451 + loger.log('切换举手状态->', _param);
  452 + if (_param && _param.isHandUp == true) {
  453 + //举手
  454 + GlobalConfig.handUpTime = EngineUtils.creatTimestamp();
  455 + } else {
  456 + GlobalConfig.handUpTime = 0; //默认0是没有举手的状态(大于0就是举手)
  457 + }
  458 + this.updateUserInfo();
426 } 459 }
427 //课堂的场景模块发送改变 460 //课堂的场景模块发送改变
428 - sceneTableChange(_param){  
429 - if(GlobalConfig.isRecordPlayBack){  
430 - return;  
431 - }  
432 - loger.log('切换文档-媒体-屏幕模块切换->',_param);  
433 - //如果是host身份  
434 - if (GlobalConfig.isHost) {  
435 - if(_param){  
436 - GlobalConfig.currentSceneTableId=parseInt(_param.currentSceneTableId)||0;//当前场景显示的模块 0=文档模块、1=屏幕共享、2=媒体共享  
437 - //保存数据到Sass  
438 - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);  
439 - //同步消息给其他人  
440 - this.sendUpdaterClassStatusInfo({"actionType": 1,isStopAllPublishMedia:false});  
441 - }  
442 - }  
443 - 461 + sceneTableChange(_param) {
  462 + if (GlobalConfig.isRecordPlayBack) {
  463 + return;
  464 + }
  465 + loger.log('切换文档-媒体-屏幕模块切换->', _param);
  466 + //如果是host身份
  467 + if (GlobalConfig.isHost) {
  468 + if (_param) {
  469 + GlobalConfig.currentSceneTableId = parseInt(_param.currentSceneTableId) || 0; //当前场景显示的模块 0=文档模块、1=屏幕共享、2=媒体共享
  470 + //保存数据到Sass
  471 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
  472 + //同步消息给其他人
  473 + this.sendUpdaterClassStatusInfo({ "actionType": 1, isStopAllPublishMedia: false });
  474 + }
  475 + }
444 476
445 } 477 }
446 //更新课堂信息 478 //更新课堂信息
447 - sendUpdaterClassStatusInfo(_param) {  
448 - //{"actionType": 1,isStopAllPublishMedia:false} //actionType课堂状态 isStopAllPublishMedia是否停止当前的所有推流  
449 - loger.log('发送更新课堂信息->');  
450 - if (_param == null || EngineUtils.isEmptyObject(_param)) {  
451 - loger.log('发送更新课堂信息->参数错误');  
452 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
453 - return;  
454 - }  
455 - let itemIdx = ApeConsts.CONFERENCE_OBJ_TABLE_ID;// itemIdx=_param.itemIdx;  
456 - let modelPdu = this.packPdu(_param, itemIdx);  
457 - loger.log(modelPdu);  
458 - if (modelPdu == null) {  
459 - loger.log('发送更新课堂信息->参数错误');  
460 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
461 - return;  
462 - }  
463 -  
464 - let tableItemPdu = new pdu['RCRegistryTableItemPdu'];  
465 - tableItemPdu.itemIdx = itemIdx;  
466 - tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定  
467 - tableItemPdu.registerObjId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;  
468 - tableItemPdu.itemData = modelPdu.toArrayBuffer();  
469 -  
470 -  
471 - //updater  
472 - let tableUpdateItem = new pdu['RCRegistryTableUpdateItemPdu'];  
473 - //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];  
474 - //repeated RCRegistryTableItemPdu items = 2;  
475 - tableUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//  
476 - tableUpdateItem.items.push(tableItemPdu);  
477 -  
478 -  
479 - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];  
480 - updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;  
481 - updateObjPdu.subType = tableUpdateItem.type;  
482 - updateObjPdu.userData = tableUpdateItem.toArrayBuffer();  
483 -  
484 - //同步  
485 - let adapterItemPdu = new pdu['RCAdapterItemPdu'];  
486 - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;  
487 - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();  
488 -  
489 - let adapterPdu = new pdu['RCAdapterPdu'];  
490 - adapterPdu.type = pdu.RCPDU_REG_ADAPTER;  
491 - adapterPdu.item.push(adapterItemPdu);  
492 -  
493 - this.sendUniform(adapterPdu, true);  
494 - }  
495 -  
496 -  
497 - /////收到消息处理/////////////////////////////////////////////////////////////////////////////////  
498 - //加入channel成功  
499 - onJoinChannelHandlerSuccess() {  
500 - loger.log('ConferApe.onJoinChannelHandlerSuccess', GlobalConfig.classStatus);  
501 - this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1);  
502 - //如果当前课堂正在进行中,开启计时器  
503 - if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {  
504 - //开始计时  
505 - this.startTimerCounter();  
506 -  
507 - //如果是host ,开始录制  
508 - this.startRecord();  
509 - }else if(GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT&&  
510 - GlobalConfig.isHost&& GlobalConfig.isAutoStartClass&&  
511 - !GlobalConfig.isRecordPlayBack){  
512 - //自动开始上课的4个条件  
513 - //1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课  
514 - loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:",GlobalConfig.isHost, " isAutoStartClass:",GlobalConfig.isAutoStartClass, " isRecordPlayBack:",GlobalConfig.isRecordPlayBack);  
515 - this.startClass();  
516 - }  
517 - }  
518 -  
519 - //开启计时器  
520 - startTimerCounter() {  
521 - this.stopTimerCounter();  
522 - if(this.timerCounter){  
523 - this.timerCounter.startTimer();  
524 - } 479 + sendUpdaterClassStatusInfo(_param) {
  480 + //{"actionType": 1,isStopAllPublishMedia:false} //actionType课堂状态 isStopAllPublishMedia是否停止当前的所有推流
  481 + loger.log('发送更新课堂信息->');
  482 + if (_param == null || EngineUtils.isEmptyObject(_param)) {
  483 + loger.log('发送更新课堂信息->参数错误');
  484 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  485 + return;
  486 + }
  487 + let itemIdx = ApeConsts.CONFERENCE_OBJ_TABLE_ID; // itemIdx=_param.itemIdx;
  488 + let modelPdu = this.packPdu(_param, itemIdx);
  489 + loger.log(modelPdu);
  490 + if (modelPdu == null) {
  491 + loger.log('发送更新课堂信息->参数错误');
  492 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  493 + return;
  494 + }
  495 +
  496 + let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
  497 + tableItemPdu.itemIdx = itemIdx;
  498 + tableItemPdu.owner = 0; //收到flash的是这个值,不清楚先写固定
  499 + tableItemPdu.registerObjId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;
  500 + tableItemPdu.itemData = modelPdu.toArrayBuffer();
  501 +
  502 + //updater
  503 + let tableUpdateItem = new pdu['RCRegistryTableUpdateItemPdu'];
  504 + //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
  505 + //repeated RCRegistryTableItemPdu items = 2;
  506 + tableUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU; //
  507 + tableUpdateItem.items.push(tableItemPdu);
  508 +
  509 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  510 + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_TABLE_ID;
  511 + updateObjPdu.subType = tableUpdateItem.type;
  512 + updateObjPdu.userData = tableUpdateItem.toArrayBuffer();
  513 +
  514 + //同步
  515 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  516 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  517 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  518 +
  519 + let adapterPdu = new pdu['RCAdapterPdu'];
  520 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  521 + adapterPdu.item.push(adapterItemPdu);
  522 +
  523 + this.sendUniform(adapterPdu, true);
  524 + }
  525 +
  526 + /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
  527 + //加入channel成功
  528 + onJoinChannelHandlerSuccess() {
  529 + loger.log('ConferApe.onJoinChannelHandlerSuccess', GlobalConfig.classStatus);
  530 + this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1);
  531 + //如果当前课堂正在进行中,开启计时器
  532 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
  533 + //开始计时
  534 + this.startTimerCounter();
  535 +
  536 + //如果是host ,开始录制
  537 + this.startRecord();
  538 + } else if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT &&
  539 + GlobalConfig.isHost && GlobalConfig.isAutoStartClass &&
  540 + !GlobalConfig.isRecordPlayBack) {
  541 + //自动开始上课的4个条件
  542 + //1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课
  543 + loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:", GlobalConfig.isHost, " isAutoStartClass:", GlobalConfig.isAutoStartClass, " isRecordPlayBack:", GlobalConfig.isRecordPlayBack);
  544 + this.startClass();
  545 + }
  546 + }
  547 +
  548 + //开启计时器
  549 + startTimerCounter() {
  550 + this.stopTimerCounter();
  551 + if (this.timerCounter) {
  552 + this.timerCounter.startTimer();
  553 + }
  554 +
  555 + }
  556 +
  557 + //停止计时器
  558 + stopTimerCounter() {
  559 + if (this.timerCounter) {
  560 + this.timerCounter.stopTimer();
  561 + }
  562 +
  563 + }
  564 +
  565 + timerCounterUptate() {
  566 + if (!this.mcu.connected) {
  567 + loger.warn('MCU 连接已经断开');
  568 + this.stopTimerCounter();
  569 + }
  570 + //如果还没开始或已经暂停、关闭,不做计时处理
  571 + if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {
  572 + loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);
  573 + return;
  574 + }
  575 + GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时
  576 +
  577 + //老师身份的时候要记录录制的时间
  578 + if (GlobalConfig.isHost) {
  579 + GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
  580 + }
  581 + //loger.log('课堂进行时间',GlobalConfig.classTimestamp);
  582 + this._emit(MessageTypes.CLASS_UPDATE_TIMER, { "classTimestamp": GlobalConfig.classTimestamp });
  583 +
  584 + if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
  585 + //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
  586 + if (GlobalConfig.isHost) {
  587 + //保存数据到Sass
  588 + this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
525 589
  590 + //同步消息给其他人
  591 + this.sendUpdaterClassStatusInfo({ "actionType": 1, isStopAllPublishMedia: false });
  592 + }
526 } 593 }
527 594
528 - //停止计时器  
529 - stopTimerCounter() {  
530 - if(this.timerCounter){  
531 - this.timerCounter.stopTimer();  
532 - }  
533 - 595 + //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
  596 + if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
  597 + this._emit(MessageTypes.SWITCH_MS_IP);
534 } 598 }
  599 + }
535 600
536 - timerCounterUptate() {  
537 - if (!this.mcu.connected) {  
538 - loger.warn('MCU 连接已经断开');  
539 - this.stopTimerCounter();  
540 - }  
541 - //如果还没开始或已经暂停、关闭,不做计时处理  
542 - if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {  
543 - loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);  
544 - return;  
545 - }  
546 - GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1;//计时  
547 -  
548 - //老师身份的时候要记录录制的时间  
549 - if(GlobalConfig.isHost){  
550 - GlobalConfig.recordTimestamp=GlobalConfig.recordTimestamp+1;  
551 - }  
552 - //loger.log('课堂进行时间',GlobalConfig.classTimestamp);  
553 - this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});  
554 -  
555 -  
556 - if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {  
557 - //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器  
558 - if (GlobalConfig.isHost) {  
559 - //保存数据到Sass  
560 - this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE); 601 + tableUpdateHandler(owner, itemIdx, itemData) {
  602 + try {
  603 + let model = this.unPackPdu(owner, itemIdx, itemData);
  604 + loger.log('课堂数据更新->', model);
561 605
562 - //同步消息给其他人  
563 - this.sendUpdaterClassStatusInfo({"actionType": 1,isStopAllPublishMedia:false});  
564 - }  
565 - }  
566 -  
567 - //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)  
568 - if (!GlobalConfig.isRecordPlayBack&&GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {  
569 - this._emit(MessageTypes.SWITCH_MS_IP);  
570 - }  
571 - } 606 + //处理课堂更新的信息
  607 + if (model && model.classStatusInfo) {
  608 + GlobalConfig.setClassStatusInfo(model.classStatusInfo);
572 609
573 - tableUpdateHandler(owner, itemIdx, itemData) {  
574 - try {  
575 - let model = this.unPackPdu(owner, itemIdx, itemData);  
576 - loger.log('课堂数据更新->',model);  
577 -  
578 - //处理课堂更新的信息  
579 - if (model && model.classStatusInfo) {  
580 - GlobalConfig.setClassStatusInfo(model.classStatusInfo);  
581 -  
582 - if( model.classStatusInfo.isStopAllPublishMedia){  
583 - //课堂状态发送改变 需要对当前正在推的流进行停止,因为录制的问题;  
584 - this._emit(MessageTypes.STOP_ALL_MEDIA_PUBLISH);  
585 - }  
586 - }  
587 -  
588 - //通知应用层更新课堂状态  
589 - let classInfo=GlobalConfig.classStatusInfo;  
590 - loger.log('通知应用层更新课堂状态->CLASS_UPTATE_STATUS')  
591 - this._emit(MessageTypes.CLASS_UPTATE_STATUS,classInfo);  
592 -  
593 - //如果MCU已经断开连接,停止计时器  
594 - if (!this.mcu.connected) {  
595 - //停止计时  
596 - this.stopTimerCounter();  
597 - return;  
598 - }  
599 -  
600 - if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {  
601 - //如果课堂在进行中,开始计时器  
602 - this.startTimerCounter();  
603 - } else {  
604 - //停止计时  
605 - this.stopTimerCounter();  
606 - }  
607 - } catch (err) {  
608 - loger.warn('ConferApe table update got exception->err', err.message); 610 + if (model.classStatusInfo.isStopAllPublishMedia) {
  611 + //课堂状态发送改变 需要对当前正在推的流进行停止,因为录制的问题;
  612 + this._emit(MessageTypes.STOP_ALL_MEDIA_PUBLISH);
609 } 613 }
610 - }  
611 - 614 + }
612 615
613 - conferMsgComingHandler(_data) {  
614 - //flash RCConferenceSendDataRequestPdu  
615 - //loger.warn('conferMsgComingHandler needs to be handled.');  
616 - //const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu);  
617 - //loger.log("conferMsgComingHandler",recordInfo);  
618 -  
619 - let chatReceivePdu = pdu['RCConferenceSendDataRequestPdu'].decode(_data);  
620 -  
621 - let chatMsg = {};  
622 - chatMsg.fromNodeID = chatReceivePdu.initiator;  
623 - chatMsg.toNodeID = chatReceivePdu.peer;  
624 - chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2);  
625 - chatMsg.actionType = chatReceivePdu.actionType;  
626 - loger.log("conferMsgComingHandler", chatMsg);//{"fromNodeID":418883112,"toNodeID":0,"message":"所有人退出课堂","actionType":1}  
627 - switch (chatMsg.actionType) {  
628 - case ApeConsts.CLASS_ACTION_CLOSE_ALL:  
629 - loger.log(chatMsg.message);  
630 - //收到课堂关闭,所有人都退出,执行自己关闭的流程  
631 - this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});  
632 - break;  
633 - case ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE:  
634 - console.log('chatMsg',chatMsg);  
635 - let msgObj=null;  
636 - try{  
637 - msgObj =JSON.parse(chatMsg.message);  
638 - if(msgObj&&msgObj.nodeId==GlobalConfig.nodeId){  
639 - this.changeHandUpStatus(msgObj);  
640 - }  
641 - }catch (err){  
642 - loger.warn('chatMsg->JSON数据解析失败');  
643 - }  
644 - break;  
645 - default:  
646 - break;  
647 - }  
648 - } 616 + //通知应用层更新课堂状态
  617 + let classInfo = GlobalConfig.classStatusInfo;
  618 + loger.log('通知应用层更新课堂状态->CLASS_UPTATE_STATUS')
  619 + this._emit(MessageTypes.CLASS_UPTATE_STATUS, classInfo);
649 620
650 - //-------------第三方消息------------------------------  
651 - //收到父级页面的消息,需要广播发送出去  
652 - onThirdReciveParentMessage(_msg){  
653 - loger.log('收到页面的消息->广播给其他模块->',_msg);  
654 - this.sendThirdBroadcastData({to:0,message:_msg}); 621 + //如果MCU已经断开连接,停止计时器
  622 + if (!this.mcu.connected) {
  623 + //停止计时
  624 + this.stopTimerCounter();
  625 + return;
  626 + }
  627 +
  628 + if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
  629 + //如果课堂在进行中,开始计时器
  630 + this.startTimerCounter();
  631 + } else {
  632 + //停止计时
  633 + this.stopTimerCounter();
  634 + }
  635 + } catch (err) {
  636 + loger.warn('ConferApe table update got exception->err', err.message);
  637 + }
  638 + }
  639 +
  640 + conferMsgComingHandler(_data) {
  641 + //flash RCConferenceSendDataRequestPdu
  642 + //loger.warn('conferMsgComingHandler needs to be handled.');
  643 + //const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu);
  644 + //loger.log("conferMsgComingHandler",recordInfo);
  645 +
  646 + let chatReceivePdu = pdu['RCConferenceSendDataRequestPdu'].decode(_data);
  647 +
  648 + let chatMsg = {};
  649 + chatMsg.fromNodeID = chatReceivePdu.initiator;
  650 + chatMsg.toNodeID = chatReceivePdu.peer;
  651 + chatMsg.message = this._rCArrayBufferUtil.uint8ArrayToStr(chatReceivePdu.userData, 2);
  652 + chatMsg.actionType = chatReceivePdu.actionType;
  653 + loger.log("conferMsgComingHandler", chatMsg); //{"fromNodeID":418883112,"toNodeID":0,"message":"所有人退出课堂","actionType":1}
  654 + switch (chatMsg.actionType) {
  655 + case ApeConsts.CLASS_ACTION_CLOSE_ALL:
  656 + loger.log(chatMsg.message);
  657 + //收到课堂关闭,所有人都退出,执行自己关闭的流程
  658 + this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 1 });
  659 + break;
  660 + case ApeConsts.CLASS_ACTION_HANDUP_STATUS_CHANGE:
  661 + console.log('chatMsg', chatMsg);
  662 + let msgObj = null;
  663 + try {
  664 + msgObj = JSON.parse(chatMsg.message);
  665 + if (msgObj && msgObj.nodeId == GlobalConfig.nodeId) {
  666 + this.changeHandUpStatus(msgObj);
  667 + }
  668 + } catch (err) {
  669 + loger.warn('chatMsg->JSON数据解析失败');
  670 + }
  671 + break;
  672 + case ApeConsts.USER_ACTION_SILENCE_STATUS_CHANGE:
  673 + let msgObj = null;
  674 + try {
  675 + msgObj = JSON.parse(chatMsg.message);
  676 + if (msgObj && msgObj.nodeId == GlobalConfig.nodeId) {
  677 + this.changeSilenceStatus(msgObj);
  678 + }
  679 + } catch (err) {
  680 + loger.warn('chatMsg->JSON数据解析失败');
  681 + }
  682 + break;
  683 + default:
  684 + break;
  685 + }
  686 + }
  687 +
  688 + //-------------第三方消息------------------------------
  689 + //收到父级页面的消息,需要广播发送出去
  690 + onThirdReciveParentMessage(_msg) {
  691 + loger.log('收到页面的消息->广播给其他模块->', _msg);
  692 + this.sendThirdBroadcastData({ to: 0, message: _msg });
655 } 693 }
656 //发送第三方广播消息 694 //发送第三方广播消息
657 - sendThirdBroadcastData(_param){  
658 - loger.log("发送第三方广播消息->",_param);  
659 - if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) {  
660 - loger.log('发送第三方广播消息->失败->SDK还未初始化数据!');  
661 - if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {  
662 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);  
663 - return;  
664 - }  
665 - return;  
666 - }  
667 -  
668 - let thirdBroadcastSendPdu = new pdu['RCThirdSendBroadcastDataRequestPdu'];  
669 - thirdBroadcastSendPdu.type = pdu.RCPDU_THIRD_BROADCAST_DATA_REQUEST;  
670 - thirdBroadcastSendPdu.initiator = this._classInfo.nodeId;//发起人  
671 - thirdBroadcastSendPdu.peer = parseInt(_param.to)||0;//发送给谁,公聊的时候是0,私聊的时候是指定的用户id  
672 - thirdBroadcastSendPdu.isPublic = true;  
673 - thirdBroadcastSendPdu.message = this._rCArrayBufferUtil.strToUint8Array("h5" + _param.message);  
674 -  
675 - if (!thirdBroadcastSendPdu.isPublic && 0 != thirdBroadcastSendPdu.peer) {  
676 - //发送给制定的人  
677 - this.send(thirdBroadcastSendPdu);  
678 - } else {  
679 - //发送给所有人  
680 - this.sendChatUniform(thirdBroadcastSendPdu);  
681 - }  
682 - }  
683 -  
684 -  
685 - //监听第三方消息通道消息  
686 - onThirdBroadcastDataHandler(_data){  
687 - //loger.log("监听第三方消息通道消息->",_data);  
688 - let thirdBroadcastReceivePdu = pdu['RCThirdSendBroadcastDataRequestPdu'].decode(_data);  
689 - let thirdMessage = {};  
690 - thirdMessage.fromNodeID = thirdBroadcastReceivePdu.initiator;  
691 - thirdMessage.toNodeID = thirdBroadcastReceivePdu.peer;  
692 - //loger.log("监听第三方消息通道消息->1", thirdMessage);  
693 - thirdMessage.message = this._rCArrayBufferUtil.uint8ArrayToStr(thirdBroadcastReceivePdu.message, 2);  
694 - loger.log("监听第三方消息通道消息->", thirdMessage);  
695 - if(this.thirdMessage){  
696 - this.thirdMessage.sendMessageToParent(thirdMessage.message);  
697 - }  
698 - }  
699 -  
700 - //------------------第三方消息 end-----------------------------------------  
701 -  
702 - onSendConferRecordRequestHandler(_data) {  
703 - try {  
704 - let conferRecordSendPdu = pdu['RCConferenceRecordRequestPdu'].decode(_data);  
705 - // {"initiator":820461225,"record":false,"classTime":3213,"filename":"h5dev/20170410/1437784290_20170410.rec"}  
706 - loger.log("录制回放控制操作成功->",conferRecordSendPdu);  
707 - if(conferRecordSendPdu&&conferRecordSendPdu.record==true||conferRecordSendPdu.record=="true"){  
708 - //每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件  
709 - this._emit(MessageTypes.CLASS_RECORD_SUCCESS);  
710 - }  
711 - } catch (err) {  
712 - loger.warn("录制回放控制操作错误->", err.message);  
713 - }  
714 -  
715 - }  
716 -  
717 - rosterInsertHandler(nodeId, nodeData) {  
718 - //loger.log("人员进入--->");  
719 - if (GlobalConfig.nodeId == nodeId) {  
720 -  
721 - } else {  
722 - // loger.log("有人加入 rosterInsertHandler");  
723 - this.rosterUpdateHandler(nodeId, nodeData); 695 + sendThirdBroadcastData(_param) {
  696 + loger.log("发送第三方广播消息->", _param);
  697 + if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) {
  698 + loger.log('发送第三方广播消息->失败->SDK还未初始化数据!');
  699 + if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
  700 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
  701 + return;
  702 + }
  703 + return;
  704 + }
  705 +
  706 + let thirdBroadcastSendPdu = new pdu['RCThirdSendBroadcastDataRequestPdu'];
  707 + thirdBroadcastSendPdu.type = pdu.RCPDU_THIRD_BROADCAST_DATA_REQUEST;
  708 + thirdBroadcastSendPdu.initiator = this._classInfo.nodeId; //发起人
  709 + thirdBroadcastSendPdu.peer = parseInt(_param.to) || 0; //发送给谁,公聊的时候是0,私聊的时候是指定的用户id
  710 + thirdBroadcastSendPdu.isPublic = true;
  711 + thirdBroadcastSendPdu.message = this._rCArrayBufferUtil.strToUint8Array("h5" + _param.message);
  712 +
  713 + if (!thirdBroadcastSendPdu.isPublic && 0 != thirdBroadcastSendPdu.peer) {
  714 + //发送给制定的人
  715 + this.send(thirdBroadcastSendPdu);
  716 + } else {
  717 + //发送给所有人
  718 + this.sendChatUniform(thirdBroadcastSendPdu);
  719 + }
  720 + }
  721 +
  722 + //监听第三方消息通道消息
  723 + onThirdBroadcastDataHandler(_data) {
  724 + //loger.log("监听第三方消息通道消息->",_data);
  725 + let thirdBroadcastReceivePdu = pdu['RCThirdSendBroadcastDataRequestPdu'].decode(_data);
  726 + let thirdMessage = {};
  727 + thirdMessage.fromNodeID = thirdBroadcastReceivePdu.initiator;
  728 + thirdMessage.toNodeID = thirdBroadcastReceivePdu.peer;
  729 + //loger.log("监听第三方消息通道消息->1", thirdMessage);
  730 + thirdMessage.message = this._rCArrayBufferUtil.uint8ArrayToStr(thirdBroadcastReceivePdu.message, 2);
  731 + loger.log("监听第三方消息通道消息->", thirdMessage);
  732 + if (this.thirdMessage) {
  733 + this.thirdMessage.sendMessageToParent(thirdMessage.message);
  734 + }
  735 + }
  736 +
  737 + //------------------第三方消息 end-----------------------------------------
  738 +
  739 + onSendConferRecordRequestHandler(_data) {
  740 + try {
  741 + let conferRecordSendPdu = pdu['RCConferenceRecordRequestPdu'].decode(_data);
  742 + // {"initiator":820461225,"record":false,"classTime":3213,"filename":"h5dev/20170410/1437784290_20170410.rec"}
  743 + loger.log("录制回放控制操作成功->", conferRecordSendPdu);
  744 + if (conferRecordSendPdu && conferRecordSendPdu.record == true || conferRecordSendPdu.record == "true") {
  745 + //每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件
  746 + this._emit(MessageTypes.CLASS_RECORD_SUCCESS);
  747 + }
  748 + } catch (err) {
  749 + loger.warn("录制回放控制操作错误->", err.message);
  750 + }
  751 +
  752 + }
  753 +
  754 + rosterInsertHandler(nodeId, nodeData) {
  755 + //loger.log("人员进入--->");
  756 + if (GlobalConfig.nodeId == nodeId) {
  757 +
  758 + } else {
  759 + // loger.log("有人加入 rosterInsertHandler");
  760 + this.rosterUpdateHandler(nodeId, nodeData);
  761 + }
  762 + }
  763 +
  764 + //更新人员列表数据
  765 + rosterUpdateHandler(nodeId, nodeData) {
  766 + nodeData.userRole = ApeConsts.userTypes[nodeData.role];
  767 + //如果是自己的信息,不处理跳过
  768 + if (nodeId == GlobalConfig.nodeId) {
  769 + //loger.log("自己加入课堂的消息->",nodeId,"role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
  770 + //自己加入的时候,需要做一下判断操作,如果满足以下3个条件就要暂停课堂:
  771 + // 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)
  772 + let rosterLen = Object.keys(this.rosters).length;
  773 + if (rosterLen < 1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
  774 + loger.warn("当前课堂没有老师->暂停课堂");
  775 + this.pauseClass({ isForce: true });
  776 + this.stopRecord(true);
724 } 777 }
725 - }  
726 -  
727 - //更新人员列表数据  
728 - rosterUpdateHandler(nodeId, nodeData) {  
729 - nodeData.userRole=ApeConsts.userTypes[nodeData.role];  
730 - //如果是自己的信息,不处理跳过  
731 - if (nodeId == GlobalConfig.nodeId) {  
732 - //loger.log("自己加入课堂的消息->",nodeId,"role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);  
733 - //自己加入的时候,需要做一下判断操作,如果满足以下3个条件就要暂停课堂:  
734 - // 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)  
735 - let rosterLen=Object.keys(this.rosters).length;  
736 - if(rosterLen<1&&!GlobalConfig.isHost&&GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED){  
737 - loger.warn("当前课堂没有老师->暂停课堂");  
738 - this.pauseClass({isForce:true});  
739 - this.stopRecord(true);  
740 - }  
741 - //处理用户信息  
742 - this.unPackRosterInfo(nodeId,nodeData);  
743 - return;  
744 - }  
745 -  
746 - //loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);  
747 -  
748 - //新加入的人员不是自己  
749 - //1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉  
750 - //2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大  
751 - if (parseInt(nodeId) > GlobalConfig.nodeId) {  
752 - if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {  
753 - this.kickOutRoster();  
754 - return;  
755 - }else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){  
756 - loger.log("异地登陆->userId->",GlobalConfig.userId);  
757 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);  
758 - this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});  
759 - }  
760 - }  
761 - /*if (parseInt(nodeId) > GlobalConfig.nodeId) {  
762 - if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {  
763 - this.kickOutRoster();  
764 - return;  
765 - } else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) {  
766 - this.kickOutRoster();  
767 - return;  
768 - } else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) {  
769 - this.kickOutRoster();  
770 - return;  
771 - } else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) {  
772 - this.kickOutRoster();  
773 - return;  
774 - }else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){  
775 - loger.log("异地登陆->userId->",GlobalConfig.userId);  
776 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);  
777 - this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});  
778 - }  
779 - }*/  
780 -  
781 //处理用户信息 778 //处理用户信息
782 - this.unPackRosterInfo(nodeId,nodeData); 779 + this.unPackRosterInfo(nodeId, nodeData);
  780 + return;
  781 + }
  782 +
  783 + //loger.log(nodeId, "加入课堂,role-->", nodeData.role, ApeConsts.userTypes[nodeData.role]);
  784 +
  785 + //新加入的人员不是自己
  786 + //1.判断进入的用户身份,如果进入的人身份是host,助教,监课,并且和自己的身份冲突,自己会被踢掉
  787 + //2.最后进入的人会踢掉之前进入的人,nodeId是按时间戳生成的,最后进入的人nodeId的值比之前进入的人大
  788 + if (parseInt(nodeId) > GlobalConfig.nodeId) {
  789 + if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
  790 + this.kickOutRoster();
  791 + return;
  792 + } else if (nodeData.userId == GlobalConfig.userId && GlobalConfig.userId != "0") {
  793 + loger.log("异地登陆->userId->", GlobalConfig.userId);
  794 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
  795 + this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 1 });
  796 + }
  797 + }
  798 + /*if (parseInt(nodeId) > GlobalConfig.nodeId) {
  799 + if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
  800 + this.kickOutRoster();
  801 + return;
  802 + } else if (nodeData.role == ApeConsts.NR_PRESENTER && GlobalConfig.isPresenter) {
  803 + this.kickOutRoster();
  804 + return;
  805 + } else if (nodeData.role == ApeConsts.NR_ASSISTANT && GlobalConfig.isAssistant) {
  806 + this.kickOutRoster();
  807 + return;
  808 + } else if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.isInvisible) {
  809 + this.kickOutRoster();
  810 + return;
  811 + }else if(nodeData.userId==GlobalConfig.userId&&GlobalConfig.userId!="0"){
  812 + loger.log("异地登陆->userId->",GlobalConfig.userId);
  813 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_REMOTE_LANDING);
  814 + this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});
  815 + }
  816 + }*/
  817 +
  818 + //处理用户信息
  819 + this.unPackRosterInfo(nodeId, nodeData);
783 } 820 }
784 //处理用户信息 821 //处理用户信息
785 - unPackRosterInfo(nodeId,nodeData){  
786 - let rosterExists = this.rosters[nodeId];  
787 - this.rosters[nodeId] = nodeData;  
788 - let userDataObj = null;  
789 - try {  
790 - userDataObj = pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData);  
791 - } catch (err) {  
792 - loger.log("RCNodeInfoUserDataPdu decode err", err.message);  
793 - }  
794 -  
795 - let newNodeData = nodeData;  
796 - newNodeData.userData = userDataObj;  
797 - //如果是监课,不告诉其他人  
798 - if (nodeData.role == ApeConsts.NR_INVISIBLE&&GlobalConfig.userRole!=ApeConsts.invisible) {  
799 - loger.log("NR_INVISIBLE");  
800 - return;  
801 - }  
802 - if (!rosterExists) {  
803 - loger.log("人员加入->",newNodeData);  
804 - this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});  
805 - this.emitRosterChange();  
806 -  
807 - } else {  
808 - //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);  
809 - loger.log("人员更新信息->",newNodeData);  
810 - this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});  
811 - }  
812 -  
813 - }  
814 -  
815 - //踢出用户  
816 - kickOutRoster() {  
817 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_KICK_OUT);  
818 - this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':1});  
819 - }  
820 -  
821 - //视频模块发生更新,人员状态需要更新  
822 - updaterRosterStatus(_param) {  
823 - //loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param);  
824 - //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的  
825 - if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING && this.rosters[_param.fromNodeId] == null) {  
826 - loger.log("媒体模块被占用->占有人已经不存在课堂中->释放->", _param);  
827 - this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});  
828 - }  
829 -  
830 - /* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {  
831 - if(this.rosters[_param.fromNodeId] == null){  
832 - loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);  
833 - this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});  
834 - }  
835 -  
836 - //如果音视频消息是自己的,需要设置麦克风和摄像头状态  
837 - if(_param.fromNodeId==GlobalConfig.nodeId){  
838 - if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){  
839 - GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();  
840 - GlobalConfig.openCamera=0;  
841 - }else {  
842 - GlobalConfig.openCamera=EngineUtils.creatTimestamp();  
843 - GlobalConfig.openMicrophones=GlobalConfig.openCamera;  
844 - }  
845 - this.updateUserInfo();  
846 - }  
847 -  
848 - }else if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {  
849 - //如果音视频消息是自己的,需要设置麦克风和摄像头状态  
850 - if(_param.fromNodeId==GlobalConfig.nodeId){  
851 - GlobalConfig.openCamera=0;  
852 - GlobalConfig.openMicrophones=0;  
853 - this.updateUserInfo();  
854 - }  
855 - }*/ 822 + unPackRosterInfo(nodeId, nodeData) {
  823 + let rosterExists = this.rosters[nodeId];
  824 + this.rosters[nodeId] = nodeData;
  825 + let userDataObj = null;
  826 + try {
  827 + userDataObj = pdu['RCNodeInfoUserDataPdu'].decode(nodeData.userData);
  828 + } catch (err) {
  829 + loger.log("RCNodeInfoUserDataPdu decode err", err.message);
  830 + }
  831 +
  832 + let newNodeData = nodeData;
  833 + newNodeData.userData = userDataObj;
  834 + //如果是监课,不告诉其他人
  835 + if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.userRole != ApeConsts.invisible) {
  836 + loger.log("NR_INVISIBLE");
  837 + return;
  838 + }
  839 + if (!rosterExists) {
  840 + loger.log("人员加入->", newNodeData);
  841 + this._emit(MessageTypes.CLASS_INSERT_ROSTER, { "nodeId": nodeId, "nodeData": newNodeData });
  842 + this.emitRosterChange();
  843 +
  844 + } else {
  845 + //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
  846 + loger.log("人员更新信息->", newNodeData);
  847 + this._emit(MessageTypes.CLASS_UPDATE_ROSTER, { "nodeId": nodeId, "nodeData": newNodeData });
  848 + }
  849 +
  850 + }
  851 +
  852 + //踢出用户
  853 + kickOutRoster() {
  854 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_KICK_OUT);
  855 + this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 1 });
  856 + }
  857 +
  858 + //视频模块发生更新,人员状态需要更新
  859 + updaterRosterStatus(_param) {
  860 + //loger.log("媒体模块发生更新,人员状态需要更新,fromNodeId->",_param);
  861 + //如果视频消息中channel的占用人 fromNodeId在人员列表中不存在,需要释放这channel,因为这个有可能是之前没释放成功的
  862 + if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING && this.rosters[_param.fromNodeId] == null) {
  863 + loger.log("媒体模块被占用->占有人已经不存在课堂中->释放->", _param);
  864 + this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, { "nodeId": _param.fromNodeId });
  865 + }
  866 +
  867 + /* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {
  868 + if(this.rosters[_param.fromNodeId] == null){
  869 + loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);
  870 + this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
  871 + }
  872 +
  873 + //如果音视频消息是自己的,需要设置麦克风和摄像头状态
  874 + if(_param.fromNodeId==GlobalConfig.nodeId){
  875 + if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){
  876 + GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();
  877 + GlobalConfig.openCamera=0;
  878 + }else {
  879 + GlobalConfig.openCamera=EngineUtils.creatTimestamp();
  880 + GlobalConfig.openMicrophones=GlobalConfig.openCamera;
  881 + }
  882 + this.updateUserInfo();
  883 + }
  884 +
  885 + }else if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
  886 + //如果音视频消息是自己的,需要设置麦克风和摄像头状态
  887 + if(_param.fromNodeId==GlobalConfig.nodeId){
  888 + GlobalConfig.openCamera=0;
  889 + GlobalConfig.openMicrophones=0;
  890 + this.updateUserInfo();
  891 + }
  892 + }*/
856 } 893 }
857 //设备状态更新 894 //设备状态更新
858 - updaterUserDeviecStatusChange(_data){  
859 - loger.log("音视频设备状态更新->",_data);  
860 - this.updateUserInfo();  
861 - }  
862 -  
863 - //删除用户  
864 - rosterDelHandler(nodeId) {  
865 - if (GlobalConfig.nodeId == nodeId) {  
866 - loger.log("自己离开课堂");  
867 - // 自己退出  
868 - this._emit(MessageTypes.CLASS_RUN_EXIT,{'type':0}); 895 + updaterUserDeviecStatusChange(_data) {
  896 + loger.log("音视频设备状态更新->", _data);
  897 + this.updateUserInfo();
  898 + }
  899 +
  900 + //删除用户
  901 + rosterDelHandler(nodeId) {
  902 + if (GlobalConfig.nodeId == nodeId) {
  903 + loger.log("自己离开课堂");
  904 + // 自己退出
  905 + this._emit(MessageTypes.CLASS_RUN_EXIT, { 'type': 0 });
  906 + } else {
  907 + let user = this.rosters[nodeId];
  908 + if (user) {
  909 + loger.log(nodeId, "->离开课堂->身份->", user.role);
  910 + }
  911 + delete this.rosters[nodeId];
  912 + this.emitRosterChange();
  913 + this._emit(MessageTypes.CLASS_DELETE_ROSTER, { "nodeId": nodeId });
  914 +
  915 + //当前人员列表中抽一个人来检查离开人员是否占用频道
  916 + for (let key in this.rosters) {
  917 + let randNodeId = parseInt(key);
  918 + //如果抽到的人是自己就处理以下操作
  919 + if (randNodeId == GlobalConfig.nodeId) {
  920 + loger.log(randNodeId, "有权限检查离开的人员是否占用channel");
  921 + this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, { "nodeId": nodeId });
  922 + //如果离开的人员是老师,需要暂停当前的课堂
  923 +
  924 + if (user && user.role == ApeConsts.NR_HOST) {
  925 + this.pauseClass();
  926 + //强制停止录制
  927 + this.stopRecord(true);
  928 + }
869 } else { 929 } else {
870 - let user=this.rosters[nodeId];  
871 - if(user){  
872 - loger.log(nodeId, "->离开课堂->身份->",user.role);  
873 - }  
874 - delete this.rosters[nodeId];  
875 - this.emitRosterChange();  
876 - this._emit(MessageTypes.CLASS_DELETE_ROSTER, {"nodeId": nodeId});  
877 -  
878 - //当前人员列表中抽一个人来检查离开人员是否占用频道  
879 - for (let key in this.rosters) {  
880 - let randNodeId = parseInt(key);  
881 - //如果抽到的人是自己就处理以下操作  
882 - if (randNodeId == GlobalConfig.nodeId) {  
883 - loger.log(randNodeId, "有权限检查离开的人员是否占用channel");  
884 - this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": nodeId});  
885 - //如果离开的人员是老师,需要暂停当前的课堂  
886 -  
887 - if(user&&user.role==ApeConsts.NR_HOST){  
888 - this.pauseClass();  
889 - //强制停止录制  
890 - this.stopRecord(true);  
891 - }  
892 - } else {  
893 - loger.warn(GlobalConfig.nodeId, "没有权限检查离开的人员是否占用channel");  
894 - }  
895 - //查找到一个就跳出操作  
896 - return;  
897 - }  
898 - }  
899 - }  
900 -  
901 - //广播当前的人数  
902 - emitRosterChange() {  
903 - this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length);  
904 - }  
905 -  
906 - ///////数据的封包和解包/////////////////////////////////////////  
907 - packPdu(_param, _itemIdx) {  
908 - loger.log("课堂===packPdu ");  
909 - //验证坐标点集合数组是否合法  
910 - if (_param == null || _itemIdx == null) {  
911 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
912 - return null;  
913 - }  
914 - let classStatusInfo = new pdu['RCClassStatusInfoPdu'];  
915 - classStatusInfo.nodeId = GlobalConfig.nodeId;//mcu中的唯一ID  
916 - classStatusInfo.userId = GlobalConfig.userId;  
917 - classStatusInfo.userName = GlobalConfig.userName;  
918 - classStatusInfo.siteId = GlobalConfig.siteId;//站点号  
919 - classStatusInfo.classId = GlobalConfig.classId;  
920 - classStatusInfo.className = GlobalConfig.className;  
921 - classStatusInfo.classType = GlobalConfig.classType;//课堂类型  
922 - classStatusInfo.classStatus = GlobalConfig.classStatus;//课堂的状态  
923 - classStatusInfo.classStartTime = GlobalConfig.classStartTime;//课堂点击开始时间  
924 - classStatusInfo.classStopTime = GlobalConfig.classStopTime;//最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳  
925 - classStatusInfo.classTimestamp = GlobalConfig.classTimestamp;//相对于点开始课堂的时间戳  
926 - classStatusInfo.classBeginTime = GlobalConfig.classBeginTime;//课堂创建的时间,这个是Sass返回的  
927 - classStatusInfo.classEndTime = GlobalConfig.classEndTime;//课堂结束的时间,这个是Sass返回的  
928 - classStatusInfo.recordStatus = GlobalConfig.recordStatus;//当前录制状态  
929 - classStatusInfo.recordTimestamp = GlobalConfig.recordTimestamp;//相对于首次开始录制的时间戳  
930 - classStatusInfo.recordFileName = GlobalConfig.recordFileName;//录制的文件名  
931 - classStatusInfo.recordDownloadUrl = GlobalConfig.recordDownloadUrl;//下载地址  
932 - classStatusInfo.serverTimestamp = GlobalConfig.serverTimestamp;//当前的系统时间戳  
933 - classStatusInfo.activeDocId = GlobalConfig.activeDocId;//当前激活的文档id  
934 - classStatusInfo.activeDocCurPage = GlobalConfig.activeDocCurPage;//当前激活的文档的当前页  
935 - classStatusInfo.isStopAllPublishMedia=_param.isStopAllPublishMedia||false;  
936 - classStatusInfo.currentSceneTableId=GlobalConfig.currentSceneTableId;  
937 - //loger.log("classStatusInfo--->", classStatusInfo);  
938 -  
939 - /*  
940 - optional uint32 item_idx=1;  
941 - optional uint32 from=2;  
942 - optional uint32 owner=3;  
943 - optional uint32 action_type=4;//状态改变的类型  
944 - optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息  
945 - */  
946 - //判断type类型,根据type设置不同的参数  
947 - let modelPdu = new pdu['RCClassSendDataModelPdu'];  
948 - modelPdu.itemIdx = _itemIdx;  
949 - modelPdu.from = GlobalConfig.nodeId;  
950 - modelPdu.owner = GlobalConfig.nodeId;  
951 - //modelPdu.actionType =_param.actionType;  
952 - modelPdu.classStatusInfo = classStatusInfo;  
953 - return modelPdu;  
954 - }  
955 -  
956 - unPackPdu(owner, itemIdx, itemData) {  
957 - loger.log("课堂数据->unPackPdu ");  
958 - if (owner == null || itemIdx == null || itemData == null) {  
959 - this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
960 - return null;  
961 - }  
962 -  
963 - try {  
964 - let modelPdu = pdu['RCClassSendDataModelPdu'].decode(itemData);  
965 - return modelPdu;  
966 - } catch (err) {  
967 - loger.log("课堂收到数据 unPackPdu Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message);  
968 - }  
969 - return null;  
970 - } 930 + loger.warn(GlobalConfig.nodeId, "没有权限检查离开的人员是否占用channel");
  931 + }
  932 + //查找到一个就跳出操作
  933 + return;
  934 + }
  935 + }
  936 + }
  937 +
  938 + //广播当前的人数
  939 + emitRosterChange() {
  940 + this._emit(MessageTypes.CLASS_UPDATE_ROSTER_NUM, Object.keys(this.rosters).length);
  941 + }
  942 +
  943 + ///////数据的封包和解包/////////////////////////////////////////
  944 + packPdu(_param, _itemIdx) {
  945 + loger.log("课堂===packPdu ");
  946 + //验证坐标点集合数组是否合法
  947 + if (_param == null || _itemIdx == null) {
  948 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  949 + return null;
  950 + }
  951 + let classStatusInfo = new pdu['RCClassStatusInfoPdu'];
  952 + classStatusInfo.nodeId = GlobalConfig.nodeId; //mcu中的唯一ID
  953 + classStatusInfo.userId = GlobalConfig.userId;
  954 + classStatusInfo.userName = GlobalConfig.userName;
  955 + classStatusInfo.siteId = GlobalConfig.siteId; //站点号
  956 + classStatusInfo.classId = GlobalConfig.classId;
  957 + classStatusInfo.className = GlobalConfig.className;
  958 + classStatusInfo.classType = GlobalConfig.classType; //课堂类型
  959 + classStatusInfo.classStatus = GlobalConfig.classStatus; //课堂的状态
  960 + classStatusInfo.classStartTime = GlobalConfig.classStartTime; //课堂点击开始时间
  961 + classStatusInfo.classStopTime = GlobalConfig.classStopTime; //最后一次停止的时间(点暂停或结束),每次发送数据都获取当前时间戳
  962 + classStatusInfo.classTimestamp = GlobalConfig.classTimestamp; //相对于点开始课堂的时间戳
  963 + classStatusInfo.classBeginTime = GlobalConfig.classBeginTime; //课堂创建的时间,这个是Sass返回的
  964 + classStatusInfo.classEndTime = GlobalConfig.classEndTime; //课堂结束的时间,这个是Sass返回的
  965 + classStatusInfo.recordStatus = GlobalConfig.recordStatus; //当前录制状态
  966 + classStatusInfo.recordTimestamp = GlobalConfig.recordTimestamp; //相对于首次开始录制的时间戳
  967 + classStatusInfo.recordFileName = GlobalConfig.recordFileName; //录制的文件名
  968 + classStatusInfo.recordDownloadUrl = GlobalConfig.recordDownloadUrl; //下载地址
  969 + classStatusInfo.serverTimestamp = GlobalConfig.serverTimestamp; //当前的系统时间戳
  970 + classStatusInfo.activeDocId = GlobalConfig.activeDocId; //当前激活的文档id
  971 + classStatusInfo.activeDocCurPage = GlobalConfig.activeDocCurPage; //当前激活的文档的当前页
  972 + classStatusInfo.isStopAllPublishMedia = _param.isStopAllPublishMedia || false;
  973 + classStatusInfo.currentSceneTableId = GlobalConfig.currentSceneTableId;
  974 + classStatusInfo.silence = GlobalConfig.silence;
  975 + //loger.log("classStatusInfo--->", classStatusInfo);
  976 +
  977 + /*
  978 + optional uint32 item_idx=1;
  979 + optional uint32 from=2;
  980 + optional uint32 owner=3;
  981 + optional uint32 action_type=4;//状态改变的类型
  982 + optional RCClassStatusInfoPdu class_status_info=5;//当前课堂状态的信息
  983 + */
  984 + //判断type类型,根据type设置不同的参数
  985 + let modelPdu = new pdu['RCClassSendDataModelPdu'];
  986 + modelPdu.itemIdx = _itemIdx;
  987 + modelPdu.from = GlobalConfig.nodeId;
  988 + modelPdu.owner = GlobalConfig.nodeId;
  989 + //modelPdu.actionType =_param.actionType;
  990 + modelPdu.classStatusInfo = classStatusInfo;
  991 + return modelPdu;
  992 + }
  993 +
  994 + unPackPdu(owner, itemIdx, itemData) {
  995 + loger.log("课堂数据->unPackPdu ");
  996 + if (owner == null || itemIdx == null || itemData == null) {
  997 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  998 + return null;
  999 + }
  1000 +
  1001 + try {
  1002 + let modelPdu = pdu['RCClassSendDataModelPdu'].decode(itemData);
  1003 + return modelPdu;
  1004 + } catch (err) {
  1005 + loger.log("课堂收到数据 unPackPdu Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message);
  1006 + }
  1007 + return null;
  1008 + }
971 1009
972 } 1010 }
973 1011
@@ -896,6 +896,7 @@ message RCNodeInfoRecordPdu { @@ -896,6 +896,7 @@ message RCNodeInfoRecordPdu {
896 optional string province=27; 896 optional string province=27;
897 optional string isp=28; 897 optional string isp=28;
898 repeated MsListItemPdu msList = 29; 898 repeated MsListItemPdu msList = 29;
  899 + optional string selfSilence = 30;
899 } 900 }
900 901
901 message RCVotingPollSettingsPdu { 902 message RCVotingPollSettingsPdu {
@@ -991,6 +992,7 @@ message RCClassStatusInfoPdu { @@ -991,6 +992,7 @@ message RCClassStatusInfoPdu {
991 optional uint32 active_doc_cur_page=21;//当前激活的文档的当前页 992 optional uint32 active_doc_cur_page=21;//当前激活的文档的当前页
992 optional bool isStopAllPublishMedia=22;//是否停止推流 993 optional bool isStopAllPublishMedia=22;//是否停止推流
993 optional uint32 currentSceneTableId=23;//文档区域的当前模块id 994 optional uint32 currentSceneTableId=23;//文档区域的当前模块id
  995 + optional bool silence=24;//课堂禁言
994 } 996 }
995 997
996 message RCConferenceRecordRequestPdu { 998 message RCConferenceRecordRequestPdu {