李勇

1.音视频模块在录制状态发生改变的时候增加更新接口,把当前的音视频模块数据录制;

2.音视频模块发起人的身份和名称不对应的bug修复
3.媒体共享模块的消息中增加SEEK字段
4.录制回放中增加媒体共享的SEEK功能
此 diff 太大无法显示。
... ... @@ -32,7 +32,7 @@ import QuestionApe from 'apes/QuestionApe';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('McuClient');
let _sdkInfo = {"version": "v1.32.0.20170613", "author": "www.3mang.com"};
let _sdkInfo = {"version": "v1.32.1.20170614", "author": "www.3mang.com"};
//APE
let _sass;
... ... @@ -332,11 +332,26 @@ export default class MessageEntrance extends Emiter {
//开启录制成功
_onClassRecordSuccess(_param) {
if (_doc_ape) {
_doc_ape.updaterRecordStatus();
}
if (_whiteboard_ape) {
_whiteboard_ape.updaterRecordStatus();
this.updaterRecordAllApeStatus(_param);
}
//录制状态发送改变,更新所有模块的当前数据发送到MCU
updaterRecordAllApeStatus(_param){
//老师身份和非录制回放的时候执行,录制状态发送改变,需要更新当前的数据,否则已有的消息会录制不上
if(GlobalConfig.isHost&&!GlobalConfig.isRecordPlayBack){
loger.warn('录制状态发送改变->更新所有模块的当前数据发送到MCU');
if (_doc_ape) {
_doc_ape.updaterRecordApeStatus();
}
if (_whiteboard_ape) {
_whiteboard_ape.updaterRecordApeStatus();
}
if (_video_ape) {
_video_ape.updaterRecordApeStatus();
}
if (_audio_ape) {
_audio_ape.updaterRecordApeStatus();
}
}
}
... ... @@ -518,6 +533,7 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.fps = _data.fps || 15;
GlobalConfig.gop = _data.gop || 3;
GlobalConfig.videoQuality = parseInt(_data.videoQuality);
GlobalConfig.curVideoQuality= GlobalConfig.videoQuality;
//是否自动开始(身份是host的时候才用到的)
GlobalConfig.isAutoStartClass = _data.autoRecord || 0;
... ...
... ... @@ -399,16 +399,24 @@ class RecordPlayBackParse extends Emiter {
//音视频模块的查找规则和其他模块不一样,音视频按频道查找,如果课堂内存在多个频道,都要查
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--) {
... ... @@ -434,7 +442,9 @@ class RecordPlayBackParse extends Emiter {
//音视频模块seek的时候,查找当前seek点的关键帧数据,所有频道的数据都需要查一下,否则多路视频的时候会显示不全
searchMediaApeMessageKeyfram(_apeMessages){
loger.log("SEEK->查找音视频模块数据");
if(!_apeMessages){
return;
}
console.log('SEEK->查找音视频模块数据',_apeMessages)
if(_apeMessages) {
for (let k in _apeMessages) {
... ... @@ -453,8 +463,33 @@ class RecordPlayBackParse extends Emiter {
}
}
}
//媒体共享模块查找关键帧时间戳的消息
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;
... ... @@ -485,6 +520,9 @@ class RecordPlayBackParse extends Emiter {
//查找白板标注模块ape关键帧数据,聊天模块比较特殊,消息是累积的,当前时间戳之前的都需要显示
_searchWhiteboradHistoryMessageKeyfram(_apeMessages) {
if(!_apeMessages){
return;
}
//最多30条数据
let counter=0;
let messageItem;
... ...
... ... @@ -160,7 +160,7 @@ export default class Ape extends Emiter {
}
//文档数据数组内部自己处理数组
this.tableInsertApeHandler(tableInsertItems);
this.tableInsertApeHandler(tableInsertItems,seekTime);
break;
case pdu.RCPDU_REG_TABLE_DELETE_PDU:
let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data);
... ... @@ -181,7 +181,7 @@ export default class Ape extends Emiter {
}
//白板,文档数据数组内部自己处理数组
this.tableUpdateApeHandler(tableUpdateItems);
this.tableUpdateApeHandler(tableUpdateItems,seekTime);
break;
case pdu.RCPDU_REG_QUEUE_UPDATE_PDU:
case pdu.RCPDU_REG_QUEUE_DELETE_PDU:
... ...
... ... @@ -424,6 +424,22 @@ class AudioApe extends Ape {
this._emit(MessageTypes.AUDIO_UPDATE, unpackChannelInfo);
}
//更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
updaterRecordApeStatus(_param){
console.warn("录制状态发送改变->更新当前的状态->",this.mediaModule.mediaChannels);
for (let i in this.mediaModule.mediaChannels){
let channelInfo=this.mediaModule.mediaChannels[i];
if(channelInfo){
if(channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){
channelInfo.owner=0;
}else {
channelInfo.owner=channelInfo.fromNodeId;
}
this.sendTableUpdateHandler(channelInfo);
}
}
}
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param, _itemIdx) {
//验证坐标点集合数组是否合法
... ... @@ -443,10 +459,10 @@ class AudioApe extends Ape {
packPduModel.userId =_param.userId||"0";
packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_AUDIO;
packPduModel.timestamp =_param.timestamp||EngineUtils.creatTimestamp();
packPduModel.fromNodeId = GlobalConfig.nodeId;
packPduModel.userName=GlobalConfig.userName||"";
packPduModel.fromNodeId =_param.nodeId|| GlobalConfig.nodeId;
packPduModel.userName=_param.userName||GlobalConfig.userName||"";
packPduModel.toNodeId = 0;
packPduModel.userRole=GlobalConfig.userRole||ApeConsts.normal;
packPduModel.userRole=_param.userRole||GlobalConfig.userRole;
packPduModel.screenWidth=_param.screenWidth||GlobalConfig.screenWidth;
packPduModel.screenHeight=_param.screenHeight||GlobalConfig.screenHeight;
loger.log("packPdu->",packPduModel);
... ...
... ... @@ -309,14 +309,19 @@ class DocApe extends Ape {
return itemDataInfo;
}
//更新文档模块的录制信息,每次开启录制的时候需要把当前文档的信息更新一次
updaterRecordStatus(_param){
if(GlobalConfig.isHost&&!GlobalConfig.isRecordPlayBack&&GlobalConfig.activeDocId>0){
loger.log("开启录制成功->更新当前的文档数据->docId:", GlobalConfig.activeDocId, 'page:',GlobalConfig.activeDocCurPage);
updaterRecordApeStatus(_param){
/* if(GlobalConfig.isHost&&!GlobalConfig.isRecordPlayBack&&GlobalConfig.activeDocId>0){
loger.log("录制状态发送改变->更新当前的文档数据->docId:", GlobalConfig.activeDocId, 'page:',GlobalConfig.activeDocCurPage);
this.documentSwitchPage({
"itemIdx": GlobalConfig.activeDocId,
"curPageNo":GlobalConfig.activeDocCurPage
});
}
}*/
loger.warn("录制状态发送改变->更新当前的文档数据->docId:", GlobalConfig.activeDocId, 'page:',GlobalConfig.activeDocCurPage);
this.documentSwitchPage({
"itemIdx": GlobalConfig.activeDocId,
"curPageNo":GlobalConfig.activeDocCurPage
});
}
//清除当前文档模块的数据
clearData(){
... ...
... ... @@ -283,7 +283,7 @@ class MediaModule {
channelInfo.status=ApeConsts.CHANNEL_STATUS_RELEASED;
channelInfo.fromNodeId=GlobalConfig.nodeId;
channelInfo.channelId=0;//channelId不能为0
channelInfo.streamId=""
channelInfo.streamId="";
channelInfo.classId=GlobalConfig.classId;
channelInfo.siteId=GlobalConfig.siteId;
channelInfo.toNodeId=0;
... ...
... ... @@ -149,21 +149,26 @@ class MediaSharedApe extends Ape {
//组织完整的媒体文件信息,包含上传时的信息和转换后的完整地址信息
_mediaSharedPackFullInfo(_itemDataInfo){
let itemDataInfo=_itemDataInfo;
if(itemDataInfo.seek==null){
if(!itemDataInfo.seek){
itemDataInfo.seek=1;
}
loger.log('mediaPackFullInfo->', itemDataInfo);
return itemDataInfo;
}
//更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
updaterRecordStatus(_param){
if(GlobalConfig.isHost&&!GlobalConfig.isRecordPlayBack&&GlobalConfig.activeMediaId>0){
updaterRecordApeStatus(_param){
/*if(GlobalConfig.isHost&&!GlobalConfig.isRecordPlayBack&&GlobalConfig.activeMediaId>0){
loger.log("开启录制成功->更新当前的媒体文件数据->fileId:", GlobalConfig.activeMediaId, 'page:',GlobalConfig.activeMediaSeek);
this.mediaSharedSeek({
"itemIdx": GlobalConfig.activeMediaId,
"seek":GlobalConfig.activeMediaSeek
});
}
}*/
loger.warn("录制状态发送改变->更新当前的媒体文件数据->fileId:", GlobalConfig.activeMediaId, 'page:',GlobalConfig.activeMediaSeek);
this.mediaSharedSeek({
"itemIdx": GlobalConfig.activeMediaId,
"seek":GlobalConfig.activeMediaSeek
});
}
//清除当前媒体文件模块的数据
clearData(){
... ... @@ -331,16 +336,17 @@ class MediaSharedApe extends Ape {
tableInsertApeHandler(_tableUpdateItems, _seekTime) {
let tableInsertItems =_tableUpdateItems;
let tableInsertItemsLen = tableInsertItems.length;
loger.log('添加媒体文件->', "activeDocId->", GlobalConfig.activeMediaId, "tableUpdateItemsLen->", tableInsertItemsLen);
loger.log('添加媒体文件->_seekTime:'+_seekTime, "activeMediaId->", GlobalConfig.activeMediaId, "tableUpdateItemsLen->", tableInsertItemsLen);
for (let i = 0; i < tableInsertItemsLen; ++i) {
let insertItem = tableInsertItems[i];
//this.tableInsertHandler(insertItem.owner, insertItem.itemIdx, insertItem.itemData);
let itemDataInfo = this.unPackPdu(insertItem.owner, insertItem.itemIdx, insertItem.itemData);
if(itemDataInfo){
itemDataInfo.seek=itemDataInfo.seek+parseInt(_seekTime);//seek是媒体文件自己的,_seekTime是录制回放时进度条换算的
this.mediaSharedList[insertItem.itemIdx] = itemDataInfo;
if (itemDataInfo.status == 1) {
GlobalConfig.activeMediaId = itemDataInfo.itemIdx;//当前激活的媒体文件ID
GlobalConfig.activeMediaSeek = itemDataInfo.seek;//当前激活的媒体文件的当前页
GlobalConfig.activeMediaSeek = itemDataInfo.seek;
loger.log('添加媒体文件->设置当前激活的媒体文件id');
}
let getMediaPackFullInfo= this._mediaSharedPackFullInfo(itemDataInfo);
... ... @@ -376,15 +382,16 @@ class MediaSharedApe extends Ape {
}
tableUpdateApeHandler(_tableUpdateItems, _seekTime) {
let tableUpdateItemsLen = _tableUpdateItems.length;
loger.log('更新媒体文件->', "activeDocId->", GlobalConfig.activeMediaId, "更新的数量->", tableUpdateItemsLen);
loger.log('更新媒体文件->_seekTime:'+_seekTime, "activeDocId->", GlobalConfig.activeMediaId, "更新的数量->", tableUpdateItemsLen);
for (let i = 0; i < tableUpdateItemsLen; ++i) {
let tableItem = _tableUpdateItems[i];
let itemDataInfo = this.unPackPdu(tableItem.owner, tableItem.itemIdx, tableItem.itemData);
if (itemDataInfo != null) {
itemDataInfo.seek=itemDataInfo.seek+parseInt(_seekTime);
this.mediaSharedList[tableItem.itemIdx] = itemDataInfo;
if (itemDataInfo && itemDataInfo.status ==1) {
GlobalConfig.activeMediaId = itemDataInfo.itemIdx;//当前激活的媒体文件ID
GlobalConfig.activeMediaSeek = itemDataInfo.seek;//当前激活的媒体文件的当前页
GlobalConfig.activeMediaSeek = itemDataInfo.seek;
loger.log('更新媒体文件->设置当前激活的媒体文件id->', GlobalConfig.activeMediaId, "curPageNum->", GlobalConfig.activeMediaSeek);
}
let getMediaPackFullInfo= this._mediaSharedPackFullInfo(itemDataInfo);
... ...
... ... @@ -352,11 +352,9 @@ class VideoApe extends Ape {
if (!videoSendPdu.isPublic && 0 != videoSendPdu.toNodeId) {
//发送给制定的人
//loger.log('发送私聊Video消息.');
this.send(videoSendPdu);
} else {
//发送给所有人
//loger.log('发送公聊Video消息.');
this.sendChatUniform(videoSendPdu);
}
return {"code": ApeConsts.RETURN_SUCCESS, "data": ""};
... ... @@ -538,6 +536,21 @@ class VideoApe extends Ape {
}
}
//更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
updaterRecordApeStatus(_param){
console.warn("录制状态发送改变->更新当前的状态->",this.mediaModule.mediaChannels);
for (let i in this.mediaModule.mediaChannels){
let channelInfo=this.mediaModule.mediaChannels[i];
if(channelInfo){
if(channelInfo.status==ApeConsts.CHANNEL_STATUS_RELEASED){
channelInfo.owner=0;
}else {
channelInfo.owner=channelInfo.fromNodeId;
}
this.sendTableUpdateHandler(channelInfo);
}
}
}
//清除当前模块的数据
clearData(){
... ... @@ -547,7 +560,6 @@ class VideoApe extends Ape {
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param, _itemIdx) {
loger.log("packPdu ");
//验证坐标点集合数组是否合法
if (_param == null || _itemIdx == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
... ... @@ -564,13 +576,13 @@ class VideoApe extends Ape {
packPduModel.userId =_param.userId||"0";
packPduModel.mediaType =_param.mediaType|| ApeConsts.MEDIA_TYPE_VIDEO;
packPduModel.timestamp =_param.timestamp||0;
packPduModel.fromNodeId = GlobalConfig.nodeId;
packPduModel.userName=GlobalConfig.userName||"";
packPduModel.fromNodeId = _param.nodeId||GlobalConfig.nodeId;
packPduModel.userName=_param.userName||GlobalConfig.userName;
packPduModel.toNodeId = 0;
packPduModel.userRole=GlobalConfig.userRole||ApeConsts.normal;
packPduModel.userRole=_param.userRole||GlobalConfig.userRole;
packPduModel.screenWidth=_param.screenWidth||GlobalConfig.screenWidth;
packPduModel.screenHeight=_param.screenHeight||GlobalConfig.screenHeight;
loger.log(packPduModel);
loger.log('packPdu->',packPduModel);
return packPduModel;
}
... ...
... ... @@ -65,8 +65,8 @@ class WhiteBoardApe extends Ape {
this.insertHistory = [];//添加的白板记录,用于撤回操作
}
//更新文档模块的录制信息,每次开启录制的时候需要把当前文档的信息更新一次
updaterRecordStatus(_param){
if(GlobalConfig.isHost&&!GlobalConfig.isRecordPlayBack){
updaterRecordApeStatus(_param){
/* if(GlobalConfig.isHost&&!GlobalConfig.isRecordPlayBack){
let curPageAnnos={};
for (let key in this.annoInfos) {
let item = this.annoInfos[key];
... ... @@ -80,6 +80,19 @@ class WhiteBoardApe extends Ape {
}else {
loger.log("开启录制成功->当前没有标注数据需要更新->docId:", GlobalConfig.activeDocId, 'page:',GlobalConfig.activeDocCurPage);
}
}*/
let curPageAnnos={};
for (let key in this.annoInfos) {
let item = this.annoInfos[key];
if (item && item.parentId == GlobalConfig.activeDocId && item.curPageNo == GlobalConfig.activeDocCurPage) {
curPageAnnos[key]=item;
}
}
if(Object.keys(curPageAnnos).length>0){
loger.warn("录制状态发送改变->更新当前的标注数据->docId:", GlobalConfig.activeDocId, 'page:',GlobalConfig.activeDocCurPage);
this.sendUpdaterAnnotaion({"itemIdxArr":curPageAnnos});
}else {
loger.warn("录制状态发送改变->当前没有标注数据需要更新->docId:", GlobalConfig.activeDocId, 'page:',GlobalConfig.activeDocCurPage);
}
}
... ...