李勇
3c53d4c0 1 parent 9d310aa2 master ... 20170922-1 20171019-1 20171120-1w dev ly20170622 ly20170622-2 ly20170622-3 ly20170627-2 ly20170706-1 ly20170708-2 ly20170708-3 ly20170710-1 ly20170717-1 ly20170719-1 ly20170723-1 ly20170724-2 ly20170726-1 ly20170731-1 ly20170731-2 ly20170801-2 ly20170802-1 ly20170818-1 ly20170818-2 ly20170820-1 ly20170821-1 ly20170824-1 ly20170829-1 ly20170925-1 ly20170926-1 ly20170927-1 ly20170929-1 ly20171011-1 ly20171013-1 ly20171013-2 ly20171016-1 ly20171021-1 ly20171023-1 ly20171024-1w ly20171025-1w ly20171026-1w ly20171027-1w ly20171030-1 ly20171030-2w ly20171107-1 ly20171110-1w ly20171113-1w ly20171204-1w ly20171208-1w ly20171211-1w ly20171211-2w ly20171214-1w webRtc-dev v2.38.13.20171216 v2.38.11.20171214 v2.38.3.201712011 v2.38.1.201712011 v2.36.11.20171204 v2.36.8.20171206 v2.36.4.20171201 v2.35.11.20171130 v2.34.16.20171128 v2.34.5.20171127 v2.33.6.20171123 v2.32.1.20171123 v2.31.12.20171122 v2.31.10.20171122 v2.30.5.20171117 v2.30.2.20171117 v2.29.5.20171114 v2.28.1.20171110 v2.27.11.20171109 v2.26.9.20171107 v2.26.6.20171103 v2.26.2.20171102 v2.25.7.20171031 v2.25.6.20171031 v2.25.0.20171030 v2.24.2.20171030 v2.23.0.20171030 v2.22.7.20171026 v2.20.5.20171023 v2.20.0.20171021 v2.19.8.20171020 v2.18.14.20171020 v2.18.10.20171019 v2.17.11.20171014 v2.16.8.20171012 v2.16.5.20171012 v2.15.5.20171001 v2.15.3.20170929 v2.14.5.20170927 v2.13.5.20170927 v2.12.14.20170927 v2.12.8.20170926 v2.12.6.20170925 v2.11.13.20170925 v2.10.7.20170921 v2.10.6.20170921 v2.10.5.20170920 v2.10.4.20170920 v2.9.3.20170919 v2.8.17.20170918 v2.8.8.20170917 v2.8.2.20170916 v2.6.2.20170915 v2.5.12.20170915 v2.5.6.20170914 v2.5.5.20170914 v2.4.4.20170908 v2.4.2.20170908 v2.4.0.20170907 v2.3.6.20170907 v2.2.16.20170905 v2.1.22.20170904 v1.84.0.20170912 v1.83.2.20170831 v1.82.11.20170829 v1.81.19.20170828 v1.80.2.20170824 v1.79.6.20170822 v1.79.5.20170821 v1.79.4.20170821 v1.79.3.20170821 v1.78.4.20170820 v1.77.4.20170819 v1.76.2.20170818 v1.75.0.20170815 v1.74.0.20170814 v1.73.2.20170814 v1.73.1.20170814 v1.71.0.20170813 v1.70.5.20170812 v1.68.2.20170812 v1.66.1.20170809 v1.65.25.20170808 v1.65.24.20170806 v1.63.1.20170731 v1.62.3.20170731 v1.61.0.20170729 v1.60.0.20170729 v1.59.0.20170729 v1.58.0.20170729 v1.57.0.20170727 v1.56.1.20170727 v1.56.0.20170727 v1.52.1.20170726 v1.51.0.20170724 v1.50.7.20170724 v1.49.1.20170724 v1.48.2.20170723 v1.46.1.20170722 v1.45.1.20170717 v1.43.1.20170711 v1.42.1.20170708 v1.41.0.20170708 v1.40.0.20170706 v1.39.2.20170706 v1.39.1.20170705 v1.38.4.20170629 v1.37.5.20170627 v1.37.2.20170622 v1.36.7.20170620 v1.36.4.20170620 v1.36.1.20170619 v1.35.4.20170619 v1.34.2.20170615 v1.33.2.20170615 v1.32.1.20170614 v1.31.11.20170613 v1.30.20.20170607 v1.30.7.20170606 v1.30.6.20170606 v1.30.5.20170605 v1.30.3.20170602

新增媒体共享模块

此 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就是所有人都接收
... ...