李勇

新增媒体共享模块

此 diff 太大无法显示。
... ... @@ -25,11 +25,12 @@ import Base64 from 'base64-js';
import ArrayBufferUtil from 'libs/ArrayBufferUtil';
import Server from "config/Server";
import MediaModule from 'apes/MediaModule';
import MediaSharedApe from 'apes/MediaSharedApe';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('McuClient');
let _sdkInfo = {"version": "v1.29.8.20170601", "author": "www.3mang.com"};
let _sdkInfo = {"version": "v1.30.3.20170602", "author": "www.3mang.com"};
//APE
let _sass;
... ... @@ -42,6 +43,7 @@ let _audio_ape;
let _doc_ape;
let _whiteboard_ape;
let _recordPlayback;
let _mediaShareApe;
//MCUClient 外部实例化主类
export default class MessageEntrance extends Emiter {
... ... @@ -72,6 +74,7 @@ export default class MessageEntrance extends Emiter {
_sass.on(_sass.CLASS_SAVE_STATUS_INFO_SUCCESS, this._sassSaveClassStatusInfoSuccessHandler.bind(this));//保存课堂状态信息
_sass.on(_sass.CLASS_SAVE_RECORD_INFO_SUCCESS, this._sassSaveClassRecordInfoSuccessHandler.bind(this));//保存课堂录制信息
_sass.on(_sass.DELETE_DOCUMENT_SUCCESS, this._sassDeleteDocumentSuccess.bind(this));//sass删除文档成功
_sass.on(_sass.DELETE_MEDIASHARE_SUCCESS, this._sassDeleteMediaShareSuccess.bind(this));//sass删除媒体文件成功
//选点模块
_ipManager = new IpManager();
... ... @@ -115,9 +118,12 @@ export default class MessageEntrance extends Emiter {
_audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this));//这个监听事件不能删除,需要通知课堂模块,检查channel占用
_audio_ape.on(MessageTypes.USER_DEVICE_STATUS_CHAANGE, this.userDeviecStatusChange.bind(this));//监听摄像头和麦克风的开启状态
_mediaShareApe=new MediaSharedApe();
_mediaShareApe.on('*', (type, data) => this._emit(type, data));
_mediaShareApe.on(MediaSharedApe.MEDIASHARED_JOIN_CHANNEL_SUCCESS, this.mediaShareApeJoinChannelSuccess.bind(this));
_whiteboard_ape = new WhiteBoardApe();
_whiteboard_ape.on('*', (type, data) => this._emit(type, data));
//_whiteboard_ape.on(MessageTypes.WHITEBOARD_ANNOTATION_UPDATE, this.annoUpdateHandler.bind(this));
_doc_ape = new DocApe();
_doc_ape.on('*', (type, data) => this._emit(type, data));
... ... @@ -193,6 +199,16 @@ export default class MessageEntrance extends Emiter {
this.getDocFullAddress = this._getDocFullAddress.bind(this);//获取文档资源地址
//媒体共享模块
this.mediaSharedUpload = this._sendMediaSharedUpload.bind(this);//上传
this.mediaSharedDelete = this._sassDeletMediaShare.bind(this);//删除,先通过Sass删除,删除成功之后才删除MCU的
this.mediaSharedPlay = this._sendMediaSharedPlay.bind(this); //播放
this.mediaSharedStop = this._sendMediaSharedStop.bind(this);//停止
this.mediaSharedPause=this._sendMediaSharedPause.bind(this);//暂停
this.mediaSharedSeek=this._sendMediaSharedSeek.bind(this);//seek
this.setDeviceInfo = this._setDeviceInfo.bind(this);//设置设备信息(麦克风,摄像头等等.....)
this.setMessageDelay = this._setMessageDelay.bind(this);//设置是否延迟消息
this.switchServer = this._switchMcuIpHandler.bind(this);//切换mcu服务器
... ... @@ -501,6 +517,8 @@ export default class MessageEntrance extends Emiter {
GlobalConfig.setMusicList(_data.musicList);//
GlobalConfig.setMusicListPrepare(_data.musicListPrepare);//提前上传的声音文件列表
GlobalConfig.setVideoCDNAddr(_data.videoCDNAddr);//cdn加速的拉流地址,直播的时候才使用
GlobalConfig.setMediaShareList(_data.sharedMediaList); //提前上传的媒体共享文件列表
//MCU地址
if (_data.mcuList && _data.mcuList.length > 0) {
... ... @@ -970,7 +988,7 @@ export default class MessageEntrance extends Emiter {
}
//Sass删除文档数据
//先通过Sass删除文档数据,删除成功之后才能删除MCU的
_sassDeleteDocument(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
... ... @@ -1011,6 +1029,10 @@ export default class MessageEntrance extends Emiter {
loger.log('删除文档成功->', _param);
this._sendDocumentDelete(_param);
}
_sassDeleteMediaShareSuccess(_param){
loger.log('删除媒体文件成功->', _param);
this._sendMediaSharedDelete(_param);
}
//ConferApe
//开始上课
... ... @@ -1465,6 +1487,120 @@ export default class MessageEntrance extends Emiter {
}
}
//媒体共享模块的接口
//上传
_sendMediaSharedUpload(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedUpload(_param);
}
}
//Sass删除媒体文件数据
_sassDeletMediaShare(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('删除媒体文件失败->参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM);
return;
}
//判断必要的参数字段值
if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.fileId == null || _param.fileId == "") {
loger.error('删除媒体文件失败->', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM);
return;
}
loger.log('删除媒体文件->', _param);
if (_sass) {
_sass.sassDeletMediaShare(_param);
}
}
//删除
_sendMediaSharedDelete(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedDelete(_param);
}
}
//播放
_sendMediaSharedPlay(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedDelete(_param);
}
}
//停止
_sendMediaSharedStop(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedStop(_param);
}
}
//暂停
_sendMediaSharedPause(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedPause(_param);
}
}
//seek
_sendMediaSharedSeek(_param){
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_mediaShareApe) {
_mediaShareApe.mediaSharedSeek(_param);
}
}
//媒体共享模块加入频道成功,同步到MCU服务器上的数据
mediaShareApeJoinChannelSuccess() {
loger.log("媒体共享模块加入频道成功->isHost=", GlobalConfig.isHost, "length=", GlobalConfig.sharedMediaList.length);
console.log("媒体共享模数据->", GlobalConfig.sharedMediaList);
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
/* if (GlobalConfig.isHost && GlobalConfig.sharedMediaList.length > 0) {
for (let i = 0; i < GlobalConfig.sharedMediaList.length; i++) {
let value = GlobalConfig.sharedMediaList[i];
if (value) {
//loger.log("判断是否需要把提前上传的文档上传到mcu", value);
let paramInfo = {
"pageNum": value.pdfSize,
"fileName": value.name,
"fileType": value.type,
"relativeUrl": value.relativeLocation,
"url": value.absoluteLocation,
"creatUserId": value.createUserID,
"docId": value.id,
"md5": value.MD5,
"visible": false
};
this._sendDocumentUpload(paramInfo);
}
}
}*/
}
//录制回放相关的处理------------------------------------------------
//录制回放初始化
_initRecordPlayback(_param) {
... ...
... ... @@ -185,6 +185,15 @@ class GlobalConfig {
static getDocListPrepare(){
return this.docListPrepare;
}
//储存已经提前上传的媒体共享文件列表
static setMediaShareList(_data){
if(_data==null) return;
this.sharedMediaList=_data;
}
static getMediaShareList(){
return this.sharedMediaList;
}
//储存录制列表
static setRecordList(_data){
if(_data==null) return;
... ... @@ -404,11 +413,15 @@ GlobalConfig.msDynamicChooseIpDelay=15;//(秒)MS动态选点的间隔
GlobalConfig.activeDocId=0;//当前激活的文档ID
GlobalConfig.activeDocCurPage=1;//当前激活的文档的当前页
GlobalConfig.activeMediaId=0;//当前显示的媒体文件的id
GlobalConfig.activeMediaSeek=1;//当前的媒体文件的播放进度seek点
GlobalConfig.classAllParam={};//Sass直接返回的所有课堂信息(最全)
GlobalConfig.classDetail={};//Sass直接返回的当前课堂基本信息
//从Sass获取的
GlobalConfig.sharedMediaList=[]; // 已经提前上传的媒体文件列表,进入课堂后需要自动加载
GlobalConfig.docListPrepare=[]; // 已经提前上传的文档,进入课堂后需要自动加载
GlobalConfig.recordList=[];//录制服务器地址集合
GlobalConfig.docList=[];//文档服务器地址集合
... ...
... ... @@ -84,19 +84,13 @@ MessageTypes.DOC_DELETE="document_delete";//'document.delete';//鍒犻櫎鏂囨。
MessageTypes.DOC_UPDATE ="document_update";// 'document.update';//更新文档(添加、变更)
MessageTypes.DOC_BROADCAST= "doc_broadcast";//
//MessageTypes.DOC_SHOW = 'document.show';
//MessageTypes.DOC_UPLOAD='document.upload';//上传文档
//MessageTypes.DOC_COMMAND='document.command';//操作文档
//MessageTypes.DOC_SWITCH = 'document.switch';//切换文档
//MessageTypes.DOC_DELETE='document.delete';//删除文档
//MessageTypes.DOC_ANNOTATION = 'document.annotation';//笔记
//媒体共享
MessageTypes.MEDIA_SHARED_DELETE="media_shared_delete";//删除媒体文件
MessageTypes.MEDIA_SHARED_UPDATE ="media_shared_update";//更新媒体文件(添加、变更)
//白板笔记事件定义
MessageTypes.WHITEBOARD_ANNOTATION_UPDATE ="whiteboard_annotation_update";// 'whiteboard.annotation.update';
//MessageTypes.WHITEBOARD_ANNOTAION_INSERT = 'whiteboard.annotation.insert';
//MessageTypes.WHITEBOARD_ANNOTAION_DELETE = 'whiteboard.annotation.delete';
//MessageTypes.WHITEBOARD_ANNOTATION_CLEAR = 'whiteboard.annotation.clear';
//MCU MS
MessageTypes.SWITCH_MCU_IP ="switch_mcu_ip";//切换mcu 重新选点
... ... @@ -146,7 +140,9 @@ MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG=501;//APE鍦ㄦ帴鍙h皟鐢ㄦ椂鍙傛暟閿欒
//DOC
MessageTypes.ERR_DOC_DELETE_FAILED=600;//删除文档失败
MessageTypes.ERR_DOC_DELETE_FAILED_PARAM=601;//删除文档失败,参数错误
//媒体共享
MessageTypes.ERR_MEDIASHARE_DELETE_FAILED=620;//删除媒体共享文件失败
MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM=621;//删除媒体共享文件,参数错误
MessageTypes.ERR_SDK_FAILED=700;// sdk还没初始化
MessageTypes.ERR_INTERFACE_NONE=701;//调用的接口不存在
... ... @@ -199,6 +195,12 @@ MessageTypes.ErrorReson[MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG]="APE鍦ㄦ帴鍙
MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED]="删除文档失败";
MessageTypes.ErrorReson[MessageTypes.ERR_DOC_DELETE_FAILED_PARAM]="删除文档失败,参数错误";
//mediaShare
MessageTypes.ErrorReson[MessageTypes.ERR_MEDIASHARE_DELETE_FAILED]="删除媒体共享文件失败";
MessageTypes.ErrorReson[MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM]="删除媒体共享文件,参数错误";
MessageTypes.ErrorReson[MessageTypes.ERR_SDK_FAILED]="sdk还没初始化";
MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_NONE]="调用的接口不存在";
MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_PARAMS_ERROR]="调用的接口,传递的参数不正确";
... ...
... ... @@ -310,7 +310,7 @@ class Sass extends Emiter {
if (ret.ok) {
return ret.json();
} else {
loger.error(`sassDeleteDocument-网络异常.状态码:${ret.status}`);
loger.error(`删除文档-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
throw '';
... ... @@ -318,19 +318,60 @@ class Sass extends Emiter {
})
.then(ret => {
if (ret.code === 0) {
loger.log('sassDeleteDocument 完成');
loger.log('删除文档-完成');
this._emit(Sass.DELETE_DOCUMENT_SUCCESS, _param);
} else {
loger.warn('sassDeleteDocumnt 失败.');
loger.warn('删除文档-失败.')
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
}
})
.catch(err => {
loger.error(`sassDeleteDocument异常.状态码:${err}`);
loger.error(`删除文档-异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED);
});
}
//删除媒体共享文件
sassDeletMediaShare(_param) {
if(GlobalConfig.isRecordPlayBack){
loger.log('录制回放中,能删除文件');
return;
}
var timestamp = new Date().getTime();
var authId = MD5(_param.fileId + "" + _param.classId + "" + timestamp);// docId+classId+timestamp的字符串,转成MD5
let url = `http://${GlobalConfig.portal}/3m/api/sharedMedia/deleteRelation.do?fileId=${_param.fileId}&classId=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
loger.log('删除媒体共享文件', url);
fetch(url, {
timeout: 5000
})
.then(ret => {
if (ret.ok) {
return ret.json();
} else {
loger.error(`删除媒体共享文件-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED);
throw '';
}
})
.then(ret => {
//code 0 成功, 1 验证信息错误
if (ret.code === 0) {
loger.log('删除媒体共享文件 完成');
this._emit(Sass.DELETE_MEDIASHARE_SUCCESS, _param);
} else {
loger.warn('删除媒体共享文件 失败.');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED);
}
})
.catch(err => {
loger.error(`删除媒体共享文件-异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED);
});
}
//保存课堂的当前信息-------------------------------------------------------------------------------------------------
/*保存课堂的当前信息,首次是插入,后面是更新
/api/meeting/saveInfo.do
... ... @@ -504,6 +545,7 @@ Sass.prototype.CLASS_INIT_SUCCESS = Sass.CLASS_INIT_SUCCESS = 'sass_class_init_s
Sass.prototype.CLASS_GET_CLASS_PARAM = Sass.CLASS_GET_CLASS_PARAM = 'sass_class_getClassParam.message';
Sass.prototype.CLASS_GET_CLASS_DETAIL = Sass.CLASS_GET_CLASS_DETAIL = 'sass_class_getClassDetail_message';
Sass.prototype.DELETE_DOCUMENT_SUCCESS = Sass.DELETE_DOCUMENT_SUCCESS = 'sass_class_deleteDocumentSuccess_message';//删除文档成功
Sass.prototype.DELETE_MEDIASHARE_SUCCESS = Sass.DELETE_MEDIASHARE_SUCCESS = 'sass_class_deleteMediaShareSuccess_message';//删除文档成功
Sass.prototype.CLASS_SAVE_STATUS_INFO_SUCCESS = Sass.CLASS_SAVE_STATUS_INFO_SUCCESS = 'sass_class_saveClassStatusInfoSuccess_message';//保存课堂状态信息
Sass.prototype.CLASS_SAVE_RECORD_INFO_SUCCESS = Sass.CLASS_SAVE_RECORD_INFO_SUCCESS = 'sass_class_saveClassRecordInfoSuccess_message';//保存录制课堂信息
... ...
... ... @@ -22,7 +22,7 @@ import GlobalConfig from 'GlobalConfig';
import EngineUtils from 'EngineUtils';
let loger = Loger.getLoger('DocApe');
let itemIdx = 0;//table插入新数据的计数id,目前用时间戳
//let itemIdx = 0;//table插入新数据的计数id,目前用时间戳
class DocApe extends Ape {
constructor() {
... ... @@ -53,7 +53,7 @@ class DocApe extends Ape {
return;
}
itemIdx = EngineUtils.creatSoleNumberFromTimestamp();//
let itemIdx = EngineUtils.creatSoleNumberFromTimestamp();//
let docDataModelPdu = this.packPdu(paramInfo, itemIdx);
if (docDataModelPdu == null) {
loger.log('上传文档->失败->数据无效');
... ...
// //////////////////////////////////////////////////////////////////////////////
//
// 媒体共享模块
// //////////////////////////////////////////////////////////////////////////////
import Ape from './Ape';
import ApeConsts from './ApeConsts';
import pdu from 'pdus';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
import GlobalConfig from 'GlobalConfig';
import EngineUtils from 'EngineUtils';
let loger = Loger.getLoger('MediaSharedApe');
class MediaSharedApe extends Ape {
constructor() {
super(
ApeConsts.MEDIA_SESSION_ID,
ApeConsts.MEDIA_SESSION_NAME,
ApeConsts.MEDIA_SESSION_TAG
);
this.mediaSharedList = {};//记录媒体数据
// Ape Models
this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.MEDIA_OBJ_TABLE_ID, ApeConsts.MEDIA_OBJ_TABLE_NAME, ApeConsts.MEDIA_OBJ_TABLE_TAG, 0, new ArrayBuffer);
}
/////////////发送数据操作//////////////////////////////////////////////////////
//上传媒体文件
mediaSharedUpload(paramInfo) {
if (paramInfo == null || EngineUtils.isEmptyObject(paramInfo)) {
loger.warn('上传媒体文件->失败->参数错误->',paramInfo);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return;
}
//判断媒体文件是否已经存在,每个媒体文件都有唯一的fileId,如果已经同步的媒体文件中存在相同的fileId就不需要再同步
if (this.checkMediaSharedId(paramInfo.fileId)) {
//媒体文件已经存在相同的fileId,不需要同步上传
loger.warn('上传媒体文件->失败->媒体文件档的fileId无效或已经存在相同的fileId不需要上传');
return;
}
let itemIdx = EngineUtils.creatSoleNumberFromTimestamp();//
let pduDataModel = this.packPdu(paramInfo, itemIdx);
if (pduDataModel == null) {
loger.log('上传媒体文件->失败->数据无效');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return;
}
let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
tableItemPdu.itemIdx = itemIdx;//直接用时间戳作为id
tableItemPdu.registerObjId = ApeConsts.MEDIA_OBJ_TABLE_ID;
tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
tableItemPdu.itemData = pduDataModel.toArrayBuffer();
//insert
let tableInsertItemPdu = new pdu['RCRegistryTableInsertItemPdu'];
//optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
//repeated RCRegistryTableItemPdu items = 2;
tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_INSERT_PDU;//
tableInsertItemPdu.items.push(tableItemPdu);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.MEDIA_OBJ_TABLE_ID;
updateObjPdu.subType = tableInsertItemPdu.type;
updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
loger.log("上传媒体文件->发送->itemIdx=" + tableItemPdu.itemIdx);
this.sendUniform(adapterPdu, true);
}
//删除媒体文件
mediaSharedDelete(paramInfo) {
let tableDeleteItemPdu = new pdu['RCRegistryTableDeleteItemPdu'];
tableDeleteItemPdu.type = pdu.RCPDU_REG_TABLE_DELETE_PDU;//
tableDeleteItemPdu.itemIdx = parseInt(paramInfo.itemIdx);//这里需要设置要删除的数据的itemIdx,每条数据的这个id都不一样
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.MEDIA_OBJ_TABLE_ID;
updateObjPdu.subType = tableDeleteItemPdu.type;
updateObjPdu.userData = tableDeleteItemPdu.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
loger.log("媒体文件发送删除数据=============>" + tableDeleteItemPdu.itemIdx);
this.sendUniform(adapterPdu, true);
}
//更新
updaterMediaShared(_pduDataModel, _itemIdx) {
//验证坐标点集合数组是否合法
if (_pduDataModel == null || _itemIdx == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}
loger.log("媒体文件->updaterMediaShared ", _pduDataModel);
let pduDataModel = this.packPdu(_pduDataModel, _itemIdx);
let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
tableItemPdu.itemIdx = _itemIdx;//直接用时间戳作为id
tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
tableItemPdu.itemData = pduDataModel.toArrayBuffer();
//insert
let tableInsertItemPdu = new pdu['RCRegistryTableUpdateItemPdu'];
//optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
//repeated RCRegistryTableItemPdu items = 2;
tableInsertItemPdu.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
tableInsertItemPdu.items.push(tableItemPdu);
let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
updateObjPdu.objId = ApeConsts.MEDIA_OBJ_TABLE_ID;
updateObjPdu.subType = tableInsertItemPdu.type;
updateObjPdu.userData = tableInsertItemPdu.toArrayBuffer();
//同步
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
let adapterPdu = new pdu['RCAdapterPdu'];
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
loger.log("发送更新媒体文件.itemIdx=" + tableItemPdu.itemIdx);
this.sendUniform(adapterPdu, true);
}
//获取媒体文件的完整地址和所有图片
getMediaSharedAddress(_param){
if (_param == null || _param.url == null || _param.itemIdx ==null) {
loger.warn('获取媒体文件完整地址->传递的参数不正确->', _param);
return {"code":ApeConsts.RETURN_FAILED, "data": "获取媒体文件时传递的参数不对"};
}
let fullPath='';//媒体文件路径地址
let pageNum=1;//总页数
let docType="";//媒体文件地址的后缀类型
let fileType="";//媒体文件的原始类型
let docItem=this.mediaSharedList[_param.itemIdx];
if(docItem){
fullPath=docItem.url||"";
pageNum=docItem.pageNum||1;
fileType=docItem.fileType||""
}else {
fullPath =_param.url;
}
//获取当前媒体文件的后缀名
docType=this._getMediaType(fullPath);
let substrFullPath=this._getMediaPath(fullPath);//获取去掉后缀和文件名的地址,需要获取同目录下其他文件
let imagesArr=[];
let htmlPath="";
let pdfPath="";
//根据文件后缀名,生成对应的访问地址
if(docType=="jpg"||docType=="png"||docType=="swf"||docType=="pdf"||docType=="doc"||docType=="pptx"){
//页数从1开始
for (let i = 1; i <=pageNum; i++) {
imagesArr.push(substrFullPath + "/" + i + ".jpg");
}
}
if(docType=="swf"||docType=="pdf"||docType=="doc"||docType=="pptx"){
pdfPath=fullPath.replace(/\.swf/g, ".pdf")||"";
}
//动态PPT
if(docType=="html"){
htmlPath=fullPath;
}
//返回媒体文件第所有地址
return {'code':ApeConsts.RETURN_SUCCESS, 'data': '','docFullAddress':{
'images':imagesArr,
'pdf':pdfPath,
'html':htmlPath
}};
}
_getMediaType(_fullPath){
if(!_fullPath){
return "";
}
if(_fullPath.lastIndexOf(".jpg")>=0){
return "jpg";
}
if(_fullPath.lastIndexOf(".png")>=0){
return "png";
}
if(_fullPath.lastIndexOf(".swf")>=0){
return "swf";
}
if(_fullPath.lastIndexOf(".pdf")>=0){
return "pdf";
}
if(_fullPath.lastIndexOf(".doc")>=0){
return "doc";
}
if(_fullPath.lastIndexOf(".html")>=0){
return "html";
}
if(_fullPath.lastIndexOf(".pptx")>=0){
return "pptx";
}
return "";
}
//获取去掉文件名和后缀名的地址 http://www.xxx.xxx/image/aa.jpg -->http://www.xxx.xxx/image/
_getMediaPath(_fullPath){
if(!_fullPath){
return "";
}
var lastIndex = _fullPath.lastIndexOf("/");
if (lastIndex > 0) {
return _fullPath.substr(0, lastIndex);
}
return _fullPath;
}
//组织完整的媒体文件信息,包含上传时的信息和转换后的完整地址信息
_mediaSharedPackFullInfo(_itemDataInfo){
let itemDataInfo=_itemDataInfo;
let getDocAddress=this.getMediaSharedAddress(_itemDataInfo);
if(getDocAddress.code==ApeConsts.RETURN_SUCCESS){
itemDataInfo.images=getDocAddress.docFullAddress.images||[];
itemDataInfo.pdf=getDocAddress.docFullAddress.pdf||"";
itemDataInfo.html=getDocAddress.docFullAddress.html||"";
}else {
itemDataInfo.images=[];
itemDataInfo.pdf='';
itemDataInfo.html='';
}
loger.log('docPackFullInfo->', itemDataInfo);
return itemDataInfo;
}
//更新媒体文件模块的录制信息,每次开启录制的时候需要把当前媒体文件的信息更新一次
updaterRecordStatus(_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
});
}
}
//清除当前媒体文件模块的数据
clearData(){
loger.log("clearData->")
this.mediaSharedList={};
GlobalConfig.activeMediaId=0;
GlobalConfig.activeMediaSeek=1;
}
//播放媒体文件
mediaSharedPlay(paramInfo) {
loger.log('切换媒体文件->', paramInfo);
if (GlobalConfig.isRecordPlayBack) {
loger.warn('录制回放状态不允许切换媒体文件');
return;
}
if (paramInfo == null || paramInfo.itemIdx == null) {
loger.warn('切换媒体文件失败,参数错误', paramInfo);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return;
}
if (paramInfo.itemIdx == GlobalConfig.activeMediaId && GlobalConfig.activeMediaId != 0) {
loger.warn('媒体文件已经显示', paramInfo.itemIdx, GlobalConfig.activeMediaId);
return;
}
//更新切换之前的媒体文件的数据,要显示当前切换的媒体文件,上一个媒体文件需要隐藏
let oldPduDataModel;
if (GlobalConfig.activeMediaId != 0) {
oldPduDataModel = this.mediaSharedList[GlobalConfig.activeMediaId];
if (oldPduDataModel) {
oldPduDataModel.status = 1;//设置为不可见
}
}
//获取已经存在的数据
let pduDataModel = this.mediaSharedList[paramInfo.itemIdx];
if (pduDataModel == null) {
loger.warn('切换媒体文件失败,媒体文件不存在', paramInfo);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return;
}
//更新当前选择的媒体文件数据的字段
pduDataModel.status = paramInfo.status || 0;//默认是0
//loger.log('切换媒体文件,当前媒体文件和上一个显示的媒体文件都需要更新状态');
loger.log({"oldDoc": oldPduDataModel, "nowDoc": pduDataModel});
//更新当前选择的媒体文件
this.updaterMediaShared(pduDataModel, pduDataModel.itemIdx);
//更新上一个媒体文件 隐藏
if (oldPduDataModel) {
this.updaterMediaShared(oldPduDataModel, oldPduDataModel.itemIdx);
}
}
//停止媒体文件
mediaSharedStop(paramInfo) {
}
//暂停媒体文件
mediaSharedPause(paramInfo) {
}
//媒体文件SEEK
mediaSharedSeek(paramInfo) {
loger.log('媒体文件SEEK->',paramInfo);
//获取已经存在的数据
let pduDataModel = this.mediaSharedList[paramInfo.itemIdx];
//console.log(pduDataModel);
//console.log(pduDataModel);
if (pduDataModel == null) {
loger.log('媒体文件SEEK->媒体文件不存在', paramInfo);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return;
}
//更新数据的字段
pduDataModel.seek = parseInt(paramInfo.seek) || 1;
if (pduDataModel.seek < 1) {
pduDataModel.seek = 1;//默认值最小是1
}
this.updaterMediaShared(pduDataModel, pduDataModel.itemIdx);
}
/////收到消息处理/////////////////////////////////////////////////////////////////////////////////
tableInsertHandler(owner, itemIdx, itemData) {
}
//添加媒体文件
tableInsertApeHandler(_tableUpdateItems, _seekTime) {
let tableInsertItems =_tableUpdateItems;
let tableInsertItemsLen = tableInsertItems.length;
loger.log('添加媒体文件->', "activeDocId->", 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){
this.mediaSharedList[insertItem.itemIdx] = itemDataInfo;
if (itemDataInfo.status == 1) {
GlobalConfig.activeMediaId = itemDataInfo.itemIdx;//当前激活的媒体文件ID
GlobalConfig.activeMediaSeek = itemDataInfo.seek;//当前激活的媒体文件的当前页
loger.log('添加媒体文件->设置当前激活的媒体文件id');
}
let getMediaPackFullInfo= this._mediaSharedPackFullInfo(itemDataInfo);
this._emit(MessageTypes.MEDIA_SHARED_UPDATE, getMediaPackFullInfo);
}
}
//媒体文件数据更新完毕,如果当前没有显示的媒体文件,默认选择一个显示
this._showDefaultMeida();
}
tableDeleteHandler(object_id, tableDeleteData) {
loger.log('删除媒体文件数据->', object_id, tableDeleteData);//["tableDeleteHandler",1179649,{"type":231,"itemIdx":[1486301768]}]
if (tableDeleteData && tableDeleteData.itemIdx) {
let len = tableDeleteData.itemIdx.length;
let itemIdxs = tableDeleteData.itemIdx;
for (let i = 0; i < len; i++) {
if (this.mediaSharedList[itemIdxs[i]]) {
loger.log("删除媒体文件数据:", itemIdxs[i]);
let itemDataInfo = this.mediaSharedList[itemIdxs[i]];
if (itemDataInfo && itemDataInfo.status ==1) {
GlobalConfig.activeMediaId = 0;//当前激活的媒体文件ID
GlobalConfig.activeMediaSeek = 1;//当前激活的媒体文件的当前页
loger.log('删除媒体文件数据->清除当前显示的媒体文件');
}
this._emit(MessageTypes.MEDIA_SHARED_DELETE, {"itemIdx": itemIdxs[i]});
delete this.mediaSharedList[itemIdxs[i]];
}
}
}
}
tableUpdateHandler(owner, itemIdx, itemData) {
}
tableUpdateApeHandler(_tableUpdateItems, _seekTime) {
let tableUpdateItemsLen = _tableUpdateItems.length;
loger.log('更新媒体文件->', "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) {
this.mediaSharedList[tableItem.itemIdx] = itemDataInfo;
if (itemDataInfo && itemDataInfo.status ==1) {
GlobalConfig.activeMediaId = itemDataInfo.itemIdx;//当前激活的媒体文件ID
GlobalConfig.activeMediaSeek = itemDataInfo.seek;//当前激活的媒体文件的当前页
loger.log('更新媒体文件->设置当前激活的媒体文件id->', GlobalConfig.activeMediaId, "curPageNum->", GlobalConfig.activeMediaSeek);
}
let getMediaPackFullInfo= this._mediaSharedPackFullInfo(itemDataInfo);
this._emit(MessageTypes.MEDIA_SHARED_UPDATE, getMediaPackFullInfo);
} else {
loger.log('更新媒体文件-> 数据无效--> itemIdx', itemIdx);
}
}
this._showDefaultMeida();
}
//果当前没有显示的媒体文件,默认选择一个显示媒体文件
_showDefaultMeida() {
//显示默认媒体文件条件->1.非录制回放状态下 2.只有host有权限操作 3.当前激活的媒体文件id不为0
if (GlobalConfig.isRecordPlayBack || !GlobalConfig.isHost || GlobalConfig.activeMediaId > 0) {
return;
}
let tempDocItemIdx;//临时记录媒体文件数据,用于显示默认媒体文件
for (let key in this.mediaSharedList) {
tempDocItemIdx= this.mediaSharedList[key];
if (tempDocItemIdx) {
loger.log("选择一个媒体文件作为默认媒体文件显示->", tempDocItemIdx);
let paramInfo = {
"itemIdx": tempDocItemIdx.itemIdx,
"status": 1
};
this.mediaSharedPlay(paramInfo);
//选择完成就跳出循环
return;
}
}
}
onJoinChannelHandlerSuccess() {
loger.log(this._session_name + ' 媒体共享加入频道成功');
if (this._apeDelayed) {
setTimeout(() => {
this._emit(MediaSharedApe.MEDIASHARED_JOIN_CHANNEL_SUCCESS);
}, (GlobalConfig.mcuDelay + GlobalConfig.docDelay) || 12000 + GlobalConfig.docDelay);
} else {
setTimeout(() => {
this._emit(MediaSharedApe.MEDIASHARED_JOIN_CHANNEL_SUCCESS);
}, GlobalConfig.docDelay);
}
}
//检查媒体文件是否已经存在,如果存在 返回true,否则返回false
checkMediaSharedId(_fileId) {
if (_fileId == null) {
loger.warn('查找媒体文件->失败->参数为null');
return true;
}
//遍历查找
for (let key in this.mediaSharedList) {
let item = this.mediaSharedList[key];
if (item && item.fileId == _fileId) {
loger.log('查找媒体文件->已经存在->',_fileId);
return true;
}
}
loger.log('查找媒体文件->没有查找到媒体文件->',_fileId);
//储存的数据中没有查找到
return false;
}
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param, _itemIdx) {
loger.log("媒体文件->packPdu");
//验证坐标点集合数组是否合法
if (_param == null || _itemIdx == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}
//判断type类型,根据type设置不同的参数
let pduDataModel = new pdu['RCMediaSharedSendDataModelPdu'];
pduDataModel.itemIdx = _itemIdx;
pduDataModel.owner = GlobalConfig.nodeId;
pduDataModel.from = GlobalConfig.nodeId;
pduDataModel.fileType = _param.fileType || "";
pduDataModel.creatUserId = _param.creatUserId || "0";
pduDataModel.url = _param.url||"";//这个地址没用到,数据太长占用资源 暂停使用//"http://101.200.150.192/DocSharing/data/h5test/20170206-171100025/7e9c4178cac1133e0dd9d5b583439122.jpg";
pduDataModel.status = _param.status || 0;
pduDataModel.fileId = _param.fileId || "";//媒体文件在服务器数据库中的唯一id,必须有
pduDataModel.fileName = _param.fileName || "media_" + _itemIdx;//媒体文件的名字
return pduDataModel;
}
unPackPdu(owner, itemIdx, itemData) {
if (owner == null || itemIdx == null || itemData == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
}
try {
let pduDataModel = pdu['RCMediaSharedSendDataModelPdu'].decode(itemData);
loger.log("媒体文件===>unPackPdu");
return pduDataModel;
} catch (err) {
loger.log("媒体文件===>unPackPdu->Pdu解析错误->itemIdx=" + itemIdx + "->err:" + err.message);
}
return null;
}
}
MediaSharedApe.prototype.MEDIASHARED_JOIN_CHANNEL_SUCCESS = MediaSharedApe.MEDIASHARED_JOIN_CHANNEL_SUCCESS = 'mediaShared_join_channel_success';
export default MediaSharedApe;
... ...
... ... @@ -25,7 +25,7 @@ import EngineUtils from 'EngineUtils';
let loger = Loger.getLoger('WhiteBoardApe');
let itemIdx = 0;//table插入新数据的计数id,目前用时间戳
//let itemIdx = 0;//table插入新数据的计数id,目前用时间戳
const TYPE_BIGHT = 0;//任意线段
const TYPE_LINE = 1;//直线
const TYPE_RECT = 2;//矩形
... ... @@ -92,7 +92,7 @@ class WhiteBoardApe extends Ape {
return;
}
itemIdx = EngineUtils.creatSoleNumberFromTimestamp();//创建时间戳,保证每条数据的唯一
let itemIdx = EngineUtils.creatSoleNumberFromTimestamp();//创建时间戳,保证每条数据的唯一
let whiteBoardModelPdu = this.packPdu(_param, itemIdx);
if (whiteBoardModelPdu == null) {
loger.warn('添加标注失败-->参数错误->',_param);
... ...
... ... @@ -744,6 +744,18 @@ message RCDocSendDataModelPdu {
}
message RCMediaSharedSendDataModelPdu {
optional uint32 item_idx=1;//唯一标识
optional uint32 owner=2;
optional uint32 from=3;
optional string file_type=4;
optional string creat_user_id=5;//创建文件userid
optional string url =6;//文件地址
optional uint32 status=7;//状态0停止 1播放 2暂停
optional string fileId=8;//文件在服务器数据库中的唯一id
optional string file_name=9;//文件的名字
}
message RCDocBroadcastDataRequestPdu {
optional uint32 from_node_id = 1;//发起人
optional uint32 to_node_id = 2;//接收人,如果是0就是所有人都接收
... ...