李勇

修复录制回放多路音视频,在seek拖动播放的时候,显示数量不正确的问题

此 diff 太大无法显示。
@@ -28,7 +28,7 @@ import MediaModule from 'apes/MediaModule'; @@ -28,7 +28,7 @@ import MediaModule from 'apes/MediaModule';
28 import UTF8 from 'utf-8'; 28 import UTF8 from 'utf-8';
29 29
30 let loger = Loger.getLoger('McuClient'); 30 let loger = Loger.getLoger('McuClient');
31 -let _sdkInfo = {"version": "v1.22.0.201705017", "author": "www.3mang.com"}; 31 +let _sdkInfo = {"version": "v1.23.0.201705018", "author": "www.3mang.com"};
32 32
33 //APE 33 //APE
34 let _sass; 34 let _sass;
@@ -7,6 +7,7 @@ import pdu from 'pdus/index'; @@ -7,6 +7,7 @@ import pdu from 'pdus/index';
7 import PduType from 'pdus/PduType'; 7 import PduType from 'pdus/PduType';
8 import PduConsts from 'pdus/PduConsts'; 8 import PduConsts from 'pdus/PduConsts';
9 import ApeConsts from 'apes/ApeConsts'; 9 import ApeConsts from 'apes/ApeConsts';
  10 +
10 import ArrayBufferUtil from 'libs/ArrayBufferUtil'; 11 import ArrayBufferUtil from 'libs/ArrayBufferUtil';
11 import Base64 from 'base64-js'; 12 import Base64 from 'base64-js';
12 import GlobalConfig from 'GlobalConfig'; 13 import GlobalConfig from 'GlobalConfig';
@@ -32,7 +33,7 @@ class RecordPlayBackParse extends Emiter { @@ -32,7 +33,7 @@ class RecordPlayBackParse extends Emiter {
32 this._recordPlaybackMaxTime = 0;//录制回放的总时间 33 this._recordPlaybackMaxTime = 0;//录制回放的总时间
33 this._isReady = false;//录制回放是否已经准备完成 34 this._isReady = false;//录制回放是否已经准备完成
34 this._apes = {}; 35 this._apes = {};
35 - 36 + this.mediaChannleList={};
36 this._conferApeMssages = {};//会议数据 37 this._conferApeMssages = {};//会议数据
37 this._chatApeMssages = {};//聊天数据 38 this._chatApeMssages = {};//聊天数据
38 this._videoApeMssages = {};//视频数据 39 this._videoApeMssages = {};//视频数据
@@ -118,6 +119,7 @@ class RecordPlayBackParse extends Emiter { @@ -118,6 +119,7 @@ class RecordPlayBackParse extends Emiter {
118 119
119 //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳 120 //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳
120 _parseSaveSocketMsgReceivedHandler(data, timestamp) { 121 _parseSaveSocketMsgReceivedHandler(data, timestamp) {
  122 + loger.log('解析和储存,录制回放EverSocket底层消息处理 ');
121 let pduMsg = pdu.decode_pdu(data); 123 let pduMsg = pdu.decode_pdu(data);
122 let pduType = pduMsg.get("type"); 124 let pduType = pduMsg.get("type");
123 let pduData = pduMsg.get("data"); 125 let pduData = pduMsg.get("data");
@@ -170,9 +172,11 @@ class RecordPlayBackParse extends Emiter { @@ -170,9 +172,11 @@ class RecordPlayBackParse extends Emiter {
170 break; 172 break;
171 case ApeConsts.VIDEO_SESSION_ID: 173 case ApeConsts.VIDEO_SESSION_ID:
172 this.saveParseData(data, timestamp, this._videoApeMssages); 174 this.saveParseData(data, timestamp, this._videoApeMssages);
  175 + this._pduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.VIDEO_SESSION_ID)
173 break; 176 break;
174 case ApeConsts.AUDIO_SESSION_ID: 177 case ApeConsts.AUDIO_SESSION_ID:
175 this.saveParseData(data, timestamp, this._audioApeMssages); 178 this.saveParseData(data, timestamp, this._audioApeMssages);
  179 + this._pduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.AUDIO_SESSION_ID)
176 break; 180 break;
177 default: 181 default:
178 break; 182 break;
@@ -308,6 +312,7 @@ class RecordPlayBackParse extends Emiter { @@ -308,6 +312,7 @@ class RecordPlayBackParse extends Emiter {
308 } 312 }
309 313
310 GlobalConfig.recordPlaybackMaxTime = this._recordPlaybackMaxTime; 314 GlobalConfig.recordPlaybackMaxTime = this._recordPlaybackMaxTime;
  315 + console.log('MediaChannleList',this.mediaChannleList);
311 loger.log("录制回放数据解析完成,录制回放的总时间长为->", this._recordPlaybackMaxTime); 316 loger.log("录制回放数据解析完成,录制回放的总时间长为->", this._recordPlaybackMaxTime);
312 this._emit(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, {"recordPlaybackMaxTime": this._recordPlaybackMaxTime}); 317 this._emit(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, {"recordPlaybackMaxTime": this._recordPlaybackMaxTime});
313 } 318 }
@@ -383,15 +388,19 @@ class RecordPlayBackParse extends Emiter { @@ -383,15 +388,19 @@ class RecordPlayBackParse extends Emiter {
383 GlobalConfig.activeDocCurPage=1; 388 GlobalConfig.activeDocCurPage=1;
384 this._emit(RecordPlayBackParse.RECORD_PLAYBACK_CLEAR_DATA); 389 this._emit(RecordPlayBackParse.RECORD_PLAYBACK_CLEAR_DATA);
385 //各个ape模块查找关键帧数据 390 //各个ape模块查找关键帧数据
386 - this._searchKeyfram(); 391 + this._searchSeekKeyfram();
387 } 392 }
388 393
389 - _searchKeyfram() { 394 + //拖动进度条后根据seek时间点查找
  395 + _searchSeekKeyfram() {
390 //查找关键帧,找到关键帧后再继续播放 396 //查找关键帧,找到关键帧后再继续播放
391 this._searchApeMessageKeyfram(this._conferApeMssages, ApeConsts.CONFERENCE_SESSION_ID); 397 this._searchApeMessageKeyfram(this._conferApeMssages, ApeConsts.CONFERENCE_SESSION_ID);
392 this._searchApeMessageKeyfram(this._docApeMssages, ApeConsts.DOCSHARING_SESSION_ID); 398 this._searchApeMessageKeyfram(this._docApeMssages, ApeConsts.DOCSHARING_SESSION_ID);
393 - this._searchApeMessageKeyfram(this._videoApeMssages, ApeConsts.VIDEO_SESSION_ID);  
394 - this._searchApeMessageKeyfram(this._audioApeMssages, ApeConsts.AUDIO_SESSION_ID); 399 +
  400 + //this._searchApeMessageKeyfram(this._videoApeMssages, ApeConsts.VIDEO_SESSION_ID);
  401 + //this._searchApeMessageKeyfram(this._audioApeMssages, ApeConsts.AUDIO_SESSION_ID);
  402 +
  403 + this._searchMediaApeMessageKeyfram(this.mediaChannleList);
395 404
396 //聊天模块、白板标注模块的比较特殊,消息是累计的,默认最多30条 405 //聊天模块、白板标注模块的比较特殊,消息是累计的,默认最多30条
397 this._searchChatHistoryMessageKeyfram(this._chatApeMssages, ApeConsts.CHAT_SESSION_ID); 406 this._searchChatHistoryMessageKeyfram(this._chatApeMssages, ApeConsts.CHAT_SESSION_ID);
@@ -425,7 +434,35 @@ class RecordPlayBackParse extends Emiter { @@ -425,7 +434,35 @@ class RecordPlayBackParse extends Emiter {
425 } 434 }
426 loger.log("SEEK->APE", ApeConsts(_apeId), this._recordPlaybackTimestamp, "没有查找到相连的数据"); 435 loger.log("SEEK->APE", ApeConsts(_apeId), this._recordPlaybackTimestamp, "没有查找到相连的数据");
427 } 436 }
428 - 437 + _searchMediaApeMessageKeyfram(_apeMessages){
  438 + loger.log("_searchMediaApeMessageKeyfram->SEEK->APE")
  439 + if(_apeMessages) {
  440 + for (let k in _apeMessages) {
  441 + let channelInfos = _apeMessages[k];
  442 + let messageItem;
  443 + let keyFrameSeekTime = 0;
  444 + for (let i = this._recordPlaybackTimestamp; i > 0; i--) {
  445 + messageItem = channelInfos[i];
  446 +
  447 + if (messageItem) {
  448 + keyFrameSeekTime = (this._recordPlaybackTimestamp - i);
  449 + loger.log("_searchMediaApeMessageKeyfram->SEEK->APE->messageItem",messageItem,'keyFrameSeekTime->',keyFrameSeekTime)
  450 + this._everSocketMsgReceivedHandler(messageItem.byteData, keyFrameSeekTime);
  451 + /*for (let k = 0; k < messageItem.length; k++) {
  452 + this._everSocketMsgReceivedHandler(messageItem[k].byteData, keyFrameSeekTime);
  453 + }
  454 + if (_apeId == ApeConsts.AUDIO_SESSION_ID || _apeId == ApeConsts.VIDEO_SESSION_ID) {
  455 + this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {
  456 + "status": SEEK,
  457 + "keyFrameSeekTime": keyFrameSeekTime
  458 + });
  459 + }
  460 + return;*/
  461 + }
  462 + }
  463 + }
  464 + }
  465 + }
429 //查找聊天模块ape关键帧数据,聊天模块比较特殊,消息是累积的,当前时间戳之前的都需要显示 466 //查找聊天模块ape关键帧数据,聊天模块比较特殊,消息是累积的,当前时间戳之前的都需要显示
430 _searchChatHistoryMessageKeyfram(_apeMessages) { 467 _searchChatHistoryMessageKeyfram(_apeMessages) {
431 //最多30条数据 468 //最多30条数据
@@ -476,6 +513,156 @@ class RecordPlayBackParse extends Emiter { @@ -476,6 +513,156 @@ class RecordPlayBackParse extends Emiter {
476 } 513 }
477 } 514 }
478 } 515 }
  516 + // 数据同步处理 regBuffer已经解开的数据,timestamp 时间戳,data原始数据 ApeConsts.VIDEO_SESSION_ID
  517 + _pduRegAdapterHandler(regBuffer,timestamp,data,sessionId) {
  518 + console.log('RCAdapterPdu--->')
  519 + let regPdu;
  520 + let regItems ;
  521 + let regItemSize ;
  522 + try{
  523 + regPdu = pdu['RCAdapterPdu'].decode(regBuffer);
  524 + regItems = regPdu.item;
  525 + regItemSize = regItems.length;
  526 +
  527 + }catch (err){
  528 + console.warn('RCAdapterPdu->unpack-error',err)
  529 + return;
  530 + }
  531 +
  532 + //onsole.log('RCAdapterPdu',regPdu)
  533 +
  534 + //loger.log(this._session_name + '数据同步消息');
  535 + //loger.log(this._session_name + '数据同步消息.同步条数', regItemSize,"seekTime->",seekTime);
  536 + for (var i = 0; i < regItemSize; ++i) {
  537 + let regItem = regItems[i];
  538 + let regItemType = regItem.type;
  539 + let regItemData = regItem.itemData;
  540 +
  541 + //根据数据包中的type处理数据是否同步
  542 +
  543 + if (pdu.RCPDU_REG_UPDATE_OBJ !== regItemType) {
  544 + if (pdu.RCPDU_REG_RESPONSE_OBJ == regItemType) {
  545 + let regResponsePdu = pdu['RCRegistryResponseObjPdu'].decode(regItemData);
  546 + console.log('regResponsePdu',regResponsePdu)
  547 + //this.regResponsePduHandler(regResponsePdu);
  548 + }
  549 + // 只处理两种类型
  550 + continue;
  551 + }
  552 +
  553 + //具体的数据包
  554 + let regUpdatedItem = pdu['RCRegistryUpdateObjPdu'].decode(regItemData);
  555 + let sub_type = regUpdatedItem.subType;
  556 + let object_id = regUpdatedItem.objId;
  557 + let user_data = regUpdatedItem.userData;
  558 + //console.log('RCRegistryUpdateObjPdu',regUpdatedItem)
  559 +
  560 + switch (sub_type) {
  561 + case pdu.RCPDU_REG_ROSTER_INSERT_PDU:
  562 + //let rosterInsertData = pdu['RCRegstryRosterInsertItemPdu'].decode(user_data);
  563 + // loger.log('RCPDU_REG_ROSTER_INSERT_PDU---->');
  564 +
  565 + let rosterInsertData = pdu['RCRegistryRosterInsertItemPdu'].decode(user_data);
  566 + // console.log('RCRegistryRosterInsertItemPdu',rosterInsertData)
  567 + let rosterInsertItems = rosterInsertData.items;
  568 + let rosterInsertItemsLen = rosterInsertItems.length;
  569 + for (let i = 0; i < rosterInsertItemsLen; ++i) {
  570 + let record = rosterInsertItems[i];
  571 + let recordId = record.item_id;
  572 + let recordData = pdu['RCNodeInfoRecordPdu'].decode(record.item_data);
  573 + //this.rosterInsertHandler(recordId, recordData);
  574 + //console.log('RCNodeInfoRecordPdu',recordData)
  575 + }
  576 + break;
  577 + case pdu.RCPDU_REG_ROSTER_DELETE_PDU:
  578 + let rosterDelData = pdu['RCRegistryRosterDeleteItemPdu'].decode(user_data);
  579 + // console.log('RCRegistryRosterDeleteItemPdu',rosterDelData)
  580 + // this.rosterDelHandler(rosterDelData.nodeId);
  581 + break;
  582 + case pdu.RCPDU_REG_ROSTER_UPDATE_PDU:
  583 + let rosterUpdateData = pdu['RCRegistryRosterUpdateItemPdu'].decode(user_data);
  584 + let rosterUpdateItems = rosterUpdateData.items;
  585 + let rosterUpdateItemsLen = rosterUpdateItems.length;
  586 + //console.log('RCRegistryRosterUpdateItemPdu',rosterUpdateData)
  587 + for (let i = 0; i < rosterUpdateItemsLen; ++i) {
  588 + let node = rosterUpdateItems[i];
  589 + let nodeId = node.nodeId;
  590 + let nodeData = pdu['RCNodeInfoRecordPdu'].decode(node.nodeData);
  591 + // console.log('RCNodeInfoRecordPdu',nodeData)
  592 + //this.rosterUpdateHandler(nodeId, nodeData);
  593 + }
  594 + break;
  595 + case pdu.RCPDU_REG_TABLE_INSERT_PDU:
  596 + let tableInsertData = pdu['RCRegistryTableInsertItemPdu'].decode(user_data);
  597 + let tableInsertItems = tableInsertData.items;
  598 + let tableInsertItemsLen = tableInsertItems.length;
  599 + //console.log('RCRegistryTableInsertItemPdu',tableInsertData)
  600 + for (let i = 0; i < tableInsertItemsLen; ++i) {
  601 + let insertItem = tableInsertItems[i];
  602 + //loger.log("insertItem",insertItem);
  603 +
  604 + //this.tableInsertHandler(insertItem.owner, insertItem.itemIdx, insertItem.itemData);
  605 + }
  606 +
  607 + //文档数据数组内部自己处理数组
  608 + //this.tableInsertApeHandler(tableInsertItems);
  609 + break;
  610 + case pdu.RCPDU_REG_TABLE_DELETE_PDU:
  611 + let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data);
  612 + //console.log("tableDeleteData",object_id,tableDeleteData);
  613 + // console.log('RCRegistryTableDeleteItemPdu',tableDeleteData)
  614 + //this.tableDeleteHandler(object_id, tableDeleteData);
  615 + break;
  616 + case pdu.RCPDU_REG_TABLE_UPDATE_PDU:
  617 + let tableUpdateData = pdu['RCRegistryTableUpdateItemPdu'].decode(user_data);
  618 + let tableUpdateItems = tableUpdateData.items;
  619 + let tableUpdateItemsLen = tableUpdateItems.length;
  620 + //loger.log("RCRegistryTableUpdateItemPdu " + tableUpdateItemsLen);
  621 + //loger.log(tableUpdateData);
  622 + //console.log('RCRegistryTableUpdateItemPdu',tableUpdateData);
  623 +
  624 +
  625 + for (let i = 0; i < tableUpdateItemsLen; ++i) {
  626 + let tableItem = tableUpdateItems[i];
  627 + // this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData,seekTime);
  628 + if(sessionId==ApeConsts.VIDEO_SESSION_ID){
  629 + try {
  630 + let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(tableItem.itemData);
  631 + loger.log('RCVideoChannelInfoPdu->timestamp',timestamp,videoChannelInfo);
  632 + //储存音视频模块的数据
  633 + if(!this.mediaChannleList[videoChannelInfo.channelId]){
  634 + this.mediaChannleList[videoChannelInfo.channelId]={};
  635 + }
  636 + this.mediaChannleList[videoChannelInfo.channelId][timestamp]={parseData:videoChannelInfo,byteData:data,timestamp: timestamp };
  637 + } catch (err) {
  638 + loger.log("RCVideoChannelInfoPdu->unPackPdu error,itemIdx=" + tableItem.itemIdx + " err:" + err.message);
  639 + }
  640 + }else if(sessionId==ApeConsts.AUDIO_SESSION_ID){
  641 + try {
  642 + let audioChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(tableItem.itemData);
  643 + loger.log('RCAudioChannelInfoPdu->timestamp',timestamp,audioChannelInfo);
  644 + //储存音视频模块的数据
  645 + if(!this.mediaChannleList[audioChannelInfo.channelId]){
  646 + this.mediaChannleList[audioChannelInfo.channelId]={};
  647 + }
  648 + this.mediaChannleList[audioChannelInfo.channelId][timestamp]={parseData:audioChannelInfo,byteData:data,timestamp: timestamp };
  649 + } catch (err) {
  650 + loger.log("RCAudioChannelInfoPdu->unPackPdu error,itemIdx=" + tableItem.itemIdx + " err:" + err.message);
  651 + }
  652 + }
  653 +
  654 +
  655 + }
  656 + break;
  657 + case pdu.RCPDU_REG_QUEUE_UPDATE_PDU:
  658 + case pdu.RCPDU_REG_QUEUE_DELETE_PDU:
  659 + case pdu.RCPDU_REG_QUEUE_INSERT_PDU:
  660 + loger.warn('REG QUEUE ARE IGNORED');
  661 + break;
  662 +
  663 + }
  664 + }
  665 + }
479 666
480 } 667 }
481 668
1 -// //////////////////////////////////////////////////////////////////////////////  
2 -//视频模块  
3 -// //////////////////////////////////////////////////////////////////////////////  
4 -  
5 -import Ape from './Ape';  
6 -import ApeConsts from './ApeConsts';  
7 -import pdu from 'pdus';  
8 -import Loger from 'Loger';  
9 -import MessageTypes from 'MessageTypes';  
10 -import GlobalConfig from 'GlobalConfig';  
11 -import EngineUtils from 'EngineUtils';  
12 -import MediaModule from "./MediaModule";  
13 -  
14 -let loger = Loger.getLoger('RecordApe');  
15 -  
16 -class RecordApe extends Ape {  
17 - constructor() {  
18 - super(  
19 - ApeConsts.VIDEO_SESSION_ID,  
20 - ApeConsts.VIDEO_SESSION_NAME,  
21 - ApeConsts.VIDEO_SESSION_TAG  
22 - );  
23 -  
24 - this.mediaModule=new MediaModule();  
25 - this.mediaModule.MEDIA_OBJ_TABLE_ID=ApeConsts.VIDEO_OBJ_TABLE_ID;  
26 - this.mediaModule.mediaChannels={};  
27 - this.mediaModule.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;  
28 -  
29 - // Ape Models  
30 - this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);  
31 - this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.VIDEO_OBJ_TABLE_ID, ApeConsts.VIDEO_OBJ_TABLE_NAME, ApeConsts.VIDEO_OBJ_TABLE_TAG, 0, new ArrayBuffer);  
32 -  
33 - // videoApe 监听视频控制消息,用户之间的消息传递  
34 - this.on(pdu.RCPDU_SEND_VIDEO_DATA_REQUEST, this.receiveVideoCommandHandler.bind(this));  
35 - }  
36 - //ape加入成功  
37 - onJoinChannelHandlerSuccess(){  
38 - //这个设置很重要,因为只有Sass流程完成之后,APE才能取得GlobalConfig中的数据  
39 - this.mediaModule.maxMediaChannel=GlobalConfig.maxVideoChannels;  
40 - }  
41 -  
42 - /////////////发送数据操作////////////////////////////////////////////  
43 - //获取播流地址  
44 - getPlayVideoPath(_param) {  
45 - loger.log('getPlayVideoPath');  
46 - return this.mediaModule.getMediaPlayPath(_param);  
47 - }  
48 -  
49 - //获取推流地址  
50 - getPublishVideoPath(_param) {  
51 - loger.log('获取推流地址->');  
52 - if(!this.mcu.connected){  
53 - loger.warn(GlobalConfig.getCurrentStatus());  
54 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
55 - }  
56 - //监课比较特殊,不占用课堂内的音视频路数,额外创建  
57 - if(GlobalConfig.userRole==ApeConsts.invisible){  
58 - let result=this.mediaModule.getMediaPublishPathForInVisible(_param);  
59 - //this._emit( MessageTypes.VIDEO_GET_PUBLISH_PATH,result);  
60 - return result;  
61 - }  
62 -  
63 - //非监课的身份,需要判断是否可以继续推流  
64 - //需要判断当前已经使用的流路数  
65 - let openChannel=0;  
66 - let allChannels= MediaModule.allMediaChannelsList;  
67 - for(let i in allChannels){  
68 - let channel=allChannels[i];  
69 - if(channel&&channel.status==ApeConsts.CHANNEL_STATUS_OPENING){  
70 - openChannel++;  
71 - }  
72 - }  
73 - //如果已经开启的数量大于等于最大允许开启的数量,不允许再推流  
74 - if(openChannel>=GlobalConfig.maxMediaChannels){  
75 - loger.warn('不能再打开设备->当前开启的设备数量->',openChannel);  
76 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开设备,当前开启的设备数量"};  
77 - }  
78 -  
79 - let result=this.mediaModule.getMediaPublishPath(_param);  
80 - //this._emit( MessageTypes.VIDEO_GET_PUBLISH_PATH,result);  
81 - return result;  
82 - }  
83 -  
84 - //获取当前所有频道信息  
85 - getAllChannelInfo(_param){  
86 - loger.log('获取当前所有频道信息->');  
87 - return this.mediaModule.getAllMediaChannelInfo();  
88 - }  
89 -  
90 - //推流  
91 - publishVideo(_param) {  
92 - if(!this.mcu.connected){  
93 - loger.warn(GlobalConfig.getCurrentStatus());  
94 - //this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"已经断开连接!","mediaId":0});  
95 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
96 - }  
97 -  
98 - if (_param == null||_param.publishUrl == null)  
99 - {  
100 - loger.warn('推流->参数错误', _param);  
101 - //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
102 - //this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"参数错误!","mediaId":0});  
103 - return {"code": ApeConsts.RETURN_FAILED, "data": "参数错误"};  
104 - }  
105 -  
106 - //根据推流的地址获取对应的频道信息  
107 - let needPublishChannelInfo=this.mediaModule.getNeedPublishMediaChannel(_param.publishUrl);  
108 - if(needPublishChannelInfo==null){  
109 - loger.warn('推流->推流数据已经无效', _param);  
110 - //this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"推流数据已经无效!","mediaId":0});  
111 - return {"code": ApeConsts.RETURN_FAILED, "data": "推流数据已经无效"};  
112 - }  
113 -  
114 - //判断当前是否还有空闲的channle  
115 - let freeChannel = this.mediaModule.getFreeMediaChannel();  
116 - if (freeChannel == 0) {  
117 - loger.warn("推流->不能再打开更多的设备 ");  
118 - //this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"不能再打开更多的设备!","mediaId":0});  
119 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaModule.mediaChannels};  
120 - }  
121 -  
122 -  
123 - //判断当前的频道是否已经占用  
124 - if(this.mediaModule.checkChannelIsOpening(needPublishChannelInfo.channelId)){  
125 - if(needPublishChannelInfo.nodeId==GlobalConfig.nodeId){  
126 - loger.warn(needPublishChannelInfo.channelId,"已经推送过消息,不需要再次推送");  
127 - //this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_SUCCESS, "data":"已经推送过消息,不需要再次推送!","mediaId":needPublishChannelInfo.channelId});  
128 - return {"code": ApeConsts.RETURN_SUCCESS, "data":"已经推送过消息,不需要再次推送!","mediaId":needPublishChannelInfo.channelId};  
129 - }else {  
130 - loger.warn(needPublishChannelInfo.channelId,"频道已经被占用");  
131 - //this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!","mediaId":0});  
132 - return {"code": ApeConsts.RETURN_FAILED, "data":"频道已经被占用!","mediaChannels":this.mediaModule.mediaChannels};  
133 - }  
134 - }  
135 -  
136 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
137 - channelInfo.owner=GlobalConfig.nodeId;  
138 - channelInfo.status=ApeConsts.CHANNEL_STATUS_OPENING;  
139 - channelInfo.channelId=needPublishChannelInfo.channelId;  
140 - channelInfo.streamId=needPublishChannelInfo.streamId;//按规则拼接的流名称  
141 - channelInfo.timestamp=needPublishChannelInfo.timestamp;//时间戳  
142 - channelInfo.mediaType=ApeConsts.MEDIA_TYPE_VIDEO;  
143 - this.sendTableUpdateHandler(channelInfo);  
144 -  
145 - //this._emit( MessageTypes.VIDEO_PUBLISH_RESULT,{"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId});  
146 - return {"code": ApeConsts.RETURN_SUCCESS, "data":"推流成功!","mediaId":needPublishChannelInfo.channelId};  
147 - }  
148 -  
149 - //停止推流,  
150 - stopPublishVideo(_param) {  
151 - loger.log('停止推流->',_param);  
152 - if(!this.mcu.connected){  
153 - loger.warn(GlobalConfig.getCurrentStatus());  
154 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
155 - }  
156 -  
157 - //默认为自己的nodeId,_param如果为空,那么默认就是当前自己的nodeId,否则用_param  
158 - let nodeId=GlobalConfig.nodeId;  
159 - if(_param&&parseInt(_param.nodeId)>0){  
160 - nodeId=parseInt(_param.nodeId);  
161 - }  
162 -  
163 - //默认为0,如果releaseChannelId 存在就释放releaseChannelId通道  
164 - let releaseChannelId=0;  
165 - if(_param&&parseInt(_param.mediaId)>0){  
166 - releaseChannelId=parseInt(_param.mediaId);  
167 - }  
168 -  
169 - //释放channelId 的占用  
170 - if(releaseChannelId>0){  
171 - //第一种情况,释放nodeId占用的指定mediaId (channelId)  
172 - this._releaseChannelForNodeId(nodeId,releaseChannelId);  
173 - }else {  
174 - //第二种情况,释放nodeId占用的所有channelId  
175 - this._releaseNodeIdAllChannel(nodeId);  
176 - }  
177 - }  
178 - //释放nodeId占用的指定的channelId频道  
179 - _releaseChannelForNodeId(nodeId,channelId){  
180 - loger.log(nodeId,"_releaseChannelForNodeId-->channelId",channelId);  
181 - let channelInfo=this.mediaModule.mediaChannels[channelId];  
182 - if(channelInfo&&channelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
183 - if(channelInfo.fromNodeId==nodeId){  
184 -  
185 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
186 - channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
187 - channelInfo.channelId=channelId;  
188 -  
189 - this.sendTableUpdateHandler(channelInfo);  
190 - }else {  
191 - loger.warn(channelId,"不属于nodeId",nodeId,"不能释放",channelInfo);  
192 - }  
193 - }else {  
194 - loger.warn(nodeId,"要释放的channel不存在或者已经释放-->channelId",channelInfo);  
195 - }  
196 - }  
197 - //释放nodeId占用的所有频道  
198 - _releaseNodeIdAllChannel(nodeId){  
199 - loger.log(nodeId,"_releaseNodeIdAllChannel",this.mcu.connected);  
200 - if(!this.mcu.connected){  
201 - clearTimeout(this.releaseTimeId);  
202 - loger.warn(GlobalConfig.getCurrentStatus());  
203 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
204 - }  
205 -  
206 - let openingChannel = this.mediaModule.getOpeningMediaChannel(nodeId);  
207 - if (openingChannel == 0) {  
208 - loger.warn(nodeId,"没有占用channel不需要处理");  
209 - return {"code": ApeConsts.RETURN_FAILED, "data": "没有占用channel不需要处理"};  
210 - }  
211 -  
212 - let channelInfo=this.mediaModule.getDefaultChannelInfo();  
213 - channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
214 - channelInfo.channelId=openingChannel;  
215 -  
216 - this.sendTableUpdateHandler(channelInfo);  
217 - //递归检查,800毫秒之后执行  
218 - this.releaseTimeId=setTimeout(function(){  
219 - loger.warn(nodeId,"检查频道是否占用");  
220 - this._releaseNodeIdAllChannel(nodeId);  
221 - }.bind(this),800);  
222 - }  
223 -  
224 - sendVideoBroadcastMsg(_param) {  
225 - if(!this.mcu.connected){  
226 - loger.warn(GlobalConfig.getCurrentStatus());  
227 - return {"code": ApeConsts.RETURN_FAILED, "data": "已经断开连接"};  
228 - }  
229 -  
230 - if (this._classInfo === null || EngineUtils.isEmptyObject(this._classInfo)) {  
231 - loger.log('不能发送Video消息.McuClient还未初始化数据!');  
232 - if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {  
233 - //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);  
234 - return {"code": 1, "data": "不能发送Video消息.McuClient还未初始化数据"};  
235 - }  
236 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能发送Video消息.McuClient还未初始化数据"};  
237 - }  
238 - if (_param == null) {  
239 - loger.warn('sendVideoCommandMsg失败,参数错误', _param);  
240 - //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
241 - return {"code": ApeConsts.RETURN_FAILED, "data": "sendVideoCommandMsg失败,参数错误"};  
242 - }  
243 - // to, message  
244 - loger.log('发送Video消息.', _param);  
245 -  
246 - if (_param.actionType != null && _param.actionType == ApeConsts.MEDIA_ACTION_OPEN_CAMERA) {  
247 - //判断当前开启的视频数量是否已经是最大值,如果已经是最大值,不能再开启  
248 - let freeChannel = this.mediaModule.getFreeMediaChannel();  
249 - if (freeChannel == 0) {  
250 - loger.warn('sendVideoCommandMsg,不能再打开更多的设备', _param);  
251 - return {"code": ApeConsts.RETURN_FAILED, "data": "不能再打开更多的设备","mediaChannels":this.mediaModule.mediaChannels};  
252 - }  
253 - }  
254 -  
255 - let videoSendPdu = new pdu['RCVideoSendDataRequestPdu'];  
256 - videoSendPdu.type = pdu.RCPDU_SEND_VIDEO_DATA_REQUEST;  
257 - videoSendPdu.isPublic = true;  
258 -  
259 - videoSendPdu.fromNodeId = GlobalConfig.nodeId;//发起人  
260 - videoSendPdu.toNodeId = parseInt(_param.toNodeId) || 0;//接收者,0就是所有人  
261 - videoSendPdu.actionType = parseInt(_param.actionType) || ApeConsts.MEDIA_ACTION_DEFAULT;  
262 -  
263 - let dataStr='';  
264 - try{  
265 - dataStr=JSON.stringify(_param.data);  
266 - }catch (err){  
267 - loger.warn('控制消息->JSON转换失败');  
268 - dataStr=_param.data;  
269 - }  
270 - videoSendPdu.data = this._rCArrayBufferUtil.strToUint8Array("h5" + dataStr);//开头两个字会乱码  
271 -  
272 - if (!videoSendPdu.isPublic && 0 != videoSendPdu.toNodeId) {  
273 - //发送给制定的人  
274 - //loger.log('发送私聊Video消息.');  
275 - this.send(videoSendPdu);  
276 - } else {  
277 - //发送给所有人  
278 - //loger.log('发送公聊Video消息.');  
279 - this.sendChatUniform(videoSendPdu);  
280 - }  
281 - return {"code": ApeConsts.RETURN_SUCCESS, "data": ""};  
282 - }  
283 - //发送到mcu同步(更新数据)  
284 - sendTableUpdateHandler(_channelInfo) {  
285 - loger.log("video===sendTableUpdateHandler ");  
286 - let updateModelPdu = this.packPdu(_channelInfo, _channelInfo.channelId);//let updateModelPdu=this.packPdu({},ApeConsts.VIDEO_OBJ_TABLE_ID+2);  
287 -  
288 - if(updateModelPdu==null){  
289 - loger.warn("sendTableUpdateHandler error,updateModelPdu=null");  
290 - return;  
291 - }  
292 -  
293 - let tableItemPdu = new pdu['RCRegistryTableItemPdu'];  
294 - tableItemPdu.itemIdx = _channelInfo.channelId;//tableItemPdu.itemIdx=ApeConsts.VIDEO_OBJ_TABLE_ID+2;  
295 - tableItemPdu.owner = _channelInfo.owner;//0收到flash的是这个值,MCU做了了用户掉线处理,30秒之后会清理owner为0  
296 - tableItemPdu.itemData = updateModelPdu.toArrayBuffer();  
297 -  
298 - //insert  
299 - let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];  
300 - tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//  
301 - tableInsertItemPdu.items.push(tableItemPdu);  
302 -  
303 - let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];  
304 - updateObjPdu.objId = ApeConsts.VIDEO_OBJ_TABLE_ID;//  
305 - updateObjPdu.subType = tableInsertItemPdu.type;  
306 - updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();  
307 -  
308 - //同步  
309 - let adapterItemPdu = new pdu['RCAdapterItemPdu'];  
310 - adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;  
311 - adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();  
312 -  
313 - let adapterPdu = new pdu['RCAdapterPdu'];  
314 - adapterPdu.type = pdu.RCPDU_REG_ADAPTER;  
315 - adapterPdu.item.push(adapterItemPdu);  
316 -  
317 - loger.log("发送更新VIDEO.itemIdx=" + tableItemPdu.itemIdx);  
318 - this.sendUniform(adapterPdu, true);  
319 - }  
320 -  
321 - /////收到消息处理//////////////////////////////////////////////////  
322 -  
323 - // 视频消息处理,内部处理,不需要告诉应用层  
324 - receiveVideoCommandHandler(_data) {  
325 - let videoReceivePdu = pdu['RCVideoSendDataRequestPdu'].decode(_data);  
326 - if (videoReceivePdu == null) {  
327 - loger.warn("视频控制消息处理,收到的消息为null,不做处理");  
328 - return;  
329 - }  
330 - videoReceivePdu.data = this._rCArrayBufferUtil.uint8ArrayToStr(videoReceivePdu.data, 2);//开头两个字会乱码  
331 -  
332 - let dataObj= {};  
333 - try{  
334 - dataObj=JSON.parse(videoReceivePdu.data);  
335 - }catch (err){  
336 - loger.warn('控制消息->JSON转换失败');  
337 - dataObj= videoReceivePdu.data;  
338 - }  
339 - videoReceivePdu.data=dataObj;  
340 - //判断接收者的id,如果不是0,并且也不是自己的nodeId,那么消息不做处理  
341 - if (videoReceivePdu.toNodeId != 0 && videoReceivePdu.toNodeId != GlobalConfig.nodeId) {  
342 - loger.log('视频消息不处理 toNodeId=', videoReceivePdu.toNodeId, "my nodeId=", GlobalConfig.nodeId);  
343 - } else {  
344 - loger.log('视频控制消息处理 .',videoReceivePdu);  
345 - //this._emit(MessageTypes.VIDEO_BROADCAST, videoReceivePdu);  
346 - }  
347 - }  
348 -  
349 -  
350 -  
351 - tableUpdateHandler(owner, itemIdx, itemData,seek) {  
352 - // debugger;  
353 - let unpackChannelInfo = this.unPackPdu(owner, itemIdx, itemData);  
354 - loger.log("tableUpdateHandler->channel",itemIdx,'status->',unpackChannelInfo.status,"seek->",seek);  
355 -  
356 - //****很重要********  
357 - //如果owner的值为0,代表的是这个歌频道已经被释放了(mcu服务端对于占用channel的掉线用户,就是把owner设置为0)  
358 - if(owner==0){  
359 - loger.log("释放占用的频道,channel",itemIdx);  
360 - unpackChannelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;  
361 - unpackChannelInfo.streamId="";  
362 - }  
363 -  
364 - this.mediaModule.mediaChannels[itemIdx] = unpackChannelInfo;  
365 -  
366 - if(unpackChannelInfo&&unpackChannelInfo.fromNodeId!=GlobalConfig.nodeId){  
367 - let receiveChannelInfo={};  
368 - receiveChannelInfo.mediaId=unpackChannelInfo.channelId;  
369 - receiveChannelInfo.fromNodeId=unpackChannelInfo.fromNodeId;  
370 - receiveChannelInfo.userName=unpackChannelInfo.userName||"";  
371 - receiveChannelInfo.userRole=unpackChannelInfo.userRole||ApeConsts.normal;  
372 - //消息不是自己同步的,需要处理  
373 - if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
374 - //正在推流  
375 - receiveChannelInfo.m3u8Url="";  
376 - receiveChannelInfo.rtmpUrl="";  
377 - receiveChannelInfo.replay="";  
378 -  
379 - receiveChannelInfo.seek=seek||0;//这个是录制回放时使用的seek  
380 -  
381 - let m3u8Stream=this.mediaModule.getMediaPlayPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});  
382 - let rtmpStream=this.mediaModule.getMediaPlayPath({"type":"rtmp","streamId": unpackChannelInfo.streamId});  
383 - let replay=this.mediaModule.getMediaRecordPlaybackPath({"type":"m3u8","streamId": unpackChannelInfo.streamId});  
384 -  
385 - if(m3u8Stream.code==0){  
386 - receiveChannelInfo.m3u8Url=m3u8Stream.playUrl;  
387 - }  
388 - if(rtmpStream.code==0){  
389 - receiveChannelInfo.rtmpUrl=rtmpStream.playUrl;  
390 - }  
391 - if(replay.code==0){  
392 - receiveChannelInfo.replay=replay.playUrl;  
393 - }  
394 - loger.log("VIDEO_PLAY",receiveChannelInfo);  
395 - //广播播放视频的消息  
396 - //this._emit(MessageTypes.VIDEO_PLAY, receiveChannelInfo);  
397 - }else {  
398 - loger.log("VIDEO_STOP",receiveChannelInfo);  
399 - //流已经停止  
400 - //this._emit(MessageTypes.VIDEO_STOP, receiveChannelInfo);  
401 - }  
402 - }else {  
403 - loger.warn("视频消息是自己发送的或者是视频消息无效,不需要处理,消息内容如下:");  
404 - loger.log(unpackChannelInfo);  
405 - if(unpackChannelInfo.status==ApeConsts.CHANNEL_STATUS_OPENING){  
406 - GlobalConfig.openCamera=EngineUtils.creatTimestamp();  
407 - GlobalConfig.openMicrophones=GlobalConfig.openCamera;  
408 - }else {  
409 - GlobalConfig.openCamera=0;  
410 - GlobalConfig.openMicrophones=0;  
411 - }  
412 - //this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE,{  
413 - // nodeId:GlobalConfig.nodeId,  
414 - // userRole:GlobalConfig.userRole,  
415 - // userName:GlobalConfig.userName,  
416 - // userId:GlobalConfig.userId,  
417 - // openCamera:GlobalConfig.openCamera,  
418 - // openMicrophones:GlobalConfig.openMicrophones  
419 - // });  
420 - }  
421 -  
422 - MediaModule.allMediaChannelsList[itemIdx]=unpackChannelInfo;  
423 - console.log('MediaModule.allMediaChannelsList',MediaModule.allMediaChannelsList);  
424 - //this._emit(MessageTypes.VIDEO_UPDATE, unpackChannelInfo);  
425 - }  
426 -  
427 - ///////数据的封包和解包/////////////////////////////////////////  
428 - packPdu(_param, _itemIdx) {  
429 - loger.log("packPdu ");  
430 - //验证坐标点集合数组是否合法  
431 - if (_param == null || _itemIdx == null) {  
432 - //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
433 - return null;  
434 - }  
435 -  
436 - //判断type类型,根据type设置不同的参数  
437 - let packPduModel = new pdu['RCVideoChannelInfoPdu'];  
438 - packPduModel.status = _param.status||ApeConsts.CHANNEL_STATUS_RELEASED;  
439 - packPduModel.channelId = _itemIdx;  
440 - packPduModel.streamId = _param.streamId||"";  
441 - packPduModel.siteId=_param.siteId||GlobalConfig.siteId;//GlobalConfig.siteId;  
442 - packPduModel.classId =parseInt(_param.classId)||parseInt(GlobalConfig.classId);  
443 - packPduModel.userId =_param.userId||"0";  
444 - packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_VIDEO;  
445 - packPduModel.timestamp =_param.timestamp||0;  
446 - packPduModel.fromNodeId = GlobalConfig.nodeId;  
447 - packPduModel.userName=GlobalConfig.userName||"";  
448 - packPduModel.toNodeId = 0;  
449 - packPduModel.userRole=GlobalConfig.userRole||ApeConsts.normal;  
450 - loger.log(packPduModel);  
451 - return packPduModel;  
452 - }  
453 -  
454 - unPackPdu(owner, itemIdx, itemData) {  
455 - loger.log("unPackPdu->owner:",owner,"itemIdx->",itemIdx);  
456 - if (owner == null || itemIdx == null || itemData == null) {  
457 - //this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);  
458 - return null;  
459 - }  
460 - try {  
461 - let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(itemData);  
462 - loger.log(videoChannelInfo);  
463 - return videoChannelInfo;  
464 - } catch (err) {  
465 - loger.log("unPackPdu error,itemIdx=" + itemIdx + " err:" + err.message);  
466 - }  
467 - return null;  
468 - }  
469 -}  
470 -  
471 -export default RecordApe;  
472 -