李勇

1.视频模块增加控制消息指令接口,定义控制消息的类型;增加控制消息监听的定义

2.修改时间戳生成和唯一nodeId生成的方法
@@ -84,6 +84,12 @@ export default class MessageEntrance extends Emiter { @@ -84,6 +84,12 @@ export default class MessageEntrance extends Emiter {
84 84
85 _video_ape = new VideoApe(); 85 _video_ape = new VideoApe();
86 _video_ape.on('*', (type, data) => this._emit(type, data)); 86 _video_ape.on('*', (type, data) => this._emit(type, data));
  87 + _video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this));
  88 +
  89 + _whiteboard_ape = new WhiteBoardApe();
  90 + _whiteboard_ape.on('*', (type, data) => this._emit(type, data));
  91 + //_whiteboard_ape.on(MessageTypes.WHITEBOARD_ANNOTATION_UPDATE, this.annoUpdateHandler.bind(this));
  92 +
87 93
88 _doc_ape = new DocApe(); 94 _doc_ape = new DocApe();
89 _doc_ape.on('*', (type, data) => this._emit(type, data)); 95 _doc_ape.on('*', (type, data) => this._emit(type, data));
@@ -92,10 +98,6 @@ export default class MessageEntrance extends Emiter { @@ -92,10 +98,6 @@ export default class MessageEntrance extends Emiter {
92 _doc_ape.on(DocApe.DOC_JOIN_CHANNEL_SUCCESS, this.docJoinChannelSuccess.bind(this)); 98 _doc_ape.on(DocApe.DOC_JOIN_CHANNEL_SUCCESS, this.docJoinChannelSuccess.bind(this));
93 99
94 100
95 - _whiteboard_ape = new WhiteBoardApe();  
96 - _whiteboard_ape.on('*', (type, data) => this._emit(type, data));  
97 - //_whiteboard_ape.on(MessageTypes.WHITEBOARD_ANNOTATION_UPDATE, this.annoUpdateHandler.bind(this));  
98 -  
99 101
100 //公开外部调用的方法 102 //公开外部调用的方法
101 //class 103 //class
@@ -622,6 +624,13 @@ export default class MessageEntrance extends Emiter { @@ -622,6 +624,13 @@ export default class MessageEntrance extends Emiter {
622 } 624 }
623 625
624 //VidoeApe 626 //VidoeApe
  627 + videoUpdate(_data){
  628 + //视频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
  629 + if(_confer_ape){
  630 + _confer_ape.updaterRosterStatus(_data);
  631 + }
  632 + }
  633 +
625 sendVideoCommandMsg(_param){ 634 sendVideoCommandMsg(_param){
626 if(_video_ape){ 635 if(_video_ape){
627 _video_ape.sendVideoCommandMsg(_param); 636 _video_ape.sendVideoCommandMsg(_param);
@@ -687,7 +696,6 @@ export default class MessageEntrance extends Emiter { @@ -687,7 +696,6 @@ export default class MessageEntrance extends Emiter {
687 696
688 697
689 //DocApe 698 //DocApe
690 -  
691 //获取文档完整路径 699 //获取文档完整路径
692 _getDocFullPath(_param){ 700 _getDocFullPath(_param){
693 if(_doc_ape){ 701 if(_doc_ape){
@@ -29,11 +29,17 @@ class EngineUtils{ @@ -29,11 +29,17 @@ class EngineUtils{
29 } 29 }
30 30
31 //生成时间戳后9位 保证唯一 31 //生成时间戳后9位 保证唯一
32 - static creatTimestamp(){ 32 + static creatSoleNumberFromTimestamp(){
33 let time = new Date().getTime(); 33 let time = new Date().getTime();
34 let timestamp:int = time % 1000000000;//time后9位 34 let timestamp:int = time % 1000000000;//time后9位
35 return timestamp; 35 return timestamp;
36 } 36 }
  37 +
  38 + //生成时间戳毫秒
  39 + static creatTimestamp(){
  40 + let time = parseInt(new Date().getTime()/1000);//精确到毫秒
  41 + return time;
  42 + }
37 //生成时间戳 string 43 //生成时间戳 string
38 static creatTimestampStr(){ 44 static creatTimestampStr(){
39 let curTime = new Date(); 45 let curTime = new Date();
@@ -26,8 +26,8 @@ MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态 @@ -26,8 +26,8 @@ MessageTypes.CLASS_STATUS_INFO_CHANGE= 'class.status.info.change';//会议状态
26 MessageTypes.CHAT_RECEIVE = 'chat.receive'; 26 MessageTypes.CHAT_RECEIVE = 'chat.receive';
27 27
28 //视频模块事件定义 28 //视频模块事件定义
29 -MessageTypes.VIDEO_RECEIVE = 'video.receive';  
30 - 29 +MessageTypes.VIDEO_UPDATE = 'video.update';
  30 +MessageTypes.VIDEO_COMMAND= 'video.command';
31 31
32 //文档模块事件定义 32 //文档模块事件定义
33 MessageTypes.DOC_DELETE='document.delete';//删除文档 33 MessageTypes.DOC_DELETE='document.delete';//删除文档
@@ -69,17 +69,22 @@ ApeConsts.USER_MIC_OPEN = 0x0040; // 麦克风开启 @@ -69,17 +69,22 @@ ApeConsts.USER_MIC_OPEN = 0x0040; // 麦克风开启
69 ApeConsts.USER_CAMERA_OPEN = 0x0080; // 视频开启 69 ApeConsts.USER_CAMERA_OPEN = 0x0080; // 视频开启
70 70
71 71
72 -//VIDEO MIC  
73 -ApeConsts.OPEN_CAMERA= "open.camera";  
74 -ApeConsts.CLOSE_CAMERA= "close.camera";  
75 -ApeConsts.OPEN_MIC= "open.mic";  
76 -ApeConsts.CLOSE_MIC= "close.mic"; 72 +//VIDEO MIC 流媒体消息操作控制类型
  73 +ApeConsts.MEDIA_ACTION_DEFAULT=0;
  74 +ApeConsts.MEDIA_ACTION_OPEN_CAMERA=1;// "open.camera";
  75 +ApeConsts.MEDIA_ACTION_CLOSE_CAMERA=2;// "close.camera";
  76 +ApeConsts.MEDIA_ACTION_OPEN_MIC= 3;//"open.mic";
  77 +ApeConsts.MEDIA_ACTION_CLOSE_MIC= 4;//"close.mic";
77 78
78 79
79 // VIDEO AUDIO CHANNEL使用状态 80 // VIDEO AUDIO CHANNEL使用状态
80 ApeConsts.CHANNEL_STATUS_RELEASED = 0;///< 无人占用状态 81 ApeConsts.CHANNEL_STATUS_RELEASED = 0;///< 无人占用状态
81 ApeConsts.CHANNEL_STATUS_OPENING = 1;///< 已经占用成功 82 ApeConsts.CHANNEL_STATUS_OPENING = 1;///< 已经占用成功
82 83
  84 +//媒体类型
  85 +ApeConsts.MEDIA_TYPE_DEFAULT=0;//没有类型
  86 +ApeConsts.MEDIA_TYPE_VIDEO=1;//视频流(包含音频)
  87 +ApeConsts.MEDIA_TYPE_VIDEO=2;//音频流
83 88
84 //FLASH中使用下面4个 89 //FLASH中使用下面4个
85 ApeConsts.CGS_RELEASED = 0;///< 无人占用状态 90 ApeConsts.CGS_RELEASED = 0;///< 无人占用状态
@@ -70,7 +70,6 @@ class ConferApe extends Ape { @@ -70,7 +70,6 @@ class ConferApe extends Ape {
70 let userDataPdu = new pdu['RCNodeInfoUserDataPdu']; 70 let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
71 userDataPdu.qq = ''; 71 userDataPdu.qq = '';
72 userDataPdu.skype = ''; 72 userDataPdu.skype = '';
73 - userDataPdu.mobile = '';  
74 73
75 nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer(); 74 nodeInfoRecordPdu.userData = userDataPdu.toArrayBuffer();
76 nodeInfoRecordPdu.deviceType =GlobalConfig.deviceType;//设备类型 75 nodeInfoRecordPdu.deviceType =GlobalConfig.deviceType;//设备类型
@@ -100,7 +99,7 @@ class ConferApe extends Ape { @@ -100,7 +99,7 @@ class ConferApe extends Ape {
100 } 99 }
101 100
102 sendConferMsg(_messageInfo) { 101 sendConferMsg(_messageInfo) {
103 - if(this._classInfo===null||EngineUtils.isEmptyObject(this._classInfo)){ 102 + if(this._classInfo==null||EngineUtils.isEmptyObject(this._classInfo)){
104 loger.log('不能发送会议消息.McuClient还未初始化数据!'); 103 loger.log('不能发送会议消息.McuClient还未初始化数据!');
105 if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){ 104 if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
106 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN); 105 this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
@@ -454,6 +453,11 @@ class ConferApe extends Ape { @@ -454,6 +453,11 @@ class ConferApe extends Ape {
454 } 453 }
455 } 454 }
456 455
  456 + //视频模块发生更新,人员状态需要更新
  457 + updaterRosterStatus(_param){
  458 + loger.log("视频模块发生更新,人员状态需要更新",_param);
  459 + //如果是自己。改变自己的状态同步到MCU
  460 + }
457 //删除用户 461 //删除用户
458 rosterDelHandler(nodeId) { 462 rosterDelHandler(nodeId) {
459 if(GlobalConfig.nodeId==nodeId){ 463 if(GlobalConfig.nodeId==nodeId){
@@ -58,7 +58,7 @@ class DocApe extends Ape { @@ -58,7 +58,7 @@ class DocApe extends Ape {
58 return; 58 return;
59 } 59 }
60 60
61 - itemIdx=EngineUtils.creatTimestamp(); 61 + itemIdx=EngineUtils.creatSoleNumberFromTimestamp();
62 let docDataModelPdu = this.packPdu(paramInfo,itemIdx); 62 let docDataModelPdu = this.packPdu(paramInfo,itemIdx);
63 if(docDataModelPdu==null){ 63 if(docDataModelPdu==null){
64 loger.log('documentUpload失败,参数错误'); 64 loger.log('documentUpload失败,参数错误');
@@ -35,9 +35,6 @@ class VideoChat extends Ape { @@ -35,9 +35,6 @@ class VideoChat extends Ape {
35 35
36 //Attributes 36 //Attributes
37 this.videoChannels = {}; 37 this.videoChannels = {};
38 - this.activeChannelId = 0;  
39 - this.activeURL = '';  
40 -  
41 38
42 // Ape Models 39 // Ape Models
43 this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer); 40 this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
@@ -168,7 +165,7 @@ class VideoChat extends Ape { @@ -168,7 +165,7 @@ class VideoChat extends Ape {
168 //return openedUsers; 165 //return openedUsers;
169 } 166 }
170 167
171 - sendVideoCommandMsg(_messageInfo) { 168 + sendVideoCommandMsg(_param) {
172 if(this._classInfo===null||EngineUtils.isEmptyObject(this._classInfo)){ 169 if(this._classInfo===null||EngineUtils.isEmptyObject(this._classInfo)){
173 loger.log('不能发送Video消息.McuClient还未初始化数据!'); 170 loger.log('不能发送Video消息.McuClient还未初始化数据!');
174 if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){ 171 if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
@@ -178,27 +175,27 @@ class VideoChat extends Ape { @@ -178,27 +175,27 @@ class VideoChat extends Ape {
178 return ; 175 return ;
179 } 176 }
180 // to, message 177 // to, message
181 - loger.log('发送Video消息.', _messageInfo); 178 + loger.log('发送Video消息.', _param);
182 179
183 180
184 - /* message RCVideoSendDataRequestPdu {  
185 - optional uint32 initiator = 1;  
186 - optional bool key_frame = 2;  
187 - optional uint32 sequence_id = 3;  
188 - optional uint32 slice_id = 4;  
189 - optional bytes user_data = 5;  
190 - }  
191 - */ 181 + /* message RCVideoSendDataRequestPdu {
  182 + required uint32 from_node_id = 1;//发起人
  183 + optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收
  184 + optional uint32 actionType = 3;//消息指令类型;
  185 + optional bytes data = 4;//其他数据,这个根据actionType来确定数据的结构
  186 + }*/
192 187
193 let videoSendPdu = new pdu['RCVideoSendDataRequestPdu']; 188 let videoSendPdu = new pdu['RCVideoSendDataRequestPdu'];
194 videoSendPdu.type = pdu.RCPDU_VIDEO_SEND_DATA_REQUEST; 189 videoSendPdu.type = pdu.RCPDU_VIDEO_SEND_DATA_REQUEST;
195 - videoSendPdu.initiator = GlobalConfig.nodeId;//发起人  
196 - videoSendPdu.peer = parseInt(_messageInfo.to);//发送给谁,公聊的时候是0,私聊的时候是指定的用户id  
197 - videoSendPdu.userData = this._rCArrayBufferUtil.strToUint8Array("h5" + _messageInfo.message);//开头两个字会乱码  
198 videoSendPdu.isPublic = true; 190 videoSendPdu.isPublic = true;
199 - videoSendPdu.sliceId=_messageInfo.sliceId||0;  
200 191
201 - if (!videoSendPdu.isPublic && 0!=videoSendPdu.peer) { 192 + videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人
  193 + videoSendPdu.toNodeId = parseInt(_param.toNodeID)||0;//接收者,0就是所有人
  194 + videoSendPdu.actionType = parseInt(_param.actionType)||ApeConsts.MEDIA_ACTION_DEFAULT;
  195 +
  196 + videoSendPdu.data=this._rCArrayBufferUtil.strToUint8Array("h5" + _param.data);//开头两个字会乱码
  197 +
  198 + if (!videoSendPdu.isPublic && 0!=videoSendPdu.toNodeId) {
202 //发送给制定的人 199 //发送给制定的人
203 loger.log('发送私聊Video消息.'); 200 loger.log('发送私聊Video消息.');
204 this.send(videoSendPdu); 201 this.send(videoSendPdu);
@@ -253,20 +250,22 @@ class VideoChat extends Ape { @@ -253,20 +250,22 @@ class VideoChat extends Ape {
253 } 250 }
254 /////收到消息处理///////////////////////////////////////////////////////////////////////////////// 251 /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
255 252
256 - // 视频消息处理  
257 - videoCommandHandler(videoBuffer) {  
258 - let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(videoBuffer);  
259 -  
260 - let video_data = { };  
261 - video_data._initiator = videoReceivePdu.initiator;  
262 - video_data._is_key_frame = videoReceivePdu.keyFrame;  
263 - video_data._sequence_id = videoReceivePdu.sequenceId;  
264 - video_data._slice_id = videoReceivePdu.sliceId;  
265 - video_data._data = videoReceivePdu.userData;  
266 -  
267 - // this._notify(RCApeEvent.E_VIDEO_DATA, videoReceivePdu.sessionId, videoReceivePdu.channelId, video_data);  
268 - loger.log('视频消息处理 videoCommandHandler.', video_data);  
269 - //this._emit(MessageTypes.VIDEO_RECEIVE, video_data); 253 + // 视频消息处理,内部处理,不需要告诉应用层
  254 + videoCommandHandler(_data) {
  255 + let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data);
  256 + if(videoReceivePdu==null) {
  257 + loger.warn("视频消息处理,收到的消息为null,不做处理");
  258 + return;
  259 + }
  260 + videoReceivePdu.data=this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data,2);//开头两个字会乱码
  261 + loger.log('视频消息处理 videoCommandHandler.', videoReceivePdu);
  262 +
  263 + //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理
  264 + if(videoReceivePdu.toNodeId!=0&&videoReceivePdu.toNodeId!=GlobalConfig.nodeId){
  265 + loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId,"my nodeId=",GlobalConfig.nodeId);
  266 + }else {
  267 + this._emit(MessageTypes.VIDEO_COMMAND,videoReceivePdu);
  268 + }
270 } 269 }
271 270
272 tableUpdateHandler(owner, itemIdx, itemData) { 271 tableUpdateHandler(owner, itemIdx, itemData) {
@@ -278,6 +277,7 @@ class VideoChat extends Ape { @@ -278,6 +277,7 @@ class VideoChat extends Ape {
278 //loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo); 277 //loger.log('视频消息处理 tableUpdateHandler.',videoChannelInfo);
279 this.videoChannels[itemIdx] = videoChannelInfo; 278 this.videoChannels[itemIdx] = videoChannelInfo;
280 279
  280 + this._emit(MessageTypes.VIDEO_UPDATE,videoChannelInfo);
281 /* switch (videoChannelInfo.status) { 281 /* switch (videoChannelInfo.status) {
282 case ApeConsts.CHANNEL_STATUS_RELEASED: 282 case ApeConsts.CHANNEL_STATUS_RELEASED:
283 // 只能关闭自己的流 283 // 只能关闭自己的流
@@ -306,7 +306,7 @@ class VideoChat extends Ape { @@ -306,7 +306,7 @@ class VideoChat extends Ape {
306 } 306 }
307 307
308 emitVideoChange() { 308 emitVideoChange() {
309 - this._emit(MessageTypes.VIDEO_RECEIVE, { 309 + this._emit(MessageTypes.VIDEO_UPDATE, {
310 activeChannelId: this.activeChannelId, 310 activeChannelId: this.activeChannelId,
311 HLSURL: this.activeURL, 311 HLSURL: this.activeURL,
312 }); 312 });
@@ -334,6 +334,7 @@ class VideoChat extends Ape { @@ -334,6 +334,7 @@ class VideoChat extends Ape {
334 let packPduModel =new pdu['RCVideoChannelInfoPdu']; 334 let packPduModel =new pdu['RCVideoChannelInfoPdu'];
335 packPduModel.status=ApeConsts.CHANNEL_STATUS_OPENING; 335 packPduModel.status=ApeConsts.CHANNEL_STATUS_OPENING;
336 packPduModel.channelId=_itemIdx; 336 packPduModel.channelId=_itemIdx;
  337 + packPduModel.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;
337 packPduModel.timestamp=EngineUtils.creatTimestamp(); 338 packPduModel.timestamp=EngineUtils.creatTimestamp();
338 packPduModel.fromNodeId =GlobalConfig.nodeId; 339 packPduModel.fromNodeId =GlobalConfig.nodeId;
339 packPduModel.toNodeId = 0; 340 packPduModel.toNodeId = 0;
@@ -69,7 +69,7 @@ class WhiteBoardApe extends Ape { @@ -69,7 +69,7 @@ class WhiteBoardApe extends Ape {
69 return ; 69 return ;
70 } 70 }
71 71
72 - itemIdx=EngineUtils.creatTimestamp(); 72 + itemIdx=EngineUtils.creatSoleNumberFromTimestamp();
73 let whiteBoardModelPdu = this.packPdu(_param,itemIdx); 73 let whiteBoardModelPdu = this.packPdu(_param,itemIdx);
74 if(whiteBoardModelPdu==null){ 74 if(whiteBoardModelPdu==null){
75 loger.log('sendInsetAnnotaion失败,参数错误'); 75 loger.log('sendInsetAnnotaion失败,参数错误');
@@ -166,7 +166,7 @@ class MCU extends Emiter { @@ -166,7 +166,7 @@ class MCU extends Emiter {
166 _classInfo.classId = parseInt(_classInfo.classId); // classId 必须整形 166 _classInfo.classId = parseInt(_classInfo.classId); // classId 必须整形
167 this.classInfo = _classInfo; 167 this.classInfo = _classInfo;
168 // 创建刷新nodeId 168 // 创建刷新nodeId
169 - this.classInfo.nodeId =EngineUtils.creatTimestamp(); 169 + this.classInfo.nodeId =EngineUtils.creatSoleNumberFromTimestamp();
170 GlobalConfig.nodeId=this.classInfo.nodeId;//这是标识自己身份的id 170 GlobalConfig.nodeId=this.classInfo.nodeId;//这是标识自己身份的id
171 171
172 let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu']; 172 let nodeInfoRecordPdu = new pdu['RCNodeInfoRecordPdu'];
@@ -735,12 +735,10 @@ message RCAudioSendDataRequestPdu { @@ -735,12 +735,10 @@ message RCAudioSendDataRequestPdu {
735 } 735 }
736 736
737 message RCVideoSendDataRequestPdu { 737 message RCVideoSendDataRequestPdu {
738 - required uint32 initiator = 1;  
739 - optional bool key_frame = 2;  
740 - optional uint32 sequence_id = 3;  
741 - optional uint32 slice_id = 4;  
742 - optional bytes user_data = 5;  
743 - optional uint32 action = 6; 738 + required uint32 from_node_id = 1;//发起人
  739 + optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收
  740 + optional uint32 actionType = 3;//消息指令类型;
  741 + optional bytes data = 4;//其他数据,这个根据actionType来确定数据的结构
744 } 742 }
745 743
746 message RCAudioChannelInfoRecordPdu { 744 message RCAudioChannelInfoRecordPdu {
@@ -757,6 +755,7 @@ message RCVideoChannelInfoPdu { @@ -757,6 +755,7 @@ message RCVideoChannelInfoPdu {
757 optional uint32 timestamp = 3;//更新的时间戳 755 optional uint32 timestamp = 3;//更新的时间戳
758 optional uint32 from_node_id = 4;//发起者的id 756 optional uint32 from_node_id = 4;//发起者的id
759 optional uint32 to_node_id = 5;//接收者的id,(如果是0,所有人都接收) 757 optional uint32 to_node_id = 5;//接收者的id,(如果是0,所有人都接收)
  758 + optional uint32 media_type = 6;//媒体类型:视频(包含音频)或音频
760 } 759 }
761 760
762 message RCVideoChannelInfoRecordPdu { 761 message RCVideoChannelInfoRecordPdu {
@@ -835,10 +834,14 @@ message RCVotingPollRecordPdu { @@ -835,10 +834,14 @@ message RCVotingPollRecordPdu {
835 } 834 }
836 835
837 message RCNodeInfoUserDataPdu { 836 message RCNodeInfoUserDataPdu {
838 - optional string qq = 1;  
839 - optional string skype = 2;  
840 - optional string mobile = 3; 837 + optional string device = 1;//设备名称
  838 + optional bool has_camera = 2;//是否有摄像头可用
  839 + optional bool has_microphone = 3;//麦克风是否可用
  840 + optional string browser = 4;//浏览器
  841 + optional string qq = 5;//qq
  842 + optional string skype = 6;//skype
841 } 843 }
  844 +
842 message RCTabUpdateDataRequestPdu { 845 message RCTabUpdateDataRequestPdu {
843 optional uint32 id = 1; 846 optional uint32 id = 1;
844 optional bytes action = 2; 847 optional bytes action = 2;