import ByteBuffer from 'libs/bytebuffer.min'; import Emiter from 'Emiter'; import MessageTypes from 'MessageTypes'; import Loger from 'Loger'; import pdu from 'pdus/index'; import PduType from 'pdus/PduType'; import PduConsts from 'pdus/PduConsts'; import ApeConsts from 'apes/ApeConsts'; import ArrayBufferUtil from 'libs/ArrayBufferUtil'; import Base64 from 'base64-js'; import GlobalConfig from 'GlobalConfig'; import EngineUtils from 'EngineUtils'; import TimerCounter from "TimerCounter"; let parseBuffer; // 日志对象 const loger = Loger.getLoger('RecordPlayBackParse'); const Default = 0;//未开始 const PLAY = 1;//播放中 const PAUSE = 2;//暂停 const SEEK = 3;//seek const STOP = 4;//停止 class RecordPlayBackParse extends Emiter { constructor() { super(); //loger.log("RecordPlayBackParse"); parseBuffer = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN); parseBuffer.clear(); this._recordPlaybackTimestamp = 0;//回放的时间 this._recordPlaybackMaxTime = 0;//录制回放的总时间 this._isReady = false;//录制回放是否已经准备完成 this._apes = {}; this.mediaChannleList={}; this._conferApeMssages = {};//会议数据 this._chatApeMssages = {};//聊天数据 this._videoApeMssages = {};//视频数据 this._audioApeMssages = {};//音频数据 this._docApeMssages = {};//文档数据 this._whiteApeMssages = {};//白板数据 this._mediaShareApeMssages={};//媒体共享 this._timerCounter = new TimerCounter();//计时器 this._timerCounter.addTimerCallBack(this._timerCounterUptate.bind(this), 1); } //method--------------------内部--------------------------------------------- // 注册Ape registerApe(ape) { this._apes[ape._session_id] = ape; } initReplay() { this._stopTimerCounter(); this._recordPlaybackTimestamp = 0;//回放的时间 this._recordPlaybackMaxTime = 0;//录制回放的总时间 this._isReady = false;//录制回放是否已经准备完成 this._conferApeMssages = {};//会议数据 this._chatApeMssages = {};//聊天数据 this._videoApeMssages = {};//视频数据 this._audioApeMssages = {};//音频数据 this.mediaChannleList={}; this._docApeMssages = {};//文档数据 this._whiteApeMssages = {};//白板数据 } //发送数据个各个APE模块处理,data是数据,seekTime是当前数据需要seek的时间长度(针对音视频的seek) _everSocketMsgReceivedHandler(data, seekTime) { let pduMsg = pdu.decode_pdu(data); let pduType = pduMsg.get("type"); let pduData = pduMsg.get("data"); //*************非常重要****************** //客户端发送的所有125消息,MCU收到之后会痛120把消息返回给客户端, //所以需要把125消息type转换为120,因为MCU在录制的时候是直接录制客户端发送的消息而不是MCU转换之后的 if (pduType == PduType.RCPDU_UNIFORM_SEND_DATA_REQUEST) { pduMsg.type = PduType.RCPDU_SEND_DATA_REQUEST; pduType = PduType.RCPDU_SEND_DATA_REQUEST; } loger.log('_everSocketMsgReceivedHandler->pduType', pduType, "seekTime->", seekTime); switch (pduType) { case PduType.RCPDU_CONNECT_PROVIDER_RESPONSE: //加入课堂请求返回数据处理 let joinConfPdu = pdu['RCConferenceJoinResponsePdu'].decode(pduData); let pduResultCode = joinConfPdu.result; loger.warn('RCPDU_CONNECT_PROVIDER_RESPONSE ->pduResultCode:' + pduResultCode); switch (pduResultCode) { case PduConsts.RET_SUCCESS: //加入成功 //this._updateMCUConfInfoDescription(joinConfPdu.classDescription); this._emit(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this.classInfo); break; case PduConsts.RET_FULL_CAPACITY: this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_FULL); break; default: loger.warn('JoinConfPdu-未知类型-等待处理.', pduResultCode); break } break; case PduType.RCPDU_SEND_DATA_REQUEST: //先判断当前消息属于哪个APE 根据 sessionId来判断 let ape = this._apes[pduMsg.sessionId]; let sessionLabel = ApeConsts(pduMsg.sessionId); //对方发送消息 if (ape) { let subTypeLabel = pdu.id2type(pduMsg.subType); //loger.log('MCU-SecondLayer封装消息', 'sessionId', sessionLabel, pduMsg.sessionId, 'subtype', subTypeLabel, pduMsg.subType); //ape广播事件,只要ape中监听就能收到 ape._emit(pduMsg.subType, pduMsg.data, seekTime);//seekTime是音视频模块seek的时间长度 } else { loger.warn(sessionLabel + '尚未注册'); } break; default: loger.warn('PDU-未知类型-等待处理.', pduType); } } //解析和储存,录制回放EverSocket底层消息处理 data-数据;timestamp-数据对应的时间戳 _parseSaveSocketMsgReceivedHandler(data, timestamp) { //loger.log('解析和储存录制回放数据-> '); let pduMsg = pdu.decode_pdu(data); let pduType = pduMsg.get("type"); let pduData = pduMsg.get("data"); //*************非常重要****************** //客户端发送的所有125消息,MCU收到之后会痛120把消息返回给客户端, //所以需要把125消息type转换为120,因为MCU在录制的时候是直接录制客户端发送的消息而不是MCU转换之后的 if (pduType == PduType.RCPDU_UNIFORM_SEND_DATA_REQUEST) { pduMsg.type = PduType.RCPDU_SEND_DATA_REQUEST; pduType = PduType.RCPDU_SEND_DATA_REQUEST; } //loger.log('pduType', pduType); switch (pduType) { case PduType.RCPDU_CONNECT_PROVIDER_RESPONSE: //加入课堂请求返回数据处理 let joinConfPdu = pdu['RCConferenceJoinResponsePdu'].decode(pduData); let pduResultCode = joinConfPdu.result; //loger.warn('RCPDU_CONNECT_PROVIDER_RESPONSE ->pduResultCode:' + pduResultCode); switch (pduResultCode) { case PduConsts.RET_SUCCESS: //加入成功 //this._updateMCUConfInfoDescription(joinConfPdu.classDescription); this._emit(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this.classInfo); break; case PduConsts.RET_FULL_CAPACITY: this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_FULL); break; default: loger.warn('JoinConfPdu-未知类型-等待处理.', pduResultCode); break } break; case PduType.RCPDU_SEND_DATA_REQUEST: //先判断当前消息属于哪个APE 根据 sessionId来判断 let ape = this._apes[pduMsg.sessionId]; let sessionLabel = ApeConsts(pduMsg.sessionId); //只做解析存储,不对外发送 //loger.log('解析数据-timestamp->', timestamp, 'sessionId->', pduMsg.sessionId, 'sessionLabel->', sessionLabel); switch (pduMsg.sessionId) { case ApeConsts.CONFERENCE_SESSION_ID: this.saveParseData(data, timestamp, this._conferApeMssages); break; case ApeConsts.CHAT_SESSION_ID: this.saveParseData(data, timestamp, this._chatApeMssages); break; case ApeConsts.DOCSHARING_SESSION_ID: this.saveParseData(data, timestamp, this._docApeMssages); break; case ApeConsts.MEDIA_SESSION_ID: this.saveParseData(data, timestamp, this._mediaShareApeMssages); break; case ApeConsts.WHITEBOARD_SESSION_ID: this.saveParseData(data, timestamp, this._whiteApeMssages); break; case ApeConsts.VIDEO_SESSION_ID: this.saveParseData(data, timestamp, this._videoApeMssages); this.unPackpduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.VIDEO_SESSION_ID) break; case ApeConsts.AUDIO_SESSION_ID: this.saveParseData(data, timestamp, this._audioApeMssages); this.unPackpduRegAdapterHandler(pduMsg.data,timestamp,data,ApeConsts.AUDIO_SESSION_ID) break; default: break; } break; default: loger.warn('PDU-未知类型-等待处理.', pduType); break; } } //保存各个模块的MCU原始数据 saveParseData(data, timestamp, apeMessages) { let messageItem = apeMessages[timestamp]; if (!messageItem) { apeMessages[timestamp] = [];//数组存数据,因为有1秒内收到多个消息的情况,timestamp是按秒记录的 messageItem = apeMessages[timestamp]; } messageItem.push({"timestamp": timestamp, "byteData": data}); } //开启计时器 _startTimerCounter() { if (this._timerCounter) { this._timerCounter.startTimer(); } } //停止计时器 _stopTimerCounter() { if (this._timerCounter) { this._timerCounter.stopTimer(); } } _timerCounterUptate() { this._recordPlaybackTimestamp = this._recordPlaybackTimestamp + 1;//计时 loger.log("录制回放中...", this._recordPlaybackTimestamp); this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": this._recordPlaybackTimestamp}); if (this._recordPlaybackTimestamp >= this._recordPlaybackMaxTime) { loger.log("录制回放结束...当前时间->", this._recordPlaybackTimestamp, " 总时间->", this._recordPlaybackMaxTime); //this._stopTimerCounter(); this.stopRecordPlayback(); return; } //各个APE模块根据时间查找消息数据 this._searchMessageFromTime(this._recordPlaybackTimestamp, this._conferApeMssages,"conferApe"); this._searchMessageFromTime(this._recordPlaybackTimestamp, this._chatApeMssages,"chatApe"); this._searchMessageFromTime(this._recordPlaybackTimestamp, this._docApeMssages,"docApe"); this._searchMessageFromTime(this._recordPlaybackTimestamp, this._mediaShareApeMssages,"mediaShareApe") this._searchMessageFromTime(this._recordPlaybackTimestamp, this._whiteApeMssages,"whiteApe"); this._searchMessageFromTime(this._recordPlaybackTimestamp, this._videoApeMssages,"videoAp"); this._searchMessageFromTime(this._recordPlaybackTimestamp, this._audioApeMssages,"audioApe"); } //加载录制文件 readyRecordPlay() { this.initReplay(); loger.log("读取回放数据"); //let url = `http://123.56.73.119:80/h5dev/20170306/1357644520_20170306.rec`; let url = `http://${ GlobalConfig.RecordServerIP}:${ GlobalConfig.RecordServerPort}/${GlobalConfig.recordFileName}`; loger.log(url); fetch(url, { timeout: 180000 //加载文件超时时间3分 }) .then(ret => { if (ret.ok) { return ret.arrayBuffer(); } else { loger.error(`读取回放数据-网络异常.状态码:${ret.status}`); this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_RECORD_PLAY_BACK_DATA_FAILED); throw ''; } }) .then(ret => { if (ret) { loger.log('读取回放数据-完成'); this._loadRecordDataSuccess(ret); } else { loger.warn('读取回放数据-失败.'); this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_RECORD_PLAY_BACK_DATA_FAILED); } }) .catch(err => { loger.error(`读取回放数据.状态码:${err}`); this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_RECORD_PLAY_BACK_DATA_FAILED); }); } _loadRecordDataSuccess(arrayBuffer) { loger.log("获取录制回放数据的长度", arrayBuffer.byteLength); if (parseBuffer) { parseBuffer.clear(); parseBuffer.append(arrayBuffer); //解析数据 this.parseArrayBuf(); } } //解析数据 parseArrayBuf() { //this._messages = {}; let byteLength = parseBuffer.offset; parseBuffer.byteOffset = 0; var position = 0; while (position < byteLength) { let timestamp = parseBuffer.readUInt32(position); position += 4;//4字节 let byteLen = parseBuffer.readUInt32(position); position += 4;//4字节 let byteData = parseBuffer.buffer.slice(position, (position + byteLen)); position += byteLen; //按时间戳解保存数据 this._parseSaveSocketMsgReceivedHandler(byteData, timestamp); //记录最后一个数据的时间戳作为整个录制回放的总时间戳 this._recordPlaybackMaxTime = timestamp; } this._recordPlaybackTimestamp = 0; this._isReady = true; this._stopTimerCounter(); //录制回放的总时间长度按课堂最长时间计算,不能按最后一个消息的时间计算 /*if(this._recordPlaybackMaxTime<GlobalConfig.classTimestamp){ this._recordPlaybackMaxTime=GlobalConfig.classTimestamp; }*/ if(this._recordPlaybackMaxTime<GlobalConfig.recordTimestamp){ this._recordPlaybackMaxTime=GlobalConfig.recordTimestamp; } GlobalConfig.recordPlaybackMaxTime = this._recordPlaybackMaxTime; console.log('MediaChannleList',this.mediaChannleList); loger.log("录制回放数据解析完成,录制回放的总时间长为->", this._recordPlaybackMaxTime); this._emit(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, {"recordPlaybackMaxTime": this._recordPlaybackMaxTime}); } //根据时间查找数据 _searchMessageFromTime(_timestamp, _apeMessages,_ape) { let msgDataArr = _apeMessages[_timestamp]; if (!msgDataArr) { //没有数据,需要查找当前时间点属于哪一个时间戳关键帧 } else { //把时间点对应的数据发送,同一秒内有存在多个数据的情况 loger.log(_ape,"回放数据->",msgDataArr.length) for (let i = 0; i < msgDataArr.length; i++) { this._everSocketMsgReceivedHandler(msgDataArr[i].byteData, 0); } } } //method------------外部接口------------------------------------- //开始播放 startRecordPlayback(_param) { if (!this._isReady) { return {"code": ApeConsts.RETURN_FAILED, "data": "录制回放还未准备完成"}; } loger.log("classStatusInfo",GlobalConfig.classStatusInfo); this._startTimerCounter(); this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": PLAY}); } //停止播放 stopRecordPlayback(_param) { this._stopTimerCounter(); this._recordPlaybackTimestamp = 0; //把记录的文档信息也要清除 GlobalConfig.activeDocId=0; GlobalConfig.activeDocCurPage=1; this._emit(RecordPlayBackParse.RECORD_PLAYBACK_CLEAR_DATA); this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": STOP}); } //暂停播放 pauseRecordPlayback(_param) { this._stopTimerCounter(); this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, {"status": PAUSE}); } //跳转到指定时间点播放 seekRecordPlayback(_param) { if (!this._isReady) { return {"code": ApeConsts.RETURN_FAILED, "data": "录制回放还未准备完成"}; } if (!_param || !_param.time) { return {"code": ApeConsts.RETURN_FAILED, "data": "参数不正确"}; } //先暂停,更改进行的时间 this._stopTimerCounter(); this._recordPlaybackTimestamp = _param.time || 0; //把记录的文档信息也要清除 GlobalConfig.activeDocId=0; GlobalConfig.activeDocCurPage=1; this._emit(RecordPlayBackParse.RECORD_PLAYBACK_CLEAR_DATA); //各个ape模块查找关键帧数据 this._searchSeekKeyfram(); } //拖动进度条后根据seek时间点查找 _searchSeekKeyfram() { //查找关键帧,找到关键帧后再继续播放 this._searchApeMessageKeyfram(this._conferApeMssages, ApeConsts.CONFERENCE_SESSION_ID); this._searchApeMessageKeyfram(this._docApeMssages, ApeConsts.DOCSHARING_SESSION_ID); /* //旧的音视频查找关键帧数据,多路音视频的时候存在显示问题,已经废弃 //this._searchApeMessageKeyfram(this._videoApeMssages, ApeConsts.VIDEO_SESSION_ID); //this._searchApeMessageKeyfram(this._audioApeMssages, ApeConsts.AUDIO_SESSION_ID); */ //音视频模块的查找规则和其他模块不一样,音视频按频道查找,如果课堂内存在多个频道,都要查 this.searchMediaApeMessageKeyfram(this.mediaChannleList); //媒体共享模块 this.searchMediaShareApeMessageKeyfram(this._mediaShareApeMssages); //聊天模块、白板标注模块的比较特殊,消息是累计的,默认最多30条 this._searchChatHistoryMessageKeyfram(this._chatApeMssages, ApeConsts.CHAT_SESSION_ID); this._searchWhiteboradHistoryMessageKeyfram(this._whiteApeMssages, ApeConsts.WHITEBOARD_SESSION_ID); //各个ape模块无论有没有找到关键帧数据,都继续播放 this._startTimerCounter(); } //查找ape关键帧数据 _searchApeMessageKeyfram(_apeMessages, _apeId) { if(!_apeMessages){ return; } let messageItem; let keyFrameSeekTime = 0; for (let i = this._recordPlaybackTimestamp; i > 0; i--) { messageItem = _apeMessages[i]; if (messageItem) { keyFrameSeekTime = (this._recordPlaybackTimestamp - i) loger.log("SEEK->APE", ApeConsts(_apeId), this._recordPlaybackTimestamp, "查找到相连的timestamp->", i, '需要seek->', keyFrameSeekTime, "秒"); //把时间点对应的数据发送,同一秒内有存在多个数据的情况 for (let k = 0; k < messageItem.length; k++) { this._everSocketMsgReceivedHandler(messageItem[k].byteData, keyFrameSeekTime); } if (_apeId == ApeConsts.AUDIO_SESSION_ID || _apeId == ApeConsts.VIDEO_SESSION_ID) { this._emit(MessageTypes.RECORD_PLAYBACK_UPDATE, { "status": SEEK, "keyFrameSeekTime": keyFrameSeekTime }); } return; } } loger.log("SEEK->APE", ApeConsts(_apeId), this._recordPlaybackTimestamp, "没有查找到相连的数据"); } //音视频模块seek的时候,查找当前seek点的关键帧数据,所有频道的数据都需要查一下,否则多路视频的时候会显示不全 searchMediaApeMessageKeyfram(_apeMessages){ if(!_apeMessages){ return; } console.log('SEEK->查找音视频模块数据',_apeMessages) if(_apeMessages) { for (let k in _apeMessages) { let channelInfos = _apeMessages[k]; let messageItem; let keyFrameSeekTime = 0; for (let i = this._recordPlaybackTimestamp; i > 0; i--) { messageItem = channelInfos[i]; if (messageItem) { keyFrameSeekTime = (this._recordPlaybackTimestamp - i); loger.log("SEEK->查找音视频模块数据->",messageItem,'keyFrameSeekTime->',keyFrameSeekTime) this._everSocketMsgReceivedHandler(messageItem.byteData, keyFrameSeekTime); break; } } } } } //媒体共享模块查找关键帧时间戳的消息 searchMediaShareApeMessageKeyfram(_apeMessages){ if(!_apeMessages){ return; } let messageItem; let keyFrameSeekTime = 0; for (let i = this._recordPlaybackTimestamp; i > 0; i--) { messageItem = _apeMessages[i]; if (messageItem) { keyFrameSeekTime = (this._recordPlaybackTimestamp - i) loger.log("SEEK->APE",'媒体共享',this._recordPlaybackTimestamp, "查找到相连的timestamp->", i, '需要seek->', keyFrameSeekTime, "秒"); //把时间点对应的数据发送,同一秒内有存在多个数据的情况 for (let k = 0; k < messageItem.length; k++) { this._everSocketMsgReceivedHandler(messageItem[k].byteData, keyFrameSeekTime); } return; } } loger.log("SEEK->APE->媒体共享", this._recordPlaybackTimestamp, "没有查找到相连的数据"); } //查找聊天模块ape关键帧数据,聊天模块比较特殊,消息是累积的,当前时间戳之前的都需要显示 _searchChatHistoryMessageKeyfram(_apeMessages) { if(!_apeMessages){ return; } //最多30条数据 let counter=0; let messageItem; let mssageArr=[]; for (let i = this._recordPlaybackTimestamp; i > 0; i--) { messageItem = _apeMessages[i]; if (messageItem) { //把时间点对应的数据发送,同一秒内有存在多个数据的情况 for (let i = 0; i < messageItem.length; i++) { //this._everSocketMsgReceivedHandler(messageItem[i].byteData, 0); mssageArr.push(messageItem[i].byteData); counter++; if(counter>30){ loger.warn("SEEK->最多处理历史消息30条"); break; } } } } //mssageArr记录的数据是按时间最大排序的,发消息的时候需要从时间小的开始,倒着发数据 let len=mssageArr.length; if(len>0){ for (let k=len-1;k>=0;k--){ this._everSocketMsgReceivedHandler(mssageArr[k], 0); } } } //查找白板标注模块ape关键帧数据,聊天模块比较特殊,消息是累积的,当前时间戳之前的都需要显示 _searchWhiteboradHistoryMessageKeyfram(_apeMessages) { if(!_apeMessages){ return; } //最多30条数据 let counter=0; let messageItem; for (let i = this._recordPlaybackTimestamp; i > 0; i--) { messageItem = _apeMessages[i]; if (messageItem) { //把时间点对应的数据发送,同一秒内有存在多个数据的情况 for (let i = 0; i < messageItem.length; i++) { this._everSocketMsgReceivedHandler(messageItem[i].byteData, 0); counter++; if(counter>30){ loger.warn("SEEK->最多处理历史消息30条"); return; } } } } } //音视频的数据需要解析,然后按频道储存数据 // 解析pdu RCAdapterPdu的数据: regBuffer(RCAdapterPdu数据),timestamp(时间戳), data(mcu的原始数据) sessionId(类型) unPackpduRegAdapterHandler(regBuffer, timestamp, data, sessionId) { let regPdu; let regItems ; let regItemSize ; try{ console.log('RCAdapterPdu--->') regPdu = pdu['RCAdapterPdu'].decode(regBuffer); regItems = regPdu.item; regItemSize = regItems.length; }catch (err){ console.warn('RCAdapterPdu->unpack-error->type类型不对') return; } for (var i = 0; i < regItemSize; ++i) { let regItem = regItems[i]; let regItemType = regItem.type; let regItemData = regItem.itemData; //根据数据包中的type处理数据是否同步 if (pdu.RCPDU_REG_UPDATE_OBJ !== regItemType) { if (pdu.RCPDU_REG_RESPONSE_OBJ == regItemType) { let regResponsePdu = pdu['RCRegistryResponseObjPdu'].decode(regItemData); console.log('regResponsePdu',regResponsePdu) //this.regResponsePduHandler(regResponsePdu); } // 只处理两种类型 continue; } //具体的数据包 let regUpdatedItem = pdu['RCRegistryUpdateObjPdu'].decode(regItemData); let sub_type = regUpdatedItem.subType; let object_id = regUpdatedItem.objId; let user_data = regUpdatedItem.userData; //console.log('RCRegistryUpdateObjPdu',regUpdatedItem) switch (sub_type) { case pdu.RCPDU_REG_ROSTER_INSERT_PDU: let rosterInsertData = pdu['RCRegistryRosterInsertItemPdu'].decode(user_data); let rosterInsertItems = rosterInsertData.items; let rosterInsertItemsLen = rosterInsertItems.length; for (let i = 0; i < rosterInsertItemsLen; ++i) { let record = rosterInsertItems[i]; let recordId = record.item_id; let recordData = pdu['RCNodeInfoRecordPdu'].decode(record.item_data); } break; case pdu.RCPDU_REG_ROSTER_DELETE_PDU: let rosterDelData = pdu['RCRegistryRosterDeleteItemPdu'].decode(user_data); // console.log('RCRegistryRosterDeleteItemPdu',rosterDelData) break; case pdu.RCPDU_REG_ROSTER_UPDATE_PDU: let rosterUpdateData = pdu['RCRegistryRosterUpdateItemPdu'].decode(user_data); let rosterUpdateItems = rosterUpdateData.items; let rosterUpdateItemsLen = rosterUpdateItems.length; //console.log('RCRegistryRosterUpdateItemPdu',rosterUpdateData) for (let i = 0; i < rosterUpdateItemsLen; ++i) { let node = rosterUpdateItems[i]; let nodeId = node.nodeId; let nodeData = pdu['RCNodeInfoRecordPdu'].decode(node.nodeData); // console.log('RCNodeInfoRecordPdu',nodeData) } break; case pdu.RCPDU_REG_TABLE_INSERT_PDU: let tableInsertData = pdu['RCRegistryTableInsertItemPdu'].decode(user_data); let tableInsertItems = tableInsertData.items; let tableInsertItemsLen = tableInsertItems.length; //console.log('RCRegistryTableInsertItemPdu',tableInsertData) for (let i = 0; i < tableInsertItemsLen; ++i) { let insertItem = tableInsertItems[i]; //loger.log("insertItem",insertItem); //this.tableInsertHandler(insertItem.owner, insertItem.itemIdx, insertItem.itemData); } break; case pdu.RCPDU_REG_TABLE_DELETE_PDU: let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data); //console.log("tableDeleteData",object_id,tableDeleteData); break; case pdu.RCPDU_REG_TABLE_UPDATE_PDU: let tableUpdateData = pdu['RCRegistryTableUpdateItemPdu'].decode(user_data); let tableUpdateItems = tableUpdateData.items; let tableUpdateItemsLen = tableUpdateItems.length; for (let i = 0; i < tableUpdateItemsLen; ++i) { let tableItem = tableUpdateItems[i]; //只处理音视频模块的消息 if(sessionId==ApeConsts.VIDEO_SESSION_ID){ try { let videoChannelInfo = pdu['RCVideoChannelInfoPdu'].decode(tableItem.itemData); loger.log('RCVideoChannelInfoPdu->timestamp',timestamp,videoChannelInfo); //储存音视频模块的数据 if(!this.mediaChannleList[videoChannelInfo.channelId]){ this.mediaChannleList[videoChannelInfo.channelId]={}; } this.mediaChannleList[videoChannelInfo.channelId][timestamp]={parseData:videoChannelInfo,byteData:data,timestamp: timestamp }; } catch (err) { loger.log("RCVideoChannelInfoPdu->unPackPdu->error->" + tableItem.itemIdx + " err:" + err.message); } }else if(sessionId==ApeConsts.AUDIO_SESSION_ID){ try { let audioChannelInfo = pdu['RCAudioChannelInfoPdu'].decode(tableItem.itemData); loger.log('RCAudioChannelInfoPdu->timestamp',timestamp,audioChannelInfo); //储存音视频模块的数据 if(!this.mediaChannleList[audioChannelInfo.channelId]){ this.mediaChannleList[audioChannelInfo.channelId]={}; } this.mediaChannleList[audioChannelInfo.channelId][timestamp]={parseData:audioChannelInfo,byteData:data,timestamp: timestamp }; } catch (err) { loger.log("RCAudioChannelInfoPdu->unPackPdu->error->" + tableItem.itemIdx + " err:" + err.message); } } } break; case pdu.RCPDU_REG_QUEUE_UPDATE_PDU: case pdu.RCPDU_REG_QUEUE_DELETE_PDU: case pdu.RCPDU_REG_QUEUE_INSERT_PDU: loger.warn('REG QUEUE ARE IGNORED'); break; default : break; } } } } RecordPlayBackParse.prototype.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS = RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS = 'class_join_recordPlayback_success';//加入录制回放成功 RecordPlayBackParse.prototype.RECORD_PLAYBACK_CLEAR_DATA = RecordPlayBackParse.RECORD_PLAYBACK_CLEAR_DATA = 'record_playback_clear_data';//清除录制回放数据 export default new RecordPlayBackParse;