李勇

1.增加录制回放接口

2.增加录制文件解析模块 RecordPlayBackParse.js
3.所有“会议” 改成 “课堂”
此 diff 太大无法显示。
... ... @@ -6,6 +6,7 @@ require('string.fromcodepoint');
import Emiter from './Emiter';
import Sass from 'Sass';
import ServerCheck from 'ServerCheck';
import RecordPlayBackParse from 'RecordPlayBackParse';
import Mcu from 'mcu';
import MessageTypes from 'MessageTypes';
import Loger from 'Loger';
... ... @@ -20,945 +21,1120 @@ import GlobalConfig from 'GlobalConfig';
import ApeConsts from 'apes/ApeConsts';
import Base64 from 'base64-js';
import ArrayBufferUtil from 'libs/ArrayBufferUtil';
import UTF8 from 'utf-8';
let loger = Loger.getLoger('MessageEntrance');
let _sdkInfo={"version":"v.1.0.2017.0307","author":"www.3mang.com"};
let _sdkInfo = {"version": "v.1.0.2017.0307", "author": "www.3mang.com"};
//APE
let _sass;
let _serverCheck;
let _mcu ;
let _mcu;
let _confer_ape;
let _chat_ape;
let _video_ape;
let _audio_ape;
let _doc_ape;
let _whiteboard_ape;
let _parseBuf;
//MCUClient 外部实例化主类
export default class MessageEntrance extends Emiter {
constructor() {
super();
//sdk 信息
this.sdkInfo = _sdkInfo;
loger.log(this.sdkInfo);
//初始化状态
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_0);
//全局的Error处理
this.on(MessageTypes.MCU_ERROR, this._mcuErrorHandler.bind(this));
// Sass平台层
_sass = Sass;
_sass.on('*', (type, data) => this._emit(type, data));
_sass.on(_sass.SUCCESS, this._sassJoinSuccessHandler.bind(this));//通过SASS平台验证(密码和MD5)
_sass.on(_sass.CLASS_INIT_SUCCESS, this._sassInitSuccessHandler.bind(this));//获取会议初始化信息
//_sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取会议的基本信息
_sass.on(_sass.CLASS_GET_CLASS_PARAM, this._sassGetClassParamSuccessHandler.bind(this));//获取会议的最全信息和历史保存的数据
_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删除文档成功
//ServerCheck ip
_serverCheck=ServerCheck;
_serverCheck.on(_serverCheck.SEVER_CHECK_BEST_IP_SUCCESS, this._serverCheckBestIpSuccessHandler.bind(this));//ip选点,获取最佳ip完成
// 底层MCU消息层
_mcu = Mcu;
_mcu.on('*', (type, data) => this._emit(type, data));
_mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuJoinMCUClassSuccessHandler.bind(this));//加入MCU会议完成
// 注册所有应用Ape
_confer_ape = new ConferApe();
_confer_ape.on('*', (type, data) => this._emit(type, data));
_confer_ape.on(MessageTypes.CLASS_EXIT, this._doClassExit.bind(this));//监听自己的关闭事件
_confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this));//当前会议状态信息发生改变
_confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this));//当前会议人员离开
_confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER,this._onClassNonentityRoster.bind(this));//当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在
_confer_ape.on(MessageTypes.CLASS_RECORD_START,this._onClassRecordStart.bind(this));//会议开始录制
_chat_ape = new ChatApe();
_chat_ape.on('*', (type, data) => this._emit(type, data));
_video_ape = new VideoApe();
_video_ape.on('*', (type, data) => this._emit(type, data));
_video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this));//这个监听事件不能删除,需要通知会议模块,检查channel占用
_audio_ape= new AudioApe();
_audio_ape.on('*', (type, data) => this._emit(type, data));
_audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this));//这个监听事件不能删除,需要通知会议模块,检查channel占用
_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));
_doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this));
_doc_ape.on(MessageTypes.DOC_DELETE, this.docDeleteHandler.bind(this));
_doc_ape.on(DocApe.DOC_JOIN_CHANNEL_SUCCESS, this.docJoinChannelSuccess.bind(this));
//公开外部调用的方法
//class
this.init = this._init.bind(this);
this.joinClass = this._joinClass.bind(this);
this.leaveClass = this._leaveClass.bind(this);
this.getMcuClientStatus = this._getMcuClientStatus.bind(this);
//this.getClassDetail = this._getClassDetail;//停用
this.getClassStatusInfo = this._getClassStatusInfo.bind(this);
this.sendStartClass = this._sendStartClass.bind(this);
this.sendPauseClass = this._sendPauseClass.bind(this);
this.sendCloseClass = this._sendCloseClass.bind(this);
//chatApe
this.sendChatMsg = this._sendChatMsg.bind(this);
//videoApe
//this.getVideoPlayPath = this._getVideoPlayPath.bind(this);
this.getVideoPublishPath = this._getVideoPublishPath.bind(this);
this.getVideoAllChannelInfo = this._getVideoAllChannelInfo.bind(this);
this.publishVideo = this._publishVideo.bind(this);
this.stopPublishVideo = this._stopPublishVideo.bind(this);
this.sendVideoBroadcastMsg=this._sendVideoBroadcastMsg.bind(this);
//audioApe
//this.getAudioPlayPath = this._getPlayAudioPath.bind(this);
this.getAudioPublishPath = this._getPublishAudioPath.bind(this);
this.getAudioAllChannelInfo = this._getAudioAllChannelInfo.bind(this);
this.publishAudio = this._publishAudio.bind(this);
this.stopPublishAudio = this._stopPublishAudio.bind(this);
this.sendAudioBroadcastMsg=this.sendAudioCommandMsg.bind(this);
//whiteBoradApe
this.sendInsertAnnotaion = this._sendInsertAnnotaion.bind(this);
//this.sendDeleteAnnotaion=this._sendDeleteAnnotaion;
this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation.bind(this);
this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this);
this.sendGotoPrev = this._sendGotoPrev.bind(this);
constructor() {
super();
//sdk 信息
this.sdkInfo = _sdkInfo;
loger.log(this.sdkInfo);
//初始化状态
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_0);
//全局的Error处理
this.on(MessageTypes.MCU_ERROR, this._mcuErrorHandler.bind(this));
// Sass平台层
_sass = Sass;
_sass.on('*', (type, data) => this._emit(type, data));
_sass.on(_sass.SUCCESS, this._sassJoinSuccessHandler.bind(this));//通过SASS平台验证(密码和MD5)
_sass.on(_sass.CLASS_INIT_SUCCESS, this._sassInitSuccessHandler.bind(this));//获取课堂初始化信息
//_sass.on(_sass.CLASS_GET_CLASS_DETAIL, this._sassGetClassDetailSuccessHandler.bind(this));//获取课堂的基本信息
_sass.on(_sass.CLASS_GET_CLASS_PARAM, this._sassGetClassParamSuccessHandler.bind(this));//获取课堂的最全信息和历史保存的数据
_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删除文档成功
//ServerCheck ip
_serverCheck = ServerCheck;
_serverCheck.on(_serverCheck.SEVER_CHECK_BEST_IP_SUCCESS, this._serverCheckBestIpSuccessHandler.bind(this));//ip选点,获取最佳ip完成
// 底层MCU消息层
_mcu = Mcu;
_mcu.on('*', (type, data) => this._emit(type, data));
_mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuJoinMCUClassSuccessHandler.bind(this));//加入MCU课堂完成
//录制回放
_parseBuf = RecordPlayBackParse;
_parseBuf.on('*', (type, data) => this._emit(type, data));
_parseBuf.on(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, this._joinRecordPlaybackSuccessHandler.bind(this));//加入录制回放完成
// 注册所有应用Ape
_confer_ape = new ConferApe();
_confer_ape.on('*', (type, data) => this._emit(type, data));
_confer_ape.on(MessageTypes.CLASS_EXIT, this._doClassExit.bind(this));//监听自己的关闭事件
_confer_ape.on(MessageTypes.CLASS_STATUS_INFO_CHANGE, this._onClassStatusInfoChange.bind(this));//当前课堂状态信息发生改变
_confer_ape.on(MessageTypes.CLASS_DELETE_ROSTER, this._onClassDeleteRoster.bind(this));//当前课堂人员离开
_confer_ape.on(MessageTypes.CLASS_NONENTITY_ROSTER, this._onClassNonentityRoster.bind(this));//当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在
_confer_ape.on(MessageTypes.CLASS_RECORD_START, this._onClassRecordStart.bind(this));//课堂开始录制
_chat_ape = new ChatApe();
_chat_ape.on('*', (type, data) => this._emit(type, data));
_video_ape = new VideoApe();
_video_ape.on('*', (type, data) => this._emit(type, data));
_video_ape.on(MessageTypes.VIDEO_UPDATE, this.videoUpdate.bind(this));//这个监听事件不能删除,需要通知课堂模块,检查channel占用
_audio_ape = new AudioApe();
_audio_ape.on('*', (type, data) => this._emit(type, data));
_audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this));//这个监听事件不能删除,需要通知课堂模块,检查channel占用
_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));
_doc_ape.on(MessageTypes.DOC_UPDATE, this.docUpdateHandler.bind(this));
_doc_ape.on(MessageTypes.DOC_DELETE, this.docDeleteHandler.bind(this));
_doc_ape.on(DocApe.DOC_JOIN_CHANNEL_SUCCESS, this.docJoinChannelSuccess.bind(this));
//公开外部调用的方法
//class
this.init = this._init.bind(this);
this.joinClass = this._joinClass.bind(this);
this.leaveClass = this._leaveClass.bind(this);
this.getMcuClientStatus = this._getMcuClientStatus.bind(this);
//this.getClassDetail = this._getClassDetail;//停用
this.getClassStatusInfo = this._getClassStatusInfo.bind(this);
this.sendStartClass = this._sendStartClass.bind(this);
this.sendPauseClass = this._sendPauseClass.bind(this);
this.sendCloseClass = this._sendCloseClass.bind(this);
//录制回放
this.initRecordPlayback = this._initRecordPlayback.bind(this);
this.startRecordPlayback = this._startRecordPlayback.bind(this);
this.stopRecordPlayback = this._stopRecordPlayback.bind(this);
this.pauseRecordPlayback = this._pauseRecordPlayback.bind(this);
this.seekRecordPlayback = this._seekRecordPlayback.bind(this);
this.addBuffer = this._addBuffer.bind(this);
this.read = this._read.bind(this);
this.writeBuffer = this._writeBuffer.bind(this);
//chatApe
this.sendChatMsg = this._sendChatMsg.bind(this);
//videoApe
//this.getVideoPlayPath = this._getVideoPlayPath.bind(this);
this.getVideoPublishPath = this._getVideoPublishPath.bind(this);
this.getVideoAllChannelInfo = this._getVideoAllChannelInfo.bind(this);
this.publishVideo = this._publishVideo.bind(this);
this.stopPublishVideo = this._stopPublishVideo.bind(this);
this.sendVideoBroadcastMsg = this._sendVideoBroadcastMsg.bind(this);
//audioApe
//this.getAudioPlayPath = this._getPlayAudioPath.bind(this);
this.getAudioPublishPath = this._getPublishAudioPath.bind(this);
this.getAudioAllChannelInfo = this._getAudioAllChannelInfo.bind(this);
this.publishAudio = this._publishAudio.bind(this);
this.stopPublishAudio = this._stopPublishAudio.bind(this);
this.sendAudioBroadcastMsg = this.sendAudioCommandMsg.bind(this);
//whiteBoradApe
this.sendInsertAnnotaion = this._sendInsertAnnotaion.bind(this);
//this.sendDeleteAnnotaion=this._sendDeleteAnnotaion;
this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation.bind(this);
this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this);
this.sendGotoPrev = this._sendGotoPrev.bind(this);
//DocApe
this.sendDocumentUpload = this._sendDocumentUpload.bind(this);//上传文档
this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this); //切换文档
this.sendDocumentSwitchPage = this._sendDocumentSwitchPage.bind(this);//翻页
this.sendDocumentDelete = this._sassDeleteDocument.bind(this);
//删除文档,先通过Sass删除,sass删除成功之后再同步mcu
//this.sendDocumentDeleteAll= this._documentDeleteAll;//删除所有文档
this.sendDocumentCommand = this._sendDocumentCommand.bind(this);
//操作文档(翻页、缩放、滚动...)
this.getDocImageFullPath = this._getDocImageFullPath.bind(this);
//获取文档图片的完整路径
this.getDocPDFFullPath = this._getDocPDFFullPath.bind(this);//获取文档的完整路径
}
//mcu异常监听
_mcuErrorHandler(_data, _option) {
let option = _option || "";
let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option};
loger.error("MCU_ERROR", errorMessage);
this._emit(MessageTypes.ERROR_EVENT, errorMessage);
/* if (_mcuErrorCallBackFun) {
_mcuErrorCallBackFun(errorMessage);
}*/
}
//获取当前的状态
_getMcuClientStatus() {
return GlobalConfig.getCurrentStatus();
}
//获取课堂信息
_getClassDetail() {
return GlobalConfig.getClassDetail();
}
//获取当前课堂的状态信息
_getClassStatusInfo() {
return GlobalConfig.classStatusInfo;
}
//关闭课堂,所有人都退出
_doClassClose(_param) {
this._leaveClass();
}
//离开课堂,断开连接
_doClassExit() {
this._leaveClass();
}
//当前的课堂状态信息发生改变,需要保存课堂状态到Sass
_onClassStatusInfoChange(_param) {
//如果MCU连接已经断开,不发送
if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
return;
}
this._sassSaveClassStatusInfo();
}
//DocApe
this.sendDocumentUpload = this._sendDocumentUpload.bind(this);//上传文档
this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this); //切换文档
this.sendDocumentSwitchPage = this._sendDocumentSwitchPage.bind(this);//翻页
this.sendDocumentDelete = this._sassDeleteDocument.bind(this);;//删除文档,先通过Sass删除,sass删除成功之后再同步mcu
//this.sendDocumentDeleteAll= this._documentDeleteAll;//删除所有文档
this.sendDocumentCommand = this._sendDocumentCommand.bind(this);;//操作文档(翻页、缩放、滚动...)
this.getDocImageFullPath=this._getDocImageFullPath.bind(this);;//获取文档图片的完整路径
this.getDocPDFFullPath=this._getDocPDFFullPath.bind(this);;//获取文档的完整路径
}
//mcu异常监听
_mcuErrorHandler(_data, _option) {
let option = _option || "";
let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option};
loger.error("MCU_ERROR", errorMessage);
this._emit(MessageTypes.ERROR_EVENT,errorMessage);
/* if (_mcuErrorCallBackFun) {
_mcuErrorCallBackFun(errorMessage);
}*/
}
//获取当前的状态
_getMcuClientStatus() {
return GlobalConfig.getCurrentStatus();
}
//获取会议信息
_getClassDetail() {
return GlobalConfig.getClassDetail();
}
//获取当前会议的状态信息
_getClassStatusInfo(){
return GlobalConfig.classStatusInfo;
}
//关闭会议,所有人都退出
_doClassClose(_param) {
this._leaveClass();
}
//离开会议,断开连接
_doClassExit() {
this._leaveClass();
}
//当前的会议状态信息发生改变,需要保存会议状态到Sass
_onClassStatusInfoChange(_param) {
//如果MCU连接已经断开,不发送
if(GlobalConfig.getCurrentStatus().code!=GlobalConfig.statusCode_2.code){
loger.warn("不能保存会议状态",GlobalConfig.getCurrentStatus());
return;
}
this._sassSaveClassStatusInfo();
}
//如果是第一次点击开始上课,需要创建录制时的文件名
_onClassRecordStart(_param){
if(GlobalConfig.getCurrentStatus().code!=GlobalConfig.statusCode_2.code){
loger.warn("不能保存会议状态",GlobalConfig.getCurrentStatus());
return;
}
if(_sass){
_sass.saveClassRecordContrlInfo(_param);
}
}
//有人员离开
_onClassDeleteRoster(_data){
//{"nodeId":nodeId}
//当有人员离开的时候,如果离开的人员已经推流,那么需要停止推流,然后释放channel;
/* if(_data!=null&&_data.nodeId!=null){
loger.log("有人员离开,检查一下离开的人员是否关闭推流");
if(_video_ape){
_video_ape.stopPublishVideo(_data);
}
if(_audio_ape){
_audio_ape.stopPublishAudio(_data);
}
}*/
}
//当前会议中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel
//的占用状态导致,对于这种情况,需要释放掉
_onClassNonentityRoster(_param){
if(_param==null||_param.nodeId==null){
loger.warn("onClassNonentityRoster.参数错误")
return;
}
let data={"nodeId":_param.nodeId};
if(_video_ape){
_video_ape.stopPublishVideo(data);
}
if(_audio_ape){
_audio_ape.stopPublishAudio(data);
}
}
//Sass
//初始化
_init(_param) {
//{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('init初始化失败,参数错误');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
}
//判断必要的参数字段值
if (_param.classId == null || isNaN(_param.classId) || _param.portal == null || _param.portal == "") {
loger.error('init初始化失败', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
}
loger.log('init', _param);
//保存参数
GlobalConfig.classId = parseInt(_param.classId);
GlobalConfig.portal = _param.portal;
GlobalConfig.userRole = _param.userRole || ApeConsts.normal;
GlobalConfig.userId = _param.userId || "0";
GlobalConfig.userName=_param.userName || "";
//获取课堂校验信息
if (_sass) {
_sass.getJoinParams(GlobalConfig.getClassInfo());
}
}
//外部请求加入会议
_joinClass(_param) {
//_joinClassSuccessCallBackFun = _onSuccess;
//{"userName":"名字","password":""}
if (_param == null || EngineUtils.isEmptyObject(_param)) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
loger.log('不能进入会议,传递的参数不对.', _param);
return;
}
//判断userName
if (_param.userName == null || _param.userName == "") {
loger.log('不能进入会议,传递的参数不对.名字不能为空');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
return;
}
if(GlobalConfig.userName==null||GlobalConfig.userName==""){
GlobalConfig.userName = _param.userName;
}
GlobalConfig.password = _param.password || "";
GlobalConfig.hasCamera=(typeof _param.hasCamera=="boolean")? _param.hasCamera:false;
GlobalConfig.hasMicrophone=(typeof _param.hasMicrophone=="boolean")? _param.hasMicrophone:false;
//debugger;
//开始校验
if (_sass) {
_sass.passwordAndMd5Checking(GlobalConfig.getClassInfo());
}
}
// 用classId向SASS平台获取入会验证信息成功
_sassInitSuccessHandler(_data) {
//{"siteId":"h5test","passwordRequired":true,"md5":"de399d5540b3da2fbc1eb0a770d4fd66","code":0,"msType":1}
//储存数据
GlobalConfig.md5 = _data.md5 || "";//这个暂时用假数据,后台接口写完就有数据了
GlobalConfig.msType = _data.msType || 1;
GlobalConfig.siteId = _data.siteId || "";
GlobalConfig.classType = _data.meetingType || 0;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
GlobalConfig.passwordRequired = _data.passwordRequired || false;//md5验证的时候需要Sass返回的值,不能更改
loger.log('SASS平台获取入会验证信息成功.');
//设置当前的会议状态
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_1);
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.userName= GlobalConfig.userName;
initSuccessCallBackData.classType = GlobalConfig.classType;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
if (GlobalConfig.userRole== ApeConsts.host) {
initSuccessCallBackData.passwordRequired =true;
} else {
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
}
this._emit(MessageTypes.CLASS_INIT_SUCCESS,initSuccessCallBackData);
/* if (_initSuccessCallBackFun) {
_initSuccessCallBackFun(initSuccessCallBackData);
}*/
}
// 通过SASS平台验证(密码和MD5)
_sassJoinSuccessHandler(_data) {
//返回值
/* flag 数值型 无 True:成功
Flag:失败
h5_mcu_list 字符串 H5muc列表
maxVideoChannels 数值型 最大视频路数
maxAudioChannels 数值型 最大音频路数
h5Module 数值型 H5开关
ms 字符串 Ms列表
mcu 字符串 Mcu列表
rs 字符串 Rs列表
doc 字符串 Doc列表*/
//获取会议最完整的数据
if (_sass) {
_sass.getClassParam();
}
}
//获取会议所有参数 api/meeting/detail.do? flash中的接口文件是 getClassParam.do
_sassGetClassParamSuccessHandler(_data) {
//console.log(GlobalConfig.classStatusInfo)
loger.log('获取课堂会议的完整信息完成.');
// console.log(_data);
//包含整个会议最全的信息,储存数据
if (_data) {
GlobalConfig.mcuDelay=_data.mcuDelay || 60;//mcu消息延迟,用于文档模块
GlobalConfig.className = _data.meetingName || "";
GlobalConfig.classBeginTime = _data.beginTime || "";
GlobalConfig.classEndTime = _data.endTime || "";
GlobalConfig.userIp=_data.userIp||"";
GlobalConfig.maxVideoChannels = _data.maxVideoChannels;
GlobalConfig.maxAudioChannels = _data.maxAudioChannels;
GlobalConfig.setDocListPrepare(_data.docListPrepare); //提前上传的文档列表
GlobalConfig.setRecordList(_data.recordList);//录制回放地址
GlobalConfig.setDocList(_data.docList);//文档地址
GlobalConfig.setMsList(_data.msList);//推流播流服务器地址
GlobalConfig.setRsList(_data.rsList);//播放m3u8格式的地址
GlobalConfig.setMcuList(_data.mcuList);//mcu
GlobalConfig.setMusicList(_data.musicList);//
GlobalConfig.setMusicListPrepare(_data.musicListPrepare);//提前上传的声音文件列表
if (_data.mcuList) {
//MCU地址默认使用第一个
GlobalConfig.MCUServerIP =_data.mcuList[0].ip||"";
GlobalConfig.MCUServerPort =_data.mcuList[0].port||"";
}
//视频推流播流地址
if (_data.msList) {
//MS地址默认使用第一个
GlobalConfig.MSServerIP =_data.msList[0].ip||"";
GlobalConfig.MSServerPort =_data.msList[0].port||"";
}
//m3u8播流地址
if(_data.rsList){
//RS地址默认使用第一个
GlobalConfig.RSServerIP =_data.rsList[0].ip||"";
GlobalConfig.RSServerPort =_data.rsList[0].port||"";
}
//文档地址
if(_data.docList){
//doc地址默认使用第一个
GlobalConfig.DOCServerIP =_data.docList[0].ip||"";
GlobalConfig.DOCServerPort =_data.docList[0].port||"";
}
//record
if(_data.recordList){
//地址默认使用第一个
GlobalConfig.RecordServerIP =_data.recordList[0].ip||"";
GlobalConfig.RecordServerPort =_data.recordList[0].port||"";
}
}
if (_data.currentInfo) {
//根据从Sass获取的数据信息,同步最后一次保存的会议状态信息
loger.log("同步最后一次保存过的会议状态信息");
GlobalConfig.setClassStatusInfo(_data.currentInfo);
console.log(GlobalConfig.classStatusInfo);
} else {
loger.log("还没有保存过会议状信息");
}
//根据用户的userIp获取信息
this.getUserIpInfo();
}
//根据UserIp获取ip信息
getUserIpInfo(){
if(_serverCheck){
_serverCheck.getUserIpInfo("",GlobalConfig.userIp);
}
}
//MCU MS ip选点完成,开加入MCU
_serverCheckBestIpSuccessHandler(_data){
loger .log("_serverCheckBestIpSuccessHandler,IP选点结束");
this._joinMCU();
}
//保存会议状态信息
_sassSaveClassStatusInfo() {
if (GlobalConfig.isHost) {
//只有加入会议之后才能保存数据
if (GlobalConfig.getCurrentStatus().code == GlobalConfig.statusCode_2.code) {
//POST 保存数据
_sass.saveClassStatusInfo({"classStatusInfo": GlobalConfig.classStatusInfo});//保存会议状态信息
} else {
loger.error("不能保存会议数据", GlobalConfig.getCurrentStatus());
}
} else {
loger.log("没有保存会议状态信息的权限 isHost", GlobalConfig.isHost);
}
}
//保存会态信息成功
_sassSaveClassStatusInfoSuccessHandler(_data) {
loger.log('保存会议状态信息成功.');
console.log(_data);
}
_sassSaveClassRecordInfoSuccessHandler(_data){
loger.log('保存会议录制信息成功.');
console.log(_data);
}
//Sass校验流程结束之后,开始加入MCU
_joinMCU() {
loger.log('加入底层MCU会议.');
if (_mcu) {
_mcu.joinMCU(GlobalConfig.getClassInfo());
}
}
// MCU 会议成功
_mcuJoinMCUClassSuccessHandler(_data) {
loger.log('MCU 会议成功.');
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
//返回给客户端初始化成功的数据
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.DOCServerIP =GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort =GlobalConfig.DOCServerPort;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.className = GlobalConfig.className;
joinClassSuccessCallBackData.h5Module = GlobalConfig.h5Module;
joinClassSuccessCallBackData.isHost = GlobalConfig.isHost;
joinClassSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
joinClassSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
joinClassSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
joinClassSuccessCallBackData.msType = GlobalConfig.msType;
joinClassSuccessCallBackData.nodeId = GlobalConfig.nodeId;
joinClassSuccessCallBackData.password = GlobalConfig.password;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;// 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
joinClassSuccessCallBackData.role = GlobalConfig.role;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.userName = GlobalConfig.userName;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
joinClassSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
joinClassSuccessCallBackData.country = GlobalConfig.country;//国家
joinClassSuccessCallBackData.city = GlobalConfig.city;//城市
joinClassSuccessCallBackData.province = GlobalConfig.province;//服务商
joinClassSuccessCallBackData.isp = GlobalConfig.isp;//服务商
loger.log('加入会议成功');
console.log(joinClassSuccessCallBackData);
//加入会议成功,广播消息
this._emit(MessageTypes.CLASS_JOIN_SUCCESS,joinClassSuccessCallBackData);
}
//Sass删除文档数据
_sassDeleteDocument(_param) {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('sassDeleteDocument失败,参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
return;
}
//判断必要的参数字段值
if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.docId == null || _param.docId == "") {
loger.error('sassDeleteDocument失败', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
return;
}
loger.log('_sassDeleteDocument', _param);
if (_sass) {
_sass.sassDeleteDocument(_param);
}
}
//Sass删除文档成功之后,同步删除MCU数据
_sassDeleteDocumentSuccess(_param) {
loger.log('sassDeleteDocumentSuccess', _param);
this._sendDocumentDelete(_param);
}
//ConferApe
//开始上课
_sendStartClass(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_confer_ape){
_confer_ape.startClass(_param);
}
}
//暂停上课
_sendPauseClass(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_confer_ape){
_confer_ape.pauseClass(_param);
}
}
//停止上课
_sendCloseClass(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_confer_ape){
_confer_ape.closeClass(_param);
}
}
// 离开会议
_leaveClass() {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
//如果是第一次点击开始上课,需要创建录制时的文件名
_onClassRecordStart(_param) {
if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
return;
}
if (_sass) {
_sass.saveClassRecordContrlInfo(_param);
}
}
//停止推流
if(_video_ape){
_video_ape.stopPublishVideo();
//有人员离开
_onClassDeleteRoster(_data) {
//在conferApe中做处理,这里不需要再处理
//{"nodeId":nodeId}
//当有人员离开的时候,如果离开的人员已经推流,那么需要停止推流,然后释放channel;
/* if(_data!=null&&_data.nodeId!=null){
loger.log("有人员离开,检查一下离开的人员是否关闭推流");
if(_video_ape){
_video_ape.stopPublishVideo(_data);
}
if(_audio_ape){
_audio_ape.stopPublishAudio(_data);
}
}*/
}
if(_audio_ape){
_audio_ape.stopPublishAudio();
//当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel
//的占用状态导致,对于这种情况,需要释放掉
_onClassNonentityRoster(_param) {
if (_param == null || _param.nodeId == null) {
loger.warn("onClassNonentityRoster.参数错误")
return;
}
let data = {"nodeId": _param.nodeId};
if (_video_ape) {
_video_ape.stopPublishVideo(data);
}
if (_audio_ape) {
_audio_ape.stopPublishAudio(data);
}
}
//离开会议
if(_confer_ape){
_confer_ape.stopRecord();
_confer_ape.leaveClass();
//Sass
//初始化
_init(_param) {
//{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('init初始化失败,参数错误');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
}
//判断必要的参数字段值
if (_param.classId == null || isNaN(_param.classId) || _param.portal == null || _param.portal == "") {
loger.error('init初始化失败', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
return;
}
loger.log('init', _param);
//保存参数
GlobalConfig.isRecordPlayBack=false;//设置为非录制回放状态
GlobalConfig.classId = parseInt(_param.classId);
GlobalConfig.portal = _param.portal;
GlobalConfig.userRole = _param.userRole || ApeConsts.normal;
GlobalConfig.userId = _param.userId || "0";
GlobalConfig.userName = _param.userName || "";
//获取课堂校验信息
if (_sass) {
_sass.getJoinParams(GlobalConfig.getClassInfo());
}
}
//断开MCU连接
if(_mcu){
_mcu.leaveMCU();
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
//外部请求加入课堂
_joinClass(_param) {
//_joinClassSuccessCallBackFun = _onSuccess;
//{"userName":"名字","password":""}
if (_param == null || EngineUtils.isEmptyObject(_param)) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
loger.log('不能进入课堂,传递的参数不对.', _param);
return;
}
//判断userName
if (_param.userName == null || _param.userName == "") {
loger.log('不能进入课堂,传递的参数不对.名字不能为空');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PARAM);
return;
}
if (GlobalConfig.userName == null || GlobalConfig.userName == "") {
GlobalConfig.userName = _param.userName;
}
GlobalConfig.password = _param.password || "";
GlobalConfig.hasCamera = (typeof _param.hasCamera == "boolean") ? _param.hasCamera : false;
GlobalConfig.hasMicrophone = (typeof _param.hasMicrophone == "boolean") ? _param.hasMicrophone : false;
//debugger;
//开始校验
if (_sass) {
_sass.passwordAndMd5Checking(GlobalConfig.getClassInfo());
}
}
}
// 用classId向SASS平台获取入会验证信息成功
_sassInitSuccessHandler(_data) {
//{"siteId":"h5test","passwordRequired":true,"md5":"de399d5540b3da2fbc1eb0a770d4fd66","code":0,"msType":1}
//储存数据
GlobalConfig.md5 = _data.md5 || "";//这个暂时用假数据,后台接口写完就有数据了
GlobalConfig.msType = _data.msType || 1;
GlobalConfig.siteId = _data.siteId || "";
GlobalConfig.classType = _data.meetingType || 0;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
GlobalConfig.passwordRequired = _data.passwordRequired || false;//md5验证的时候需要Sass返回的值,不能更改
loger.log('SASS平台获取入会验证信息成功.');
//设置当前的课堂状态
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_1);
//返回给客户端初始化成功的数据
let initSuccessCallBackData = {};
initSuccessCallBackData.siteId = GlobalConfig.siteId;
initSuccessCallBackData.classId = GlobalConfig.classId;
initSuccessCallBackData.userRole = GlobalConfig.userRole;
initSuccessCallBackData.userId = GlobalConfig.userId;
initSuccessCallBackData.userName = GlobalConfig.userName;
initSuccessCallBackData.classType = GlobalConfig.classType;
//host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
if (GlobalConfig.userRole == ApeConsts.host) {
initSuccessCallBackData.passwordRequired = true;
} else {
initSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
}
//ChatApe
// 发送聊天消息
_sendChatMsg(_messageInfo) {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
this._emit(MessageTypes.CLASS_INIT_SUCCESS, initSuccessCallBackData);
}
// 通过SASS平台验证(密码和MD5)
_sassJoinSuccessHandler(_data) {
//返回值
/* flag 数值型 无 True:成功
Flag:失败
h5_mcu_list 字符串 H5muc列表
maxVideoChannels 数值型 最大视频路数
maxAudioChannels 数值型 最大音频路数
h5Module 数值型 H5开关
ms 字符串 Ms列表
mcu 字符串 Mcu列表
rs 字符串 Rs列表
doc 字符串 Doc列表*/
//获取课堂最完整的数据
if (_sass) {
_sass.getClassParam();
}
}
if(_messageInfo===null||EngineUtils.isEmptyObject(_messageInfo)){
loger.log('sendChatMsg 传递的参数不对',_messageInfo);
return ;
//获取课堂所有参数 api/meeting/detail.do? flash中的接口文件是 getClassParam.do
_sassGetClassParamSuccessHandler(_data) {
//console.log(GlobalConfig.classStatusInfo)
loger.log('获取课堂课堂的完整信息完成.');
// console.log(_data);
//包含整个课堂最全的信息,储存数据
if (_data) {
GlobalConfig.mcuDelay = _data.mcuDelay || 60;//mcu消息延迟,用于文档模块
GlobalConfig.className = _data.meetingName || "";
GlobalConfig.classBeginTime = _data.beginTime || "";
GlobalConfig.classEndTime = _data.endTime || "";
GlobalConfig.userIp = _data.userIp || "";
GlobalConfig.maxVideoChannels = _data.maxVideoChannels;
GlobalConfig.maxAudioChannels = _data.maxAudioChannels;
GlobalConfig.setDocListPrepare(_data.docListPrepare); //提前上传的文档列表
GlobalConfig.setRecordList(_data.recordList);//录制回放地址
GlobalConfig.setDocList(_data.docList);//文档地址
GlobalConfig.setMsList(_data.msList);//推流播流服务器地址
GlobalConfig.setRsList(_data.rsList);//播放m3u8格式的地址
GlobalConfig.setMcuList(_data.mcuList);//mcu
GlobalConfig.setMusicList(_data.musicList);//
GlobalConfig.setMusicListPrepare(_data.musicListPrepare);//提前上传的声音文件列表
if (_data.mcuList&&_data.mcuList.length>0) {
//MCU地址默认使用第一个
GlobalConfig.MCUServerIP = _data.mcuList[0].ip || "";
GlobalConfig.MCUServerPort = _data.mcuList[0].port || "";
}
//视频推流播流地址
if (_data.msList&&_data.msList.length>0) {
//MS地址默认使用第一个
GlobalConfig.MSServerIP = _data.msList[0].ip || "";
GlobalConfig.MSServerPort = _data.msList[0].port || "";
}
//m3u8播流地址
if (_data.rsList&&_data.rsList.length>0) {
//RS地址默认使用第一个
GlobalConfig.RSServerIP = _data.rsList[0].ip || "";
GlobalConfig.RSServerPort = _data.rsList[0].port || "";
}
//文档地址
if (_data.docList&&_data.docList.length>0) {
//doc地址默认使用第一个
GlobalConfig.DOCServerIP = _data.docList[0].ip || "";
GlobalConfig.DOCServerPort = _data.docList[0].port || "";
}
//record
if (_data.recordList&&_data.recordList.length>0) {
//地址默认使用第一个
GlobalConfig.RecordServerIP = _data.recordList[0].ip || "";
GlobalConfig.RecordServerPort = _data.recordList[0].port || "";
}
}
if (_data.currentInfo) {
//根据从Sass获取的数据信息,同步最后一次保存的课堂状态信息
loger.log("本地同步最后一次保存过的课堂状态信息");
GlobalConfig.setClassStatusInfo(_data.currentInfo);
console.log(GlobalConfig.classStatusInfo);
} else {
loger.log("还没有保存过课堂状信息");
}
//录制回放不需要选点
if(GlobalConfig.isRecordPlayBack){
if (_parseBuf) {
//开启录制回放流程
loger.log("开启录制回放流程");
_parseBuf.readyRecordPlay();
}else {
loger.warn("开启录制回放流程失败,还未创建模块");
}
}else {
//根据用户的userIp获取信息
this.getUserIpInfo();
}
}
if (_chat_ape) {
_chat_ape.sendChatMsg(_messageInfo);
//根据UserIp获取ip信息
getUserIpInfo() {
if (_serverCheck) {
_serverCheck.getUserIpInfo("", GlobalConfig.userIp);
}
}
}
//VidoeApe
videoUpdate(_data){
//视频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
if(_confer_ape){
_confer_ape.updaterRosterStatus(_data);
//MCU MS ip选点完成,开加入MCU
_serverCheckBestIpSuccessHandler(_data) {
loger.log("_serverCheckBestIpSuccessHandler,IP选点结束");
this._joinMCU();
}
//保存课堂状态信息
_sassSaveClassStatusInfo() {
if (GlobalConfig.isHost) {
//只有加入课堂之后才能保存数据
if (GlobalConfig.getCurrentStatus().code == GlobalConfig.statusCode_2.code) {
//POST 保存数据
_sass.saveClassStatusInfo({"classStatusInfo": GlobalConfig.classStatusInfo});//保存课堂状态信息
} else {
loger.error("不能保存课堂数据", GlobalConfig.getCurrentStatus());
}
} else {
loger.log("没有保存课堂状态信息的权限 isHost", GlobalConfig.isHost);
}
}
}
_sendVideoBroadcastMsg(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
//保存会态信息成功
_sassSaveClassStatusInfoSuccessHandler(_data) {
loger.log('保存课堂状态信息成功.');
console.log(_data);
}
if(_video_ape){
return _video_ape.sendVideoBroadcastMsg(_param);
_sassSaveClassRecordInfoSuccessHandler(_data) {
loger.log('保存课堂录制信息成功.');
console.log(_data);
}
}
_getVideoPlayPath(_param){
if(_video_ape){
return _video_ape.getPlayVideoPath(_param);
//Sass校验流程结束之后,开始加入MCU
_joinMCU() {
loger.log('加入底层MCU课堂.');
if (_mcu) {
_mcu.joinMCU(GlobalConfig.getClassInfo());
}
}
}
_getVideoPublishPath(_param){
if(_video_ape){
return _video_ape.getPublishVideoPath(_param);
// MCU 课堂成功
_mcuJoinMCUClassSuccessHandler(_data) {
loger.log('MCU 课堂成功.');
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
//返回给客户端初始化成功的数据
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.isRecordPlayBack=GlobalConfig.isRecordPlayBack;
joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.className = GlobalConfig.className;
joinClassSuccessCallBackData.h5Module = GlobalConfig.h5Module;
joinClassSuccessCallBackData.isHost = GlobalConfig.isHost;
joinClassSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
joinClassSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
joinClassSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
joinClassSuccessCallBackData.msType = GlobalConfig.msType;
joinClassSuccessCallBackData.nodeId = GlobalConfig.nodeId;
joinClassSuccessCallBackData.password = GlobalConfig.password;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;// 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
joinClassSuccessCallBackData.role = GlobalConfig.role;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.userName = GlobalConfig.userName;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
joinClassSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
joinClassSuccessCallBackData.country = GlobalConfig.country;//国家
joinClassSuccessCallBackData.city = GlobalConfig.city;//城市
joinClassSuccessCallBackData.province = GlobalConfig.province;//服务商
joinClassSuccessCallBackData.isp = GlobalConfig.isp;//服务商
loger.log('加入课堂成功');
console.log(joinClassSuccessCallBackData);
//加入课堂成功,广播消息
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
}
//Sass删除文档数据
_sassDeleteDocument(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//判断传入的参数是否存在
if (_param == null || EngineUtils.isEmptyObject(_param)) {
loger.error('sassDeleteDocument失败,参数错误', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
return;
}
//判断必要的参数字段值
if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.docId == null || _param.docId == "") {
loger.error('sassDeleteDocument失败', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
return;
}
loger.log('_sassDeleteDocument', _param);
if (_sass) {
_sass.sassDeleteDocument(_param);
}
}
}
_getVideoAllChannelInfo(_param){
if(_video_ape){
return _video_ape.getAllChannelInfo(_param);
//Sass删除文档成功之后,同步删除MCU数据
_sassDeleteDocumentSuccess(_param) {
loger.log('sassDeleteDocumentSuccess', _param);
this._sendDocumentDelete(_param);
}
}
_publishVideo(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
//ConferApe
//开始上课
_sendStartClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_confer_ape) {
_confer_ape.startClass(_param);
}
}
if(_video_ape){
return _video_ape.publishVideo(_param);
//暂停上课
_sendPauseClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_confer_ape) {
_confer_ape.pauseClass(_param);
}
}
}
_stopPublishVideo(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
//停止上课
_sendCloseClass(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_confer_ape) {
_confer_ape.closeClass(_param);
}
}
if(_video_ape){
return _video_ape.stopPublishVideo(_param);
// 离开课堂
_leaveClass() {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
//停止推流
if (_video_ape) {
_video_ape.stopPublishVideo();
}
if (_audio_ape) {
_audio_ape.stopPublishAudio();
}
//离开课堂
if (_confer_ape) {
_confer_ape.stopRecord();
_confer_ape.leaveClass();
}
//断开MCU连接
if (_mcu) {
_mcu.leaveMCU();
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
}
}
}
//AudioApe
audioUpdate(_data){
//音频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
if(_confer_ape){
_confer_ape.updaterRosterStatus(_data);
//ChatApe
// 发送聊天消息
_sendChatMsg(_messageInfo) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_messageInfo === null || EngineUtils.isEmptyObject(_messageInfo)) {
loger.log('sendChatMsg 传递的参数不对', _messageInfo);
return;
}
if (_chat_ape) {
_chat_ape.sendChatMsg(_messageInfo);
}
}
}
sendAudioCommandMsg(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
//VidoeApe
videoUpdate(_data) {
//视频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
if (_confer_ape) {
_confer_ape.updaterRosterStatus(_data);
}
}
_sendVideoBroadcastMsg(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_video_ape) {
return _video_ape.sendVideoBroadcastMsg(_param);
}
}
if(_audio_ape){
return _audio_ape.sendAudioBroadcastMsg(_param);
_getVideoPlayPath(_param) {
if (_video_ape) {
return _video_ape.getPlayVideoPath(_param);
}
}
}
_getPlayAudioPath(_param){
if(_audio_ape){
return _audio_ape.getAudioPlayPath(_param);
_getVideoPublishPath(_param) {
if (_video_ape) {
return _video_ape.getPublishVideoPath(_param);
}
}
}
_getPublishAudioPath(_param){
if(_audio_ape){
return _audio_ape.getAudioPublishPath(_param);
_getVideoAllChannelInfo(_param) {
if (_video_ape) {
return _video_ape.getAllChannelInfo(_param);
}
}
}
_getAudioAllChannelInfo(_param){
if(_audio_ape){
return _audio_ape.getAllChannelInfo(_param);
_publishVideo(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_video_ape) {
return _video_ape.publishVideo(_param);
}
}
}
_publishAudio(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
_stopPublishVideo(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_video_ape) {
return _video_ape.stopPublishVideo(_param);
}
}
if(_audio_ape){
return _audio_ape.publishAudio(_param);
//AudioApe
audioUpdate(_data) {
//音频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
if (_confer_ape) {
_confer_ape.updaterRosterStatus(_data);
}
}
}
_stopPublishAudio(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
sendAudioCommandMsg(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_audio_ape) {
return _audio_ape.sendAudioBroadcastMsg(_param);
}
}
if(_audio_ape){
return _audio_ape.stopPublishAudio(_param);
_getPlayAudioPath(_param) {
if (_audio_ape) {
return _audio_ape.getAudioPlayPath(_param);
}
}
}
_getPublishAudioPath(_param) {
if (_audio_ape) {
return _audio_ape.getAudioPublishPath(_param);
}
}
//WhiteBoardApe
// 添加标注,发送信息
_sendInsertAnnotaion(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
_getAudioAllChannelInfo(_param) {
if (_audio_ape) {
return _audio_ape.getAllChannelInfo(_param);
}
}
if(_whiteboard_ape){
_whiteboard_ape.sendInsetAnnotaion(_param);
}
}
//删除标注,发送信息
_sendDeleteAnnotaion(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_whiteboard_ape){
_whiteboard_ape.sendDeleteAnnotaion(_param);
}
}
//删除当前页面上的所有标注
_sendDeleteCurPageAnnotation(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_whiteboard_ape){
_whiteboard_ape.sendDeleteCurPageAnnotation(_param);
}
}
//删除所有标注
_sendDeleteAllAnnotation(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_whiteboard_ape){
_whiteboard_ape.sendDeleteAllAnnotation(_param);
}
}
//返回上一步标注
_sendGotoPrev(_param){
if(_whiteboard_ape){
_whiteboard_ape.sendGotoPrev(_param);
}
}
//DocApe
//获取文档完整路径
_getDocImageFullPath(_param){
if(_doc_ape){
return _doc_ape.getDocImageFullPath(_param);
}else {
loger.error("文档模块还没有创建,无法获取");
return [];
}
}
_getDocPDFFullPath(_param){
if(_doc_ape){
return _doc_ape.getDocPDFFullPath(_param);
}else {
loger.error("文档模块还没有创建,无法获取");
return [];
}
}
//上传文档
_sendDocumentUpload(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentUpload(_param);
}
}
//切换文档
_sendDocumentSwitchDoc(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentSwitchDoc(_param);
}
}
//操作文档(翻页)
_sendDocumentSwitchPage(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentSwitchPage(_param);
}
}
//操作文档(缩放、滚动...)
_sendDocumentCommand(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentCommand(_param);
}
}
//删除文档
_sendDocumentDelete(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentDelete(_param);
}
}
//删除所有文档
_documentDeleteAll(_param){
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if(_doc_ape){
_doc_ape.documentDeleteAll(_param);
}
}
//// 文档变更,白板也需要做处理
docUpdateHandler(_data) {
if(!_mcu.connected){
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
loger.log('Doc UpdateId ->');
console.log(_data);
if(_whiteboard_ape){
_whiteboard_ape.docUpdateHandler(_data);
}
}
//文档删除,白板也需要做处理
docDeleteHandler(_data){
if(_whiteboard_ape){
_whiteboard_ape.docDeleteHandler(_data);
}
}
//文档加入频道成功,同步到MCU服务器上的数据
docJoinChannelSuccess(){
loger.log("docJoinChannelSuccess isHost=",GlobalConfig.isHost);
console.log(GlobalConfig.docListPrepare);
loger.log("docJoinChannelSuccess docListPrepare=");
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
if(GlobalConfig.isHost){
for (let value of GlobalConfig.docListPrepare){
if(value){
/* //提前上传的文档文档信息的结构
{
"MD5": "f3feb3fac8cd3a953bded00e07a0c66b",
"absoluteLocation": "http://101.200.150.192/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf",
"createUserID": "972",
"createUserIP": "114.241.81.175",
"createUserName": "base",
"dynamicPPT": 0,
"dynamicTransferStatic": "",
"id": "8ab3b0ed5a00f2fa015a0219a3df016c",
"meetingNumber": "",
"name": "McuClient_v.1.0.1_API.pdf",
"orderStr": "",
"pdfSize": 5,
"processEndTime": "2017-02-03 11:54:31",
"processRate": 0,
"processStartTime": "2017-02-03 11:54:27",
"relativeLocation": "/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf",
"siteID": "h5test",
"size": 360920,
"status": 3,
"type": "pdf",
"uploadEndTime": "2017-02-03 11:54:27",
"uploadStartTime": "2017-02-03 11:54:27"
}*/
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);
}
}
}
}
_publishAudio(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_audio_ape) {
return _audio_ape.publishAudio(_param);
}
}
_stopPublishAudio(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_audio_ape) {
return _audio_ape.stopPublishAudio(_param);
}
}
//WhiteBoardApe
// 添加标注,发送信息
_sendInsertAnnotaion(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_whiteboard_ape) {
_whiteboard_ape.sendInsetAnnotaion(_param);
}
}
//删除标注,发送信息
_sendDeleteAnnotaion(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_whiteboard_ape) {
_whiteboard_ape.sendDeleteAnnotaion(_param);
}
}
//删除当前页面上的所有标注
_sendDeleteCurPageAnnotation(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_whiteboard_ape) {
_whiteboard_ape.sendDeleteCurPageAnnotation(_param);
}
}
//删除所有标注
_sendDeleteAllAnnotation(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_whiteboard_ape) {
_whiteboard_ape.sendDeleteAllAnnotation(_param);
}
}
//返回上一步标注
_sendGotoPrev(_param) {
if (_whiteboard_ape) {
_whiteboard_ape.sendGotoPrev(_param);
}
}
//DocApe
//获取文档完整路径
_getDocImageFullPath(_param) {
if (_doc_ape) {
return _doc_ape.getDocImageFullPath(_param);
} else {
loger.error("文档模块还没有创建,无法获取");
return [];
}
}
_getDocPDFFullPath(_param) {
if (_doc_ape) {
return _doc_ape.getDocPDFFullPath(_param);
} else {
loger.error("文档模块还没有创建,无法获取");
return [];
}
}
//上传文档
_sendDocumentUpload(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentUpload(_param);
}
}
//切换文档
_sendDocumentSwitchDoc(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentSwitchDoc(_param);
}
}
//操作文档(翻页)
_sendDocumentSwitchPage(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentSwitchPage(_param);
}
}
//操作文档(缩放、滚动...)
_sendDocumentCommand(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentCommand(_param);
}
}
//删除文档
_sendDocumentDelete(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentDelete(_param);
}
}
//删除所有文档
_documentDeleteAll(_param) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
if (_doc_ape) {
_doc_ape.documentDeleteAll(_param);
}
}
//// 文档变更,白板也需要做处理
docUpdateHandler(_data) {
if (!_mcu.connected) {
loger.warn(GlobalConfig.getCurrentStatus());
return;
}
loger.log('Doc UpdateId ->');
console.log(_data);
if (_whiteboard_ape) {
_whiteboard_ape.docUpdateHandler(_data);
}
}
//文档删除,白板也需要做处理
docDeleteHandler(_data) {
if (_whiteboard_ape) {
_whiteboard_ape.docDeleteHandler(_data);
}
}
//文档加入频道成功,同步到MCU服务器上的数据
docJoinChannelSuccess() {
loger.log("docJoinChannelSuccess isHost=", GlobalConfig.isHost);
console.log(GlobalConfig.docListPrepare);
loger.log("docJoinChannelSuccess docListPrepare=");
//如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
if (GlobalConfig.isHost) {
for (let value of GlobalConfig.docListPrepare) {
if (value) {
/* //提前上传的文档文档信息的结构
{
"MD5": "f3feb3fac8cd3a953bded00e07a0c66b",
"absoluteLocation": "http://101.200.150.192/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf",
"createUserID": "972",
"createUserIP": "114.241.81.175",
"createUserName": "base",
"dynamicPPT": 0,
"dynamicTransferStatic": "",
"id": "8ab3b0ed5a00f2fa015a0219a3df016c",
"meetingNumber": "",
"name": "McuClient_v.1.0.1_API.pdf",
"orderStr": "",
"pdfSize": 5,
"processEndTime": "2017-02-03 11:54:31",
"processRate": 0,
"processStartTime": "2017-02-03 11:54:27",
"relativeLocation": "/DocSharing/data/526661904/20170203-115400026/f3feb3fac8cd3a953bded00e07a0c66b.swf",
"siteID": "h5test",
"size": 360920,
"status": 3,
"type": "pdf",
"uploadEndTime": "2017-02-03 11:54:27",
"uploadStartTime": "2017-02-03 11:54:27"
}*/
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){
//{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0}
if (_param == null) {
loger.error('录制回放初始化失败,参数错误');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_INIT_RECORD_PLAY_BACK_FAILED);
return;
}
//判断必要的参数字段值
if (_param.classId == null || isNaN(_param.classId) || _param.portal == null || _param.portal == "") {
loger.error('录制回放初始化失败', _param);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_INIT_RECORD_PLAY_BACK_FAILED);
return;
}
loger.log('录制回放', _param);
//保存参数
GlobalConfig.isRecordPlayBack=true;//设置为录制回放状态
GlobalConfig.classId = parseInt(_param.classId);
GlobalConfig.portal = _param.portal;
GlobalConfig.userRole =ApeConsts.normal;//*************很重要,录制回放的时候,身份模式是普通人********
GlobalConfig.userId = _param.userId || "0";
GlobalConfig.userName = _param.userName || "";
//获取课堂最完整的数据,录制回放需要获取课堂数据
if (_sass) {
_sass.getClassParam();
}
}
//开始录制回放
_startRecordPlayback(_param) {
if (_parseBuf) {
_parseBuf.startRecordPlayback(_param);
}
}
//停止录制回放
_stopRecordPlayback(_param) {
if (_parseBuf) {
_parseBuf.stopRecordPlayback(_param);
}
}
//暂停录制回放
_pauseRecordPlayback(_param) {
if (_parseBuf) {
_parseBuf.pauseRecordPlayback(_param);
}
}
//seek录制回放
_seekRecordPlayback(_param) {
if (_parseBuf) {
_parseBuf.seekRecordPlayback(_param);
}
}
_writeBuffer(_param) {
if (_parseBuf) {
_parseBuf.writeBuffer(_param);
}
}
_addBuffer(_arrayBuffer) {
if (_parseBuf) {
_parseBuf.addBuffer(_arrayBuffer);
}
}
_read(_param) {
if (_parseBuf) {
_parseBuf.read(_param);
}
}
// MCU 课堂成功
_joinRecordPlaybackSuccessHandler(_data) {
loger.log('加入录制回放成功.');
GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
//返回给客户端初始化成功的数据
let joinClassSuccessCallBackData = {};
joinClassSuccessCallBackData.isRecordPlayBack=GlobalConfig.isRecordPlayBack;
joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.className = GlobalConfig.className;
joinClassSuccessCallBackData.h5Module = GlobalConfig.h5Module;
joinClassSuccessCallBackData.isHost = GlobalConfig.isHost;//
joinClassSuccessCallBackData.maxAudioChannels = GlobalConfig.maxAudioChannels;
joinClassSuccessCallBackData.maxVideoChannels = GlobalConfig.maxVideoChannels;
joinClassSuccessCallBackData.mcuDelay = GlobalConfig.mcuDelay;
joinClassSuccessCallBackData.msType = GlobalConfig.msType;
joinClassSuccessCallBackData.nodeId = GlobalConfig.nodeId;
joinClassSuccessCallBackData.password = GlobalConfig.password;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;// 老师的默认是true
//GlobalConfig.passwordRequired 老师的默认是true
//GlobalConfig.portal=_data.portal;
joinClassSuccessCallBackData.role = GlobalConfig.role;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.topNodeID = GlobalConfig.topNodeID;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.userName = GlobalConfig.userName;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userType = GlobalConfig.userType;
joinClassSuccessCallBackData.siteId = GlobalConfig.siteId;
joinClassSuccessCallBackData.classId = GlobalConfig.classId;
joinClassSuccessCallBackData.userRole = GlobalConfig.userRole;
joinClassSuccessCallBackData.userId = GlobalConfig.userId;
joinClassSuccessCallBackData.passwordRequired = GlobalConfig.passwordRequired;
joinClassSuccessCallBackData.classType = GlobalConfig.classType || ApeConsts.CLASS_TYPE_INTERACT;
joinClassSuccessCallBackData.country = GlobalConfig.country;//国家
joinClassSuccessCallBackData.city = GlobalConfig.city;//城市
joinClassSuccessCallBackData.province = GlobalConfig.province;//服务商
joinClassSuccessCallBackData.isp = GlobalConfig.isp;//服务商
console.log(joinClassSuccessCallBackData);
//和加入课堂成功使用同样的消息处理
this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
}
}
... ...
... ... @@ -234,9 +234,9 @@ class GlobalConfig {
}
GlobalConfig.statusCode_0={"code":0,message:"SDK 未初始化"};
GlobalConfig.statusCode_1={"code":1,message:"未加入会议"};
GlobalConfig.statusCode_2={"code":2,message:"已经加入会议"};
GlobalConfig.statusCode_3={"code":3,message:"已经离开会议"};
GlobalConfig.statusCode_1={"code":1,message:"未加入课堂"};
GlobalConfig.statusCode_2={"code":2,message:"已经加入课堂"};
GlobalConfig.statusCode_3={"code":3,message:"已经离开课堂"};
GlobalConfig.statusCode_4={"code":4,message:"未知状态"};
GlobalConfig.md5="";
... ... @@ -303,7 +303,7 @@ GlobalConfig.recordFileName="";//录制的文件名,如 果为空就创建一个
GlobalConfig.recordDownloadUrl="";//下载地址
GlobalConfig.recordReplaytickValues={}; // 滚动条关键点,用于快进快退
GlobalConfig.updateClassInfoDelay=30;//(秒),每隔30秒同步一次会议状态的并保存到Sass
GlobalConfig.updateClassInfoDelay=30;//(秒),每隔30秒同步一次课堂状态的并保存到Sass
//GlobalConfig.serverTimestamp=0;//当前的系统时间戳 用get set 获取
... ... @@ -313,7 +313,7 @@ GlobalConfig.activeDocCurPage=1;//当前激活的文档的当前页
GlobalConfig.classAllParam={};//Sass直接返回的所有会议信息(最全)
GlobalConfig.classAllParam={};//Sass直接返回的所有课堂信息(最全)
GlobalConfig.classDetail={};//Sass直接返回的当前课堂基本信息
GlobalConfig.docListPrepare=[]; // 已经提前上传的文档,进入课堂后需要自动加载
... ... @@ -331,4 +331,6 @@ GlobalConfig.city ="";//城市
GlobalConfig.province = "";//服务商
GlobalConfig.isp ="";//服务商
GlobalConfig.isRecordPlayBack=false;//是否是录制回放,默认是否
export default GlobalConfig;
... ...
... ... @@ -9,11 +9,11 @@ function MessageTypes() {}
MessageTypes.CLASS_INIT_SUCCESS="class_init_success";//'class.init.success';//初始化成功
//MessageTypes.CLASS_INIT_FAILED='class.init.failed';//初始化失败
//加入会议相关事件定义
//加入课堂相关事件定义
MessageTypes.CLASS_JOIN_MCU_SUCCESS ="class_join_mcu_success"// 'join.mcu.success';
//MessageTypes.CLASS_JOIN_FAILED = 'join.class.failed';
//会议信息和操作事件定义
//课堂信息和操作事件定义
//MessageTypes.CLASS_SHOW_DETAIL = 'class_detail.message';
MessageTypes.CLASS_JOIN_SUCCESS ="class_join_success"// 'join.class.success';
MessageTypes.CLASS_UPDATE_ROSTER_NUM ="class_update_roster_num";// 'roster_num.message';
... ... @@ -21,9 +21,9 @@ MessageTypes.CLASS_INSERT_ROSTER ="class_insert_roster";// 'roster.insert.messag
MessageTypes.CLASS_DELETE_ROSTER ="class_delete_roster"// 'roster.delete.message';
MessageTypes.CLASS_NONENTITY_ROSTER ="class_nonenetity_roster";// 'roster.nonentity.message';
MessageTypes.CLASS_EXIT ="class_exit";// 'class.exit';//退出 关闭会议
MessageTypes.CLASS_UPTATE_STATUS ="class_update_status";// 'class.update.status';//更新会议状态信息
MessageTypes.CLASS_STATUS_INFO_CHANGE="class_status_info_change";// 'class.status.info.change';//会议状态信息发生改变,需要保存数据到sass和同步MCU
MessageTypes.CLASS_EXIT ="class_exit";// 'class.exit';//退出 关闭课堂
MessageTypes.CLASS_UPTATE_STATUS ="class_update_status";// 'class.update.status';//更新课堂状态信息
MessageTypes.CLASS_STATUS_INFO_CHANGE="class_status_info_change";// 'class.status.info.change';//课堂状态信息发生改变,需要保存数据到sass和同步MCU
MessageTypes.CLASS_UPDATE_TIMER="class_update_timer";//'class.update.timer';//更新当前上课的时间
... ... @@ -37,13 +37,13 @@ MessageTypes.CHAT_RECEIVE ="chat_receive_message";// 'chat.receive';
//视频模块事件定义
MessageTypes.VIDEO_PLAY ="video_play";// 'video.play';//播放视频
MessageTypes.VIDEO_STOP ="video_stop"; //'video.stop';//停止视频
MessageTypes.VIDEO_UPDATE ="video_update";// //这个监听事件不能删除,需要通知会议模块,检查channel占用(内部使用)
MessageTypes.VIDEO_UPDATE ="video_update";// //这个监听事件不能删除,需要通知课堂模块,检查channel占用(内部使用)
MessageTypes.VIDEO_BROADCAST= "video_broadcast";//'video.broadcast';
//音频模块事件定义
MessageTypes.AUDIO_PLAY ="audio_play";// 'audio.play';//播放
MessageTypes.AUDIO_STOP = "audio_stop";//'audio.stop';//停止
MessageTypes.AUDIO_UPDATE = "audio_update";//这个监听事件不能删除,需要通知会议模块,检查channel占用(内部使用)
MessageTypes.AUDIO_UPDATE = "audio_update";//这个监听事件不能删除,需要通知课堂模块,检查channel占用(内部使用)
MessageTypes.AUDIO_BROADCAST= "audio_broadcast";//'audio.broadcast';
... ... @@ -57,15 +57,12 @@ MessageTypes.DOC_UPDATE ="document_update";// 'document.update';//更新文档(
//MessageTypes.DOC_DELETE='document.delete';//删除文档
//MessageTypes.DOC_ANNOTATION = 'document.annotation';//笔记
//白板笔记事件定义
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';
//错误事件定义
MessageTypes.MCU_ERROR ="mcu_error";//"mcuError";//MCU错误(内部使用)
MessageTypes.ERROR_EVENT="error_event";//外部监听错误的消息ID(外部使用)
... ... @@ -73,7 +70,7 @@ MessageTypes.ERROR_EVENT="error_event";//外部监听错误的消息ID(外部使
//---------------错误消息 ErrorCode 定义-------------------------------------------------
//会议初始化失败的几种情况
//课堂初始化失败的几种情况
MessageTypes.ERR_CLASS_INIT_PARAM=100;//初始化参数错误
MessageTypes.ERR_CLASS_INIT_NETWORK=101;//初始化网络错误
MessageTypes.ERR_CLASS_INIT_PROTOCOL=102;//初始化协议错误
... ... @@ -83,11 +80,11 @@ MessageTypes.ERR_CLASS_INIT_FAILED_2=105;//初始化验证失败,无效的课堂
MessageTypes.ERR_CLASS_INIT_FAILED_3=106;//初始化验证失败,没有对应的站点
MessageTypes.ERR_CLASS_INIT_FAILED_4=107;//初始化验证失败,站点已过期
//加入会议失败的几种情况
MessageTypes.ERR_CLASS_JOIN_NETWORK=200;//加入会议网络错误
MessageTypes.ERR_CLASS_JOIN_PROTOCOL=201;//加入会议化协议错误
MessageTypes.ERR_CLASS_JOIN_FAILED=202;//加入会议化异常错误
MessageTypes.ERR_CLASS_JOIN_PARAM=203;//加入会议参数错误
//加入课堂失败的几种情况
MessageTypes.ERR_CLASS_JOIN_NETWORK=200;//加入课堂网络错误
MessageTypes.ERR_CLASS_JOIN_PROTOCOL=201;//加入课堂化协议错误
MessageTypes.ERR_CLASS_JOIN_FAILED=202;//加入课堂化异常错误
MessageTypes.ERR_CLASS_JOIN_PARAM=203;//加入课堂参数错误
MessageTypes.ERR_CLASS_JOIN_FULL=204;//人数已满
MessageTypes.ERR_CLASS_MD5_WRONG=205;//MD5验证失败
MessageTypes.ERR_CLASS_PASSWORD_WRONG=206;//密码错误
... ... @@ -98,7 +95,7 @@ MessageTypes.ERR_GET_CLASS_DETAIL=300;//获取classDetail失败
MessageTypes.ERR_GET_CLASS_PARAML=301;//获取ClassParam失败
//APE
MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN=500;//APE在sdk为初始化或未加入会议之前调用发送数据接口
MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN=500;//APE在sdk为初始化或未加入课堂之前调用发送数据接口
MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG=501;//APE在接口调用时参数错误
//DOC
... ... @@ -110,10 +107,15 @@ MessageTypes.ERR_SDK_FAILED=700;// sdk还没初始化
MessageTypes.ERR_INTERFACE_NONE=701;//调用的接口不存在
MessageTypes.ERR_INTERFACE_PARAMS_ERROR=702;//调用的接口,传递的参数不正确
MessageTypes.ERR_INIT_RECORD_PLAY_BACK_FAILED=910;//初始化录制回放失败
MessageTypes.ERR_GET_RECORD_PLAY_BACK_DATA_FAILED=911;//获取录制回放数据失败
MessageTypes.ERR_NETWORK=10000;//网络错误
MessageTypes.ERR_UNKNOWN=10001;//未知错误
MessageTypes.ERR_SOCKET_DISCONNECT=20000;//MCU断开连接,已经离开会议
MessageTypes.ERR_SOCKET_DISCONNECT=20000;//MCU断开连接,已经离开课堂
//---------------错误消息 Error Reson 定义-------------------------------------------------
MessageTypes.ErrorReson={};
... ... @@ -128,11 +130,11 @@ MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_INIT_FAILED_3]="初始化验证
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_INIT_FAILED_4]="初始化验证失败,站点已过期";
//加入会议失败的几种情况
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_NETWORK]="加入会议网络错误";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_PROTOCOL]="加入会议化协议错误";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_FAILED]="加入会议化异常错误";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_PARAM]="加入会议参数错误";
//加入课堂失败的几种情况
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_NETWORK]="加入课堂网络错误";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_PROTOCOL]="加入课堂化协议错误";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_FAILED]="加入课堂化异常错误";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_PARAM]="加入课堂参数错误";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_JOIN_FULL]="人数已满";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_MD5_WRONG]="MD5验证失败";
MessageTypes.ErrorReson[MessageTypes.ERR_CLASS_PASSWORD_WRONG]="密码错误";
... ... @@ -144,7 +146,7 @@ MessageTypes.ErrorReson[MessageTypes.ERR_GET_CLASS_DETAIL]="获取classDetail失
MessageTypes.ErrorReson[MessageTypes.ERR_GET_CLASS_PARAML]="获取ClassParam失败";
//APE
MessageTypes.ErrorReson[MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN]="APE在sdk为初始化或未加入会议之前调用发送数据接口";
MessageTypes.ErrorReson[MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN]="APE在sdk为初始化或未加入课堂之前调用发送数据接口";
MessageTypes.ErrorReson[MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG]="APE在接口调用时参数错误";
//DOC
... ... @@ -155,10 +157,16 @@ MessageTypes.ErrorReson[MessageTypes.ERR_SDK_FAILED]="sdk还没初始化";
MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_NONE]="调用的接口不存在";
MessageTypes.ErrorReson[MessageTypes.ERR_INTERFACE_PARAMS_ERROR]="调用的接口,传递的参数不正确";
MessageTypes.ErrorReson[MessageTypes.ERR_INIT_RECORD_PLAY_BACK_FAILED]="初始化录制回放失败";
MessageTypes.ErrorReson[MessageTypes.ERR_GET_RECORD_PLAY_BACK_DATA_FAILED]="获取录制回放数据失败";
MessageTypes.ErrorReson[MessageTypes.ERR_NETWORK]="网络错误";
MessageTypes.ErrorReson[MessageTypes.ERR_UNKNOWN]="未知错误";
MessageTypes.ErrorReson[MessageTypes.ERR_SOCKET_DISCONNECT]="MCU断开连接,已经离开会议";
MessageTypes.ErrorReson[MessageTypes.ERR_SOCKET_DISCONNECT]="MCU断开连接,已经离开课堂";
... ...
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';
let parseBuffer;
// 日志对象
const loger = Loger.getLoger('RecordPlayBackParse');
class RecordPlayBackParse extends Emiter {
constructor() {
super();
loger.log("RecordPlayBackParse");
parseBuffer = new ByteBuffer( ByteBuffer.DEFAULT_CAPACITY,ByteBuffer.LITTLE_ENDIAN);
parseBuffer.clear();
console.log(parseBuffer);
this._apes = {};
}
//method--------------------内部---------------------------------------------
// 注册Ape
registerApe(ape) {
this._apes[ape._session_id] = ape;
}
// 录制回放EverSocket底层消息处理
_everSocketMsgReceivedHandler(data) {
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);
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);
} else {
loger.warn(sessionLabel + '尚未注册');
}
break;
default:
loger.warn('PDU-未知类型-等待处理.', pduType);
}
}
//method------------外部接口-------------------------------------
//加载录制文件
readyRecordPlay(){
loger.log("读取回放数据");
//let url = `http://123.56.73.119:80/h5dev/20170306/1357644520_20170306.rec`;
let url=`http://${ GlobalConfig.RecordServerIP}:${ GlobalConfig.RecordServerPort}/${GlobalConfig.recordFileName}`;
console.log(url);
fetch(url, {
timeout: 90000
})
.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._emit(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS);
}
addArrayBuffer(arrayBuffer) {
loger.log("addArrayBuffer", arrayBuffer.byteLength);
parseBuffer.append(arrayBuffer, "binary");
}
read() {
//loger.log("readUInt64", parseBuffer.readUInt64(0));
//loger.log("readUInt32", parseBuffer.readUInt32(8));
//loger.log("readByte", parseBuffer.readByte(12));
let byteLength=parseBuffer.offset;
parseBuffer.byteOffset=0;
var position = 0;
while (position<byteLength){
var time = parseBuffer.readUInt64(position, true);
position += 8;
var len = parseBuffer.readUInt32(position, true);
position += 4;
var byte = parseBuffer.buffer.slice(position, (position+len));
position += len;
console.log(time, len, byte);
this._everSocketMsgReceivedHandler(byte);
}
}
writeBuffer() {
parseBuffer.writeUint64(123456789, 0).flip();
parseBuffer.writeUint32(22211122, 8).flip();
}
startRecordPlayback(_param) {
}
stopRecordPlayback(_param) {
}
pauseRecordPlayback(_param) {
}
seekRecordPlayback(_param) {
}
}
RecordPlayBackParse.prototype.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS = RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS = 'class_join_recordPlayback_success';//加入录制回放成功
export default new RecordPlayBackParse;
... ...
... ... @@ -117,7 +117,7 @@ class Sass extends Emiter {
}
let url = `http://${confInfo.portal}/3m/api/meeting/signIn.do?siteId=${confInfo.siteId}&classId=${confInfo.classId}&isTeacher=${isTeacher}&password=${confInfo.password}`;
loger.log('3.会议密码校验', url);
loger.log('3.课堂密码校验', url);
fetch(url, {
timeout: 5000
})
... ... @@ -125,7 +125,7 @@ class Sass extends Emiter {
if (ret.status === 200) {
return ret.text();
} else {
loger.error(`会议密码校验-网络异常.状态码:${ret.status}`);
loger.error(`课堂密码校验-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_NETWORK);
throw '';
}
... ... @@ -133,20 +133,20 @@ class Sass extends Emiter {
.then(ret => {
let rectObj = JSON.parse(ret);
if (rectObj.flag === 'false' || rectObj.flag === false) {
loger.error(`会议密码校验-失败.`);
loger.error(`课堂密码校验-失败.`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_PASSWORD_WRONG);
return;
}
if (rectObj.flag === 'true' || rectObj.flag === true) {
loger.log(`会议密码校验-成功.`);
loger.log(`课堂密码校验-成功.`);
this.sendMD5Checking();
return;
}
loger.error(`会议密码校验-协议异常.`, rectObj);
loger.error(`课堂密码校验-协议异常.`, rectObj);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_PROTOCOL);
})
.catch(err => {
loger.error(`会议密码校验-异常.状态码:${err}`);
loger.error(`课堂密码校验-异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_JOIN_FAILED);
});
}
... ... @@ -199,7 +199,7 @@ class Sass extends Emiter {
});
}
// 获取会议基本详情------------------------------------------------------------------------------------
// 获取课堂基本详情------------------------------------------------------------------------------------
getClassDetail() {
let url = `http://${confInfo.portal}/3m/meeting/getClassH5.do?classNumber=${confInfo.classId}`;
loger.log('获取Class详情.', url);
... ... @@ -230,7 +230,7 @@ class Sass extends Emiter {
});
}
//获取课堂会议的完整信息--------------------------------------------------------------------------------
//获取课堂课堂的完整信息--------------------------------------------------------------------------------
getClassParam() {
/*
参数 (application/x-www-form-urlencoded):
... ... @@ -249,9 +249,9 @@ class Sass extends Emiter {
meetingNumber String 课堂号 对应的是classId
*/
var timestamp = new Date().getTime();
var authId = MD5(confInfo.classId + "" + timestamp);//课堂号+时间戳 的字符串,转成MD5
let url = `http://${confInfo.portal}/3m/api/meeting/detail.do?meetingNumber=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`;
loger.log('5.获取课堂会议的完整信息 ');
var authId = MD5(GlobalConfig.classId + "" + timestamp);//课堂号+时间戳 的字符串,转成MD5
let url = `http://${GlobalConfig.portal}/3m/api/meeting/detail.do?meetingNumber=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
loger.log('5.获取课堂课堂的完整信息 ');
console.log(url);
fetch(url, {
timeout: 5000
... ... @@ -260,7 +260,7 @@ class Sass extends Emiter {
if (ret.ok) {
return ret.json();
} else {
loger.error(`获取课堂会议的完整信息-网络异常.状态码:${ret.status}`);
loger.error(`获取课堂课堂的完整信息-网络异常.状态码:${ret.status}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
throw '';
... ... @@ -268,15 +268,15 @@ class Sass extends Emiter {
})
.then(ret => {
if (ret.code === 0) {
loger.log('获取课堂会议的完整信息完成');
loger.log('获取课堂课堂的完整信息完成');
this._emit(Sass.CLASS_GET_CLASS_PARAM, ret);
} else {
loger.warn('获取课堂会议的完整信息 失败.');
loger.warn('获取课堂课堂的完整信息 失败.');
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
}
})
.catch(err => {
loger.error(`获取课堂会议的完整信息异常.状态码:${err}`);
loger.error(`获取课堂课堂的完整信息异常.状态码:${err}`);
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_GET_CLASS_PARAML);
});
}
... ... @@ -294,6 +294,10 @@ class Sass extends Emiter {
0 成功, 1 验证信息错误
*/
sassDeleteDocument(_param) {
if(GlobalConfig.isRecordPlayBack){
loger.log('录制回放中,能删除文档');
return;
}
var timestamp = new Date().getTime();
var authId = MD5(_param.docId + "" + _param.classId + "" + timestamp);// docId+classId+timestamp的字符串,转成MD5
let url = `http://${confInfo.portal}/3m/api/document/deleteRelation.do?docId=${_param.docId}&classId=${confInfo.classId}&timestamp=${timestamp}&authId=${authId}`;
... ... @@ -340,6 +344,10 @@ class Sass extends Emiter {
code 0 成功 1 课堂号为空 2 无效的课堂号 3 验证信息错误*/
saveClassStatusInfo(_param) {
if(GlobalConfig.isRecordPlayBack){
loger.log('录制回放中,不需要保存课堂信息');
return;
}
//{"classStatusInfo":classStatusInfo}
var timestamp = new Date().getTime();
var authId = MD5(confInfo.classId + "" + timestamp);// (classId+timestamp)的字符串,转成MD5
... ... @@ -386,6 +394,10 @@ class Sass extends Emiter {
//保存录制的信息,主要是录制文件的名称,必须和MCU录制的文件名相同
saveClassRecordContrlInfo(_param) {
if(GlobalConfig.isRecordPlayBack){
loger.log('录制回放中,不需要保存');
return;
}
loger.log('保存开始录制信息');
let key = "3mang123A";
let siteID = GlobalConfig.siteId;
... ... @@ -439,8 +451,8 @@ Sass.prototype.CLASS_GET_CLASS_PARAM = Sass.CLASS_GET_CLASS_PARAM = 'sass_class_
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.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';//保存录制会议信息
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';//保存录制课堂信息
export default new Sass;
... ...
... ... @@ -23,7 +23,7 @@ let tempMsIp="";
let tempMsPort="";
let msDefaultPort=":1935";
let mcuDefaultPort="7777";
let speedTestPort = ':6666';//测速端口统一
let speedTestPort = ':5555';//测速端口统一
let checkMcuIpGroup =[];//储存MCU需要查询的ip数组
let checkMsIpGroup =[];//储存MCU需要查询的ip数组
... ...
... ... @@ -15,367 +15,394 @@
import pdu from 'pdus';
import Emiter from 'Emiter';
import mcu from 'mcu';
import McuObj from 'mcu';
import Loger from 'Loger';
import MessageTypes from 'MessageTypes';
import ApeConsts from './ApeConsts';
import ArrayBufferUtil from 'libs/ArrayBufferUtil';
import PduConsts from 'pdus/PduConsts';
import GlobalConfig from 'GlobalConfig';
import RecordPlayBackParse from 'RecordPlayBackParse';
// 日志对象
const loger = Loger.getLoger('Ape');
export default class Ape extends Emiter {
constructor(
session_id,
session_name,
session_tag
) {
super();
this._session_id = session_id;
this._channel_id = session_id; // session_id === channel_id
this._session_name = session_name;
this._session_tag = session_tag;
this._session_channels = {};
this._adapter_pdu = new pdu['RCAdapterPdu'];
this._classInfo = null;
this._rCArrayBufferUtil = ArrayBufferUtil;
this._apeDelayed = false;
this._apeDelayedMsgs = [];
this._apeDelayedTimer = 0;
//Ape 通用消息处理
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
this.on(pdu.RCPDU_CHANNEL_JOIN_RESPONSE, this._joinChannelHandler.bind(this));
this.on(pdu.RCPDU_REG_ADAPTER, this._pduMessageHandler.bind(this));
//先收到onJoinSessionHandlerSuccess 后收到 onJoinChannelHandlerSuccess
// 监听底层MCU会议
this.mcu = mcu;
this.mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
this.mcu.registerApe(this);
}
regResponsePduHandler() {
}
stopApe(){
loger.log("stopApe==============================");
}
// 消息处理
_pduMessageHandler(regBuffer) {
//loger.log("RCPDU_REG_ADAPTER==============================");
if (this._apeDelayed) {
// this._apeDelayedMsgs.push(regBuffer);
// this._apeDelayedStart();
setTimeout(() => {
this._pduRegAdapterHandler(regBuffer);
},GlobalConfig.mcuDelay|| 2000);
return;
constructor(session_id,
session_name,
session_tag) {
super();
this._session_id = session_id;
this._channel_id = session_id; // session_id === channel_id
this._session_name = session_name;
this._session_tag = session_tag;
this._session_channels = {};
this._adapter_pdu = new pdu['RCAdapterPdu'];
this._classInfo = null;
this._rCArrayBufferUtil = ArrayBufferUtil;
this._apeDelayed = false;
this._apeDelayedMsgs = [];
this._apeDelayedTimer = 0;
//Ape 通用消息处理
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
this.on(pdu.RCPDU_CHANNEL_JOIN_RESPONSE, this._joinChannelHandler.bind(this));
this.on(pdu.RCPDU_REG_ADAPTER, this._pduMessageHandler.bind(this));
//先收到onJoinSessionHandlerSuccess 后收到 onJoinChannelHandlerSuccess
loger.log("APE-->registerApe");
// 监听底层MCU课堂
this.mcu = McuObj;
this.mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuConferenceJoinSuccessHandler.bind(this));
this.mcu.registerApe(this);
//录制回放
this.recordPlayBackParse = RecordPlayBackParse;
this.recordPlayBackParse.on(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, this._joinRecordPlaybackSuccessHandler.bind(this));
this.recordPlayBackParse.registerApe(this);
}
this._pduRegAdapterHandler(regBuffer);
}
// _apeDelayedStart() {
// if (this._apeDelayed && !this._apeDelayedTimer) {
// this._apeDelayedTimer = setInterval(this._delayedMsgHandler.bind(this), this._classInfo['mcuDelay'] || 10000);
// }
// }
// _apeDelayedStop() {
// clearInterval(this._apeDelayedTimer);
// this._apeDelayedTimer = 0;
// }
// // 延迟消息处理
// _delayedMsgHandler() {
// if (this._apeDelayedMsgs.length) {
// this._pduRegAdapterHandler(this._apeDelayedMsgs.pop());
// if (!this._apeDelayedMsgs.length) this._apeDelayedStop();
// }
// }
// 数据同步处理
_pduRegAdapterHandler(regBuffer) {
let regPdu = pdu['RCAdapterPdu'].decode(regBuffer);
let regItems = regPdu.item;
let regItemSize = regItems.length;
//loger.log(this._session_name + '数据同步消息');
loger.log(this._session_name + '数据同步消息.同步条数', regItemSize);
//console.log(regPdu);
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);
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;
loger.log('REG OBJECT EVENT ->', pdu.id2type(sub_type));
switch (sub_type) {
case pdu.RCPDU_REG_ROSTER_INSERT_PDU:
let rosterInsertData = pdu['RCRegstryRosterInsertItemPdu'].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);
this.rosterInsertHandler(recordId, recordData);
}
break;
case pdu.RCPDU_REG_ROSTER_DELETE_PDU:
let rosterDelData = pdu['RCRegistryRosterDeleteItemPdu'].decode(user_data);
this.rosterDelHandler(rosterDelData.nodeId);
break;
case pdu.RCPDU_REG_ROSTER_UPDATE_PDU:
let rosterUpdateData = pdu['RCRegistryRosterUpdateItemPdu'].decode(user_data);
let rosterUpdateItems = rosterUpdateData.items;
let rosterUpdateItemsLen = rosterUpdateItems.length;
for (let i = 0; i < rosterUpdateItemsLen; ++i) {
let node = rosterUpdateItems[i];
let nodeId = node.nodeId;
let nodeData = pdu['RCNodeInfoRecordPdu'].decode(node.nodeData);
this.rosterUpdateHandler(nodeId, nodeData);
}
break;
case pdu.RCPDU_REG_TABLE_INSERT_PDU:
let tableInsertData = pdu['RCRegistryTableInsertItemPdu'].decode(user_data);
let tableInsertItems = tableInsertData.items;
let tableInsertItemsLen = tableInsertItems.length;
for (let i = 0; i < tableInsertItemsLen; ++i) {
let insertItem = tableInsertItems[i];
//loger.log("insertItem",insertItem);
this.tableInsertHandler(insertItem.owner, insertItem.itemIdx, insertItem.itemData);
regResponsePduHandler() {
}
//停止APE一切操作
stopApe() {
loger.log("stopApe==============================");
}
// 消息处理
_pduMessageHandler(regBuffer) {
//loger.log("RCPDU_REG_ADAPTER==============================");
if (this._apeDelayed) {
// this._apeDelayedMsgs.push(regBuffer);
// this._apeDelayedStart();
setTimeout(() => {
this._pduRegAdapterHandler(regBuffer);
}, GlobalConfig.mcuDelay || 2000);
return;
}
break;
case pdu.RCPDU_REG_TABLE_DELETE_PDU:
let tableDeleteData = pdu['RCRegistryTableDeleteItemPdu'].decode(user_data);
//console.log("tableDeleteData",object_id,tableDeleteData);
this.tableDeleteHandler(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;
loger.log("RCRegistryTableUpdateItemPdu "+tableUpdateItemsLen);
console.log(tableUpdateData);
for (let i = 0; i < tableUpdateItemsLen; ++i) {
let tableItem = tableUpdateItems[i];
this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData);
this._pduRegAdapterHandler(regBuffer);
}
// _apeDelayedStart() {
// if (this._apeDelayed && !this._apeDelayedTimer) {
// this._apeDelayedTimer = setInterval(this._delayedMsgHandler.bind(this), this._classInfo['mcuDelay'] || 10000);
// }
// }
// _apeDelayedStop() {
// clearInterval(this._apeDelayedTimer);
// this._apeDelayedTimer = 0;
// }
// // 延迟消息处理
// _delayedMsgHandler() {
// if (this._apeDelayedMsgs.length) {
// this._pduRegAdapterHandler(this._apeDelayedMsgs.pop());
// if (!this._apeDelayedMsgs.length) this._apeDelayedStop();
// }
// }
// 数据同步处理
_pduRegAdapterHandler(regBuffer) {
let regPdu = pdu['RCAdapterPdu'].decode(regBuffer);
let regItems = regPdu.item;
let regItemSize = regItems.length;
//loger.log(this._session_name + '数据同步消息');
loger.log(this._session_name + '数据同步消息.同步条数', regItemSize);
//console.log(regPdu);
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);
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;
loger.log('REG OBJECT EVENT ->', pdu.id2type(sub_type));
switch (sub_type) {
case pdu.RCPDU_REG_ROSTER_INSERT_PDU:
let rosterInsertData = pdu['RCRegstryRosterInsertItemPdu'].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);
this.rosterInsertHandler(recordId, recordData);
}
break;
case pdu.RCPDU_REG_ROSTER_DELETE_PDU:
let rosterDelData = pdu['RCRegistryRosterDeleteItemPdu'].decode(user_data);
this.rosterDelHandler(rosterDelData.nodeId);
break;
case pdu.RCPDU_REG_ROSTER_UPDATE_PDU:
let rosterUpdateData = pdu['RCRegistryRosterUpdateItemPdu'].decode(user_data);
let rosterUpdateItems = rosterUpdateData.items;
let rosterUpdateItemsLen = rosterUpdateItems.length;
for (let i = 0; i < rosterUpdateItemsLen; ++i) {
let node = rosterUpdateItems[i];
let nodeId = node.nodeId;
let nodeData = pdu['RCNodeInfoRecordPdu'].decode(node.nodeData);
this.rosterUpdateHandler(nodeId, nodeData);
}
break;
case pdu.RCPDU_REG_TABLE_INSERT_PDU:
let tableInsertData = pdu['RCRegistryTableInsertItemPdu'].decode(user_data);
let tableInsertItems = tableInsertData.items;
let tableInsertItemsLen = tableInsertItems.length;
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);
this.tableDeleteHandler(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;
loger.log("RCRegistryTableUpdateItemPdu " + tableUpdateItemsLen);
console.log(tableUpdateData);
for (let i = 0; i < tableUpdateItemsLen; ++i) {
let tableItem = tableUpdateItems[i];
this.tableUpdateHandler(tableItem.owner, tableItem.itemIdx, tableItem.itemData);
}
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;
}
}
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;
}
}
}
rosterInsertHandler(recordId, recordData) {
loger.warn(this._session_name + ' rosterInsertHandler 应有子类具体覆盖处理.');
}
rosterUpdateHandler(nodeId, nodeData) {
loger.warn(this._session_name + ' rosterUpdateHandler 应有子类具体覆盖处理.');
}
rosterDelHandler(recordData) {
loger.warn(this._session_name + ' rosterDelHandler 应有子类具体覆盖处理.');
}
tableInsertHandler(tableId, record) {
loger.warn(this._session_name + ' tableInsertHandler 应有子类具体覆盖处理.');
}
tableUpdateHandler(ownerId, recordId, recordData) {
loger.warn(this._session_name + ' tableUpdateHandler 应有子类具体覆盖处理.');
}
tableDeleteHandler(tableId, record) {
loger.warn(this._session_name + ' tableDelHandler 应有子类具体覆盖处理.');
}
onJoinChannelHandlerSuccess(){
loger.warn(this._session_name + ' onJoinChannelHandlerSuccess 应有子类具体覆盖处理.');
}
onJoinSessionHandlerSuccess(){
loger.warn(this._session_name + ' onJoinSessionHandlerSuccess 应有子类具体覆盖处理.');
}
// 加入Session处理
_joinSessionHandler(data) {
loger.log(this._session_name, ' -> 加入Session');
this.onJoinSessionHandlerSuccess();
}
// 加入Channel处理
_joinChannelHandler(data) {
let joinedChannel = pdu['RCChannelJoinResponsePdu'].decode(data);
if (joinedChannel.result === pdu.RET_SUCCESS) {
loger.log(this._session_name, ' -> 加入Channel成功. ChannelId', joinedChannel.requestedChannelId);
this._session_channels[joinedChannel.requestedChannelId] = ApeConsts.CJS_JOINNED;
this.onJoinChannelHandlerSuccess();
} else {
loger.log(this._session_name, ' -> 加入Channel失败.', joinedChannel);
rosterInsertHandler(recordId, recordData) {
loger.warn(this._session_name + ' rosterInsertHandler 应有子类具体覆盖处理.');
}
rosterUpdateHandler(nodeId, nodeData) {
loger.warn(this._session_name + ' rosterUpdateHandler 应有子类具体覆盖处理.');
}
rosterDelHandler(recordData) {
loger.warn(this._session_name + ' rosterDelHandler 应有子类具体覆盖处理.');
}
tableInsertHandler(tableId, record) {
loger.warn(this._session_name + ' tableInsertHandler 应有子类具体覆盖处理.');
}
tableUpdateHandler(ownerId, recordId, recordData) {
loger.warn(this._session_name + ' tableUpdateHandler 应有子类具体覆盖处理.');
}
tableDeleteHandler(tableId, record) {
loger.warn(this._session_name + ' tableDelHandler 应有子类具体覆盖处理.');
}
onJoinChannelHandlerSuccess() {
loger.warn(this._session_name + ' onJoinChannelHandlerSuccess 应有子类具体覆盖处理.');
}
onJoinSessionHandlerSuccess() {
loger.warn(this._session_name + ' onJoinSessionHandlerSuccess 应有子类具体覆盖处理.');
}
// 加入Session处理
_joinSessionHandler(data) {
loger.log(this._session_name, ' -> 加入Session');
this.onJoinSessionHandlerSuccess();
}
// 加入Channel处理
_joinChannelHandler(data) {
let joinedChannel = pdu['RCChannelJoinResponsePdu'].decode(data);
if (joinedChannel.result === pdu.RET_SUCCESS) {
loger.log(this._session_name, ' -> 加入Channel成功. ChannelId', joinedChannel.requestedChannelId);
this._session_channels[joinedChannel.requestedChannelId] = ApeConsts.CJS_JOINNED;
this.onJoinChannelHandlerSuccess();
} else {
loger.log(this._session_name, ' -> 加入Channel失败.', joinedChannel);
}
}
}
// 依赖的会议创建完毕 - 发起Ape加入
_mcuConferenceJoinSuccessHandler(_data) {
loger.log('创建Ape->',
'SessionId',
this._session_id,
'SessionName',
this._session_name,
'SessionTag',
this._session_tag);
// 会议依赖底层会议信息
//this._classInfo = classInfo;
this._classInfo = GlobalConfig.getClassInfo();
var joinSessionPdu = new pdu['RCSessionJoinRequestPdu'];
joinSessionPdu.id = this._session_id;
joinSessionPdu.name = this._session_name;
joinSessionPdu.tag = this._session_tag;
joinSessionPdu.sessionData = this._adapter_pdu.toArrayBuffer();
this.sendUniform(joinSessionPdu, true);
var joinChannelPdu = new pdu['RCChannelJoinRequestPdu'];
joinChannelPdu.initiator = this.mcu.classInfo.nodeId;
joinChannelPdu.channelId = this._session_id;
this.send(joinChannelPdu);
}
// 注册Key对象
registerKey(id, name, tag, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_KEY;
// pack register key pdus
let registerKeyPdu = new pdu['RCRegistryRegisterKeyPdu'];
registerKeyPdu.id = id;
registerKeyPdu.name = name;
registerKeyPdu.tag = tag;
if (user_data.length) {
registerKeyPdu.userData = user_data;
// 依赖的课堂创建完毕 - 发起Ape加入
_mcuConferenceJoinSuccessHandler(_data) {
loger.log('创建Ape->',
'SessionId',
this._session_id,
'SessionName',
this._session_name,
'SessionTag',
this._session_tag);
// 课堂依赖底层课堂信息
//this._classInfo = classInfo;
this._classInfo = GlobalConfig.getClassInfo();
var joinSessionPdu = new pdu['RCSessionJoinRequestPdu'];
joinSessionPdu.id = this._session_id;
joinSessionPdu.name = this._session_name;
joinSessionPdu.tag = this._session_tag;
joinSessionPdu.sessionData = this._adapter_pdu.toArrayBuffer();
this.sendUniform(joinSessionPdu, true);
var joinChannelPdu = new pdu['RCChannelJoinRequestPdu'];
joinChannelPdu.initiator = this.mcu.classInfo.nodeId;
joinChannelPdu.channelId = this._session_id;
this.send(joinChannelPdu);
}
adapterItemPdu.itemData = registerKeyPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
// 注册Object对象 等同于flash中的 RCRegistryOperator
registerObj(type, id, name, tag, owner, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_OBJ;
let registerObjPdu = new pdu['RCRegistryRegisterObjPdu'];
registerObjPdu.type = type;
registerObjPdu.objId = id;
registerObjPdu.name = name;
registerObjPdu.tag = tag;
if (owner) {
registerObjPdu.owner = owner;
// 依赖的录制回放创建完毕 - 发起Ape加入
_joinRecordPlaybackSuccessHandler(_data) {
loger.log('录制回放->Ape已经创建完毕->',
'SessionId',
this._session_id,
'SessionName',
this._session_name,
'SessionTag',
this._session_tag);
}
if (user_data.length) {
registerObjPdu.userData = user_data;
// 注册Key对象
registerKey(id, name, tag, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_KEY;
// pack register key pdus
let registerKeyPdu = new pdu['RCRegistryRegisterKeyPdu'];
registerKeyPdu.id = id;
registerKeyPdu.name = name;
registerKeyPdu.tag = tag;
if (user_data.length) {
registerKeyPdu.userData = user_data;
}
adapterItemPdu.itemData = registerKeyPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
adapterItemPdu.itemData = registerObjPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
send(appPdu) {
loger.log('Ape发送数据NORMAL PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
// 注册Object对象 等同于flash中的 RCRegistryOperator
registerObj(type, id, name, tag, owner, user_data) {
let adapterItemPdu = new pdu['RCAdapterItemPdu'];
adapterItemPdu.type = pdu.RCPDU_REG_REGISTER_OBJ;
let registerObjPdu = new pdu['RCRegistryRegisterObjPdu'];
registerObjPdu.type = type;
registerObjPdu.objId = id;
registerObjPdu.name = name;
registerObjPdu.tag = tag;
if (owner) {
registerObjPdu.owner = owner;
}
if (user_data.length) {
registerObjPdu.userData = user_data;
}
adapterItemPdu.itemData = registerObjPdu.toArrayBuffer();
this._adapter_pdu.item.push(adapterItemPdu);
}
let normalPdu = pdu.create_normal_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
this._channel_id,
true,
true,
PduConsts.DP_TOP,
this._classInfo.topNodeID,
PduConsts.SEG_ONCE
);
normalPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(normalPdu);
}
// 发送当前APE(session uniform包)
sendUniform(appPdu, top) {
loger.log('Ape发送数据UNIFORM PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
send(appPdu) {
loger.log('Ape发送数据NORMAL PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
let normalPdu = pdu.create_normal_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
this._channel_id,
true,
true,
PduConsts.DP_TOP,
this._classInfo.topNodeID,
PduConsts.SEG_ONCE
);
normalPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(normalPdu);
}
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
top ? this._classInfo.topNodeID : (appPdu.peer || 0),
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(uniformPdu);
}
sendChatUniform(appPdu, top) {
loger.log('Ape发送数据UNIFORM PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if(GlobalConfig.getCurrentStatus().code==0||GlobalConfig.getCurrentStatus().code==1){
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
// 发送当前APE(session uniform包)
sendUniform(appPdu, top) {
loger.log('Ape发送数据UNIFORM PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
top ? this._classInfo.topNodeID : (appPdu.peer || 0),
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(uniformPdu);
}
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
0,//flash中这个值设置为0
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(uniformPdu);
}
sendChatUniform(appPdu, top) {
loger.log('Ape发送数据UNIFORM PDU');
console.log(appPdu);
//loger.log('当前的状态============',GlobalConfig.getCurrentStatus().code);
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
}
let uniformPdu = pdu.create_uniform_pdu(
appPdu.type,
this._classInfo.nodeId,
this._classInfo.classId,
this._session_id,
top ? ApeConsts.BROADCAST_CHANNEL_ID : this._channel_id,
true,
PduConsts.DP_TOP,
0,//flash中这个值设置为0
PduConsts.SEG_ONCE
);
uniformPdu.data = appPdu.toArrayBuffer();
// Mcu发送
this.mcu.send(uniformPdu);
}
}
... ...
... ... @@ -11,7 +11,7 @@ export default function ApeConsts(id) {
ApeConsts.CLASS_STATUS_WAIT= 0;//课堂还未开始
ApeConsts.CLASS_STATUS_STARTED= 1;//直播中
ApeConsts.CLASS_STATUS_PAUSE= 2;//暂停
ApeConsts.CLASS_STATUS_CLOSE= 3;//结束//这个是点击结束会议,把所有人踢出课堂,然后把状态值还原为0*************
ApeConsts.CLASS_STATUS_CLOSE= 3;//结束//这个是点击结束课堂,把所有人踢出课堂,然后把状态值还原为0*************
ApeConsts.CLASS_STATUS_UPTATE= 4;//更新课堂状态信息
ApeConsts.CLASS_WAIT_START = "class.wait.start";//课堂还未开始
... ... @@ -22,7 +22,7 @@ ApeConsts.CLASS_PAUSING = "class.update";//更新当前的状态信息
//课堂控制
ApeConsts.CLASS_ACTION_CLOSE_ALL=1;//所有人关闭会议
ApeConsts.CLASS_ACTION_CLOSE_ALL=1;//所有人关闭课堂
//课堂类型
ApeConsts.CLASS_TYPE_INTERACT= 1; // 互动课堂,通过MS转发音视频,不能进行H5观看
... ...
// //////////////////////////////////////////////////////////////////////////////
//会议控制APE
//课堂控制APE
// //////////////////////////////////////////////////////////////////////////////
import Ape from './Ape';
... ... @@ -56,11 +56,11 @@ class ConferApe extends Ape {
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
this.on(pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
this.on(pdu.RCPDU_SEND_CONFERENCE_DATA_REQUEST, this.conferMsgComingHandler.bind(this));//这个是课堂消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
this.on(pdu.RCPDU_CONFERENCE_RECORD_REQUEST, this.onSendConferRecordRequestHandler.bind(this));//发送录制和停止录制消息
}
//加入会议
//加入课堂
_joinSessionHandler(_data) {
let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
loger.log("_joinSessionHandler nodeInfoRecordPdu=");
... ... @@ -98,7 +98,7 @@ class ConferApe extends Ape {
sendConferMsg(_messageInfo) {
if (this._classInfo == null || EngineUtils.isEmptyObject(this._classInfo)) {
loger.log('不能发送会议消息.McuClient还未初始化数据!');
loger.log('不能发送课堂消息.McuClient还未初始化数据!');
if (GlobalConfig.getCurrentStatus().code == 0 || GlobalConfig.getCurrentStatus().code == 1) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_SEND_FAILED_NO_JOIN);
return;
... ... @@ -107,7 +107,7 @@ class ConferApe extends Ape {
}
// to, message
loger.log('发送会议消息.', _messageInfo);
loger.log('发送课堂消息.', _messageInfo);
/* message RCConferenceSendDataRequestPdu {
optional uint32 initiator = 1;
... ... @@ -129,11 +129,11 @@ class ConferApe extends Ape {
// if (!(conferSendPdu.isPublic || 0 === conferSendPdu.peer)) {
if (!conferSendPdu.isPublic && 0 != conferSendPdu.peer) {
//发送给制定的人
loger.log('发送私聊会议消息.');
loger.log('发送私聊课堂消息.');
this.send(conferSendPdu);
} else {
//发送给所有人
loger.log('发送公聊会议消息.');
loger.log('发送公聊课堂消息.');
this.sendChatUniform(conferSendPdu);
}
}
... ... @@ -182,7 +182,7 @@ class ConferApe extends Ape {
GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
this.sendConferRecordMsg({"recordStatus": true});
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
this._emit(MessageTypes.CLASS_RECORD_START);//会议开始录制
this._emit(MessageTypes.CLASS_RECORD_START);//课堂开始录制
}
}
... ... @@ -198,7 +198,7 @@ class ConferApe extends Ape {
}
//主动离开会议,发送通知到服务器
//主动离开课堂,发送通知到服务器
leaveClass() {
let nodeInfoRecordPdu = this.mcu.mcuClassInfo.self;
let userDataPdu = new pdu['RCNodeInfoUserDataPdu'];
... ... @@ -264,9 +264,9 @@ class ConferApe extends Ape {
GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_STARTED;
//开始录制
this.startRecord();
//会议状态改变
//课堂状态改变
this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
//同步会议状态
//同步课堂状态
this.sendUpdaterClassStatusInfo({"actionType": 1});
//开始计时
... ... @@ -302,11 +302,11 @@ class ConferApe extends Ape {
this.stopTimerCounter();
this.restorClass();
//把所有人都踢出课堂
this.sendConferMsg({"to": 0, "message": "所有人退出会议", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL});
this.sendConferMsg({"to": 0, "message": "所有人退出课堂", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL});
}
//更新会议信息
//更新课堂信息
sendUpdaterClassStatusInfo(_param) {
loger.log('sendUpdaterClassStatusInfo');
if (_param == null || EngineUtils.isEmptyObject(_param)) {
... ... @@ -354,7 +354,7 @@ class ConferApe extends Ape {
adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
adapterPdu.item.push(adapterItemPdu);
console.log("会议发送更新数据============");
console.log("课堂发送更新数据============");
this.sendUniform(adapterPdu, true);
}
... ... @@ -364,7 +364,7 @@ class ConferApe extends Ape {
onJoinChannelHandlerSuccess() {
loger.log('ConferApe.onJoinChannelHandlerSuccess', GlobalConfig.classStatus);
this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1);
//如果当前会议正在进行中,开启计时器
//如果当前课堂正在进行中,开启计时器
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
//开始计时
this.startTimerCounter();
... ... @@ -416,11 +416,11 @@ class ConferApe extends Ape {
loger.log('tableUpdateHandler');
console.log(model);
//处理会议更新的信息
//处理课堂更新的信息
if (model && model.classStatusInfo) {
GlobalConfig.setClassStatusInfo(model.classStatusInfo);
}
//通知应用层更新会议状态
//通知应用层更新课堂状态
this._emit(MessageTypes.CLASS_UPTATE_STATUS, GlobalConfig.classStatusInfo);
//如果MCU已经断开连接,停止计时器
... ... @@ -431,7 +431,7 @@ class ConferApe extends Ape {
}
if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
//如果会议在进行中,开始计时器
//如果课堂在进行中,开始计时器
this.startTimerCounter();
} else {
//停止计时
... ... @@ -460,7 +460,7 @@ class ConferApe extends Ape {
switch (chatMsg.actionType) {
case ApeConsts.CLASS_ACTION_CLOSE_ALL:
loger.log(chatMsg.message);
//收到会议关闭,所有人都退出,执行自己关闭的流程
//收到课堂关闭,所有人都退出,执行自己关闭的流程
this._emit(MessageTypes.CLASS_EXIT);
break;
default:
... ... @@ -596,7 +596,7 @@ class ConferApe extends Ape {
///////数据的封包和解包/////////////////////////////////////////
packPdu(_param, _itemIdx) {
loger.log("会议===packPdu ");
loger.log("课堂===packPdu ");
//验证坐标点集合数组是否合法
if (_param == null || _itemIdx == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
... ... @@ -644,7 +644,7 @@ class ConferApe extends Ape {
}
unPackPdu(owner, itemIdx, itemData) {
loger.log("会议===unPackPdu ");
loger.log("课堂===unPackPdu ");
if (owner == null || itemIdx == null || itemData == null) {
this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
return null;
... ... @@ -654,7 +654,7 @@ class ConferApe extends Ape {
let modelPdu = pdu['RCClassSendDataModelPdu'].decode(itemData);
return modelPdu;
} catch (err) {
loger.log("会议收到数据 unPackPdu Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message);
loger.log("课堂收到数据 unPackPdu Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message);
}
return null;
}
... ...
... ... @@ -504,7 +504,7 @@ class DocApe extends Ape {
docModelPdu.pageNum = _param.pageNum||1;
docModelPdu.fileType=_param.fileType||"";
docModelPdu.creatUserId=_param.creatUserId||"0";
docModelPdu.url =_param.url||"";//"http://101.200.150.192/DocSharing/data/h5test/20170206-171100025/7e9c4178cac1133e0dd9d5b583439122.jpg";
docModelPdu.url ="";//这个地址没用到,数据太长占用资源 暂停使用//"http://101.200.150.192/DocSharing/data/h5test/20170206-171100025/7e9c4178cac1133e0dd9d5b583439122.jpg";
docModelPdu.relativeUrl=_param.relativeUrl||"";//"/DocSharing/data/h5test/20170206-171100025/7e9c4178cac1133e0dd9d5b583439122.jpg";
docModelPdu.curV=_param.curV||0;
docModelPdu.curH=_param.curH||0;
... ...
... ... @@ -52,7 +52,7 @@ class WhiteBoardApe extends Ape {
// ape listeners
this.on(pdu.RCPDU_SESSION_JOIN_RESPONSE, this._joinSessionHandler.bind(this));
//this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.whiteboardMsgComingHandler.bind(this));//这个是会议消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
//this.on(pdu.RCPDU_CONFERENCE_SEND_DATA_REQUEST, this.whiteboardMsgComingHandler.bind(this));//这个是课堂消息类型,flash里在使用这里不再使用,各个模块的消息由模块自己来处理
}
_joinSessionHandler(_data) {
... ...
/*
bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
Backing buffer: ArrayBuffer, Accessor: Uint8Array
Released under the Apache License, Version 2.0
see: https://github.com/dcodeIO/bytebuffer.js for details
*/
(function(k,m){if("function"===typeof define&&define.amd)define(["long"],m);else if("function"===typeof require&&"object"===typeof module&&module&&module.exports){var r=module,s;try{s=require("long")}catch(u){}s=m(s);r.exports=s}else(k.dcodeIO=k.dcodeIO||{}).ByteBuffer=m(k.dcodeIO.Long)})(this,function(k){function m(a){var b=0;return function(){return b<a.length?a.charCodeAt(b++):null}}function r(){var a=[],b=[];return function(){if(0===arguments.length)return b.join("")+w.apply(String,a);1024<a.length+
arguments.length&&(b.push(w.apply(String,a)),a.length=0);Array.prototype.push.apply(a,arguments)}}function s(a,b,c,d,f){var l;l=8*f-d-1;var g=(1<<l)-1,e=g>>1,h=-7;f=c?f-1:0;var k=c?-1:1,p=a[b+f];f+=k;c=p&(1<<-h)-1;p>>=-h;for(h+=l;0<h;c=256*c+a[b+f],f+=k,h-=8);l=c&(1<<-h)-1;c>>=-h;for(h+=d;0<h;l=256*l+a[b+f],f+=k,h-=8);if(0===c)c=1-e;else{if(c===g)return l?NaN:Infinity*(p?-1:1);l+=Math.pow(2,d);c-=e}return(p?-1:1)*l*Math.pow(2,c-d)}function u(a,b,c,d,f,l){var g,e=8*l-f-1,h=(1<<e)-1,k=h>>1,p=23===f?
Math.pow(2,-24)-Math.pow(2,-77):0;l=d?0:l-1;var m=d?1:-1,n=0>b||0===b&&0>1/b?1:0;b=Math.abs(b);isNaN(b)||Infinity===b?(b=isNaN(b)?1:0,d=h):(d=Math.floor(Math.log(b)/Math.LN2),1>b*(g=Math.pow(2,-d))&&(d--,g*=2),b=1<=d+k?b+p/g:b+p*Math.pow(2,1-k),2<=b*g&&(d++,g/=2),d+k>=h?(b=0,d=h):1<=d+k?(b=(b*g-1)*Math.pow(2,f),d+=k):(b=b*Math.pow(2,k-1)*Math.pow(2,f),d=0));for(;8<=f;a[c+l]=b&255,l+=m,b/=256,f-=8);d=d<<f|b;for(e+=f;0<e;a[c+l]=d&255,l+=m,d/=256,e-=8);a[c+l-m]|=128*n}var h=function(a,b,c){"undefined"===
typeof a&&(a=h.DEFAULT_CAPACITY);"undefined"===typeof b&&(b=h.DEFAULT_ENDIAN);"undefined"===typeof c&&(c=h.DEFAULT_NOASSERT);if(!c){a|=0;if(0>a)throw RangeError("Illegal capacity");b=!!b;c=!!c}this.buffer=0===a?v:new ArrayBuffer(a);this.view=0===a?null:new Uint8Array(this.buffer);this.offset=0;this.markedOffset=-1;this.limit=a;this.littleEndian=b;this.noAssert=c};h.VERSION="5.0.1";h.LITTLE_ENDIAN=!0;h.BIG_ENDIAN=!1;h.DEFAULT_CAPACITY=16;h.DEFAULT_ENDIAN=h.BIG_ENDIAN;h.DEFAULT_NOASSERT=!1;h.Long=k||
null;var e=h.prototype;Object.defineProperty(e,"__isByteBuffer__",{value:!0,enumerable:!1,configurable:!1});var v=new ArrayBuffer(0),w=String.fromCharCode;h.accessor=function(){return Uint8Array};h.allocate=function(a,b,c){return new h(a,b,c)};h.concat=function(a,b,c,d){if("boolean"===typeof b||"string"!==typeof b)d=c,c=b,b=void 0;for(var f=0,l=0,g=a.length,e;l<g;++l)h.isByteBuffer(a[l])||(a[l]=h.wrap(a[l],b)),e=a[l].limit-a[l].offset,0<e&&(f+=e);if(0===f)return new h(0,c,d);b=new h(f,c,d);for(l=
0;l<g;)c=a[l++],e=c.limit-c.offset,0>=e||(b.view.set(c.view.subarray(c.offset,c.limit),b.offset),b.offset+=e);b.limit=b.offset;b.offset=0;return b};h.isByteBuffer=function(a){return!0===(a&&a.__isByteBuffer__)};h.type=function(){return ArrayBuffer};h.wrap=function(a,b,c,d){"string"!==typeof b&&(d=c,c=b,b=void 0);if("string"===typeof a)switch("undefined"===typeof b&&(b="utf8"),b){case "base64":return h.fromBase64(a,c);case "hex":return h.fromHex(a,c);case "binary":return h.fromBinary(a,c);case "utf8":return h.fromUTF8(a,
c);case "debug":return h.fromDebug(a,c);default:throw Error("Unsupported encoding: "+b);}if(null===a||"object"!==typeof a)throw TypeError("Illegal buffer");if(h.isByteBuffer(a))return b=e.clone.call(a),b.markedOffset=-1,b;if(a instanceof Uint8Array)b=new h(0,c,d),0<a.length&&(b.buffer=a.buffer,b.offset=a.byteOffset,b.limit=a.byteOffset+a.byteLength,b.view=new Uint8Array(a.buffer));else if(a instanceof ArrayBuffer)b=new h(0,c,d),0<a.byteLength&&(b.buffer=a,b.offset=0,b.limit=a.byteLength,b.view=0<
a.byteLength?new Uint8Array(a):null);else if("[object Array]"===Object.prototype.toString.call(a))for(b=new h(a.length,c,d),b.limit=a.length,c=0;c<a.length;++c)b.view[c]=a[c];else throw TypeError("Illegal buffer");return b};e.writeBitSet=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if(!(a instanceof Array))throw TypeError("Illegal BitSet: Not an array");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>
this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d=b,f=a.length,e=f>>3,g=0,h;for(b+=this.writeVarint32(f,b);e--;)h=!!a[g++]&1|(!!a[g++]&1)<<1|(!!a[g++]&1)<<2|(!!a[g++]&1)<<3|(!!a[g++]&1)<<4|(!!a[g++]&1)<<5|(!!a[g++]&1)<<6|(!!a[g++]&1)<<7,this.writeByte(h,b++);if(g<f){for(h=e=0;g<f;)h|=(!!a[g++]&1)<<e++;this.writeByte(h,b++)}return c?(this.offset=b,this):b-d};e.readBitSet=function(a){var b="undefined"===typeof a;b&&(a=this.offset);var c=this.readVarint32(a),
d=c.value,f=d>>3,e=0,g=[];for(a+=c.length;f--;)c=this.readByte(a++),g[e++]=!!(c&1),g[e++]=!!(c&2),g[e++]=!!(c&4),g[e++]=!!(c&8),g[e++]=!!(c&16),g[e++]=!!(c&32),g[e++]=!!(c&64),g[e++]=!!(c&128);if(e<d)for(f=0,c=this.readByte(a++);e<d;)g[e++]=!!(c>>f++&1);b&&(this.offset=a);return g};e.readBytes=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+a>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
b+" (+"+a+") <= "+this.buffer.byteLength);}var d=this.slice(b,b+a);c&&(this.offset+=a);return d};e.writeBytes=e.append;e.writeInt8=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);
}b+=1;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);this.view[b-1]=a;c&&(this.offset+=1);return this};e.writeByte=e.writeInt8;e.readInt8=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}a=this.view[a];128===(a&128)&&(a=-(255-a+1));b&&(this.offset+=
1);return a};e.readByte=e.readInt8;e.writeUint8=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=1;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);
this.view[b-1]=a;c&&(this.offset+=1);return this};e.writeUInt8=e.writeUint8;e.readUint8=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}a=this.view[a];b&&(this.offset+=1);return a};e.readUInt8=e.readUint8;e.writeInt16=function(a,b){var c="undefined"===typeof b;
c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=2;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=2;this.littleEndian?(this.view[b+1]=(a&65280)>>>8,this.view[b]=a&255):(this.view[b]=(a&65280)>>>
8,this.view[b+1]=a&255);c&&(this.offset+=2);return this};e.writeShort=e.writeInt16;e.readInt16=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+2) <= "+this.buffer.byteLength);}var c=0;this.littleEndian?(c=this.view[a],c|=this.view[a+1]<<8):(c=this.view[a]<<8,c|=this.view[a+1]);32768===(c&32768)&&
(c=-(65535-c+1));b&&(this.offset+=2);return c};e.readShort=e.readInt16;e.writeUint16=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=2;var d=this.buffer.byteLength;
b>d&&this.resize((d*=2)>b?d:b);b-=2;this.littleEndian?(this.view[b+1]=(a&65280)>>>8,this.view[b]=a&255):(this.view[b]=(a&65280)>>>8,this.view[b+1]=a&255);c&&(this.offset+=2);return this};e.writeUInt16=e.writeUint16;e.readUint16=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+2) <= "+this.buffer.byteLength);
}var c=0;this.littleEndian?(c=this.view[a],c|=this.view[a+1]<<8):(c=this.view[a]<<8,c|=this.view[a+1]);b&&(this.offset+=2);return c};e.readUInt16=e.readUint16;e.writeInt32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
b+" (+0) <= "+this.buffer.byteLength);}b+=4;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=4;this.littleEndian?(this.view[b+3]=a>>>24&255,this.view[b+2]=a>>>16&255,this.view[b+1]=a>>>8&255,this.view[b]=a&255):(this.view[b]=a>>>24&255,this.view[b+1]=a>>>16&255,this.view[b+2]=a>>>8&255,this.view[b+3]=a&255);c&&(this.offset+=4);return this};e.writeInt=e.writeInt32;e.readInt32=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%
1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}var c=0;this.littleEndian?(c=this.view[a+2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0):(c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+3],c+=this.view[a]<<24>>>0);b&&(this.offset+=4);return c|0};e.readInt=e.readInt32;e.writeUint32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);
if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=4;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=4;this.littleEndian?(this.view[b+3]=a>>>24&255,this.view[b+2]=a>>>16&255,this.view[b+1]=a>>>8&255,this.view[b]=
a&255):(this.view[b]=a>>>24&255,this.view[b+1]=a>>>16&255,this.view[b+2]=a>>>8&255,this.view[b+3]=a&255);c&&(this.offset+=4);return this};e.writeUInt32=e.writeUint32;e.readUint32=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}var c=0;this.littleEndian?(c=this.view[a+
2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0):(c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+3],c+=this.view[a]<<24>>>0);b&&(this.offset+=4);return c};e.readUInt32=e.readUint32;k&&(e.writeInt64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"===typeof a)a=k.fromNumber(a);else if("string"===typeof a)a=k.fromString(a);else if(!(a&&a instanceof k))throw TypeError("Illegal value: "+a+" (not an integer or Long)");if("number"!==
typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}"number"===typeof a?a=k.fromNumber(a):"string"===typeof a&&(a=k.fromString(a));b+=8;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=8;var d=a.low,f=a.high;this.littleEndian?(this.view[b+3]=d>>>24&255,this.view[b+2]=d>>>16&255,this.view[b+1]=d>>>8&255,this.view[b]=d&255,b+=4,this.view[b+3]=
f>>>24&255,this.view[b+2]=f>>>16&255,this.view[b+1]=f>>>8&255,this.view[b]=f&255):(this.view[b]=f>>>24&255,this.view[b+1]=f>>>16&255,this.view[b+2]=f>>>8&255,this.view[b+3]=f&255,b+=4,this.view[b]=d>>>24&255,this.view[b+1]=d>>>16&255,this.view[b+2]=d>>>8&255,this.view[b+3]=d&255);c&&(this.offset+=8);return this},e.writeLong=e.writeInt64,e.readInt64=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");
a>>>=0;if(0>a||a+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+8) <= "+this.buffer.byteLength);}var c=0,d=0;this.littleEndian?(c=this.view[a+2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0,a+=4,d=this.view[a+2]<<16,d|=this.view[a+1]<<8,d|=this.view[a],d+=this.view[a+3]<<24>>>0):(d=this.view[a+1]<<16,d|=this.view[a+2]<<8,d|=this.view[a+3],d+=this.view[a]<<24>>>0,a+=4,c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+3],c+=this.view[a]<<24>>>0);
a=new k(c,d,!1);b&&(this.offset+=8);return a},e.readLong=e.readInt64,e.writeUint64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"===typeof a)a=k.fromNumber(a);else if("string"===typeof a)a=k.fromString(a);else if(!(a&&a instanceof k))throw TypeError("Illegal value: "+a+" (not an integer or Long)");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
b+" (+0) <= "+this.buffer.byteLength);}"number"===typeof a?a=k.fromNumber(a):"string"===typeof a&&(a=k.fromString(a));b+=8;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=8;var d=a.low,f=a.high;this.littleEndian?(this.view[b+3]=d>>>24&255,this.view[b+2]=d>>>16&255,this.view[b+1]=d>>>8&255,this.view[b]=d&255,b+=4,this.view[b+3]=f>>>24&255,this.view[b+2]=f>>>16&255,this.view[b+1]=f>>>8&255,this.view[b]=f&255):(this.view[b]=f>>>24&255,this.view[b+1]=f>>>16&255,this.view[b+2]=f>>>8&255,
this.view[b+3]=f&255,b+=4,this.view[b]=d>>>24&255,this.view[b+1]=d>>>16&255,this.view[b+2]=d>>>8&255,this.view[b+3]=d&255);c&&(this.offset+=8);return this},e.writeUInt64=e.writeUint64,e.readUint64=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+8) <= "+this.buffer.byteLength);}var c=0,d=0;this.littleEndian?
(c=this.view[a+2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0,a+=4,d=this.view[a+2]<<16,d|=this.view[a+1]<<8,d|=this.view[a],d+=this.view[a+3]<<24>>>0):(d=this.view[a+1]<<16,d|=this.view[a+2]<<8,d|=this.view[a+3],d+=this.view[a]<<24>>>0,a+=4,c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+3],c+=this.view[a]<<24>>>0);a=new k(c,d,!0);b&&(this.offset+=8);return a},e.readUInt64=e.readUint64);e.writeFloat32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==
typeof a)throw TypeError("Illegal value: "+a+" (not a number)");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=4;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);u(this.view,a,b-4,this.littleEndian,23,4);c&&(this.offset+=4);return this};e.writeFloat=e.writeFloat32;e.readFloat32=function(a){var b="undefined"===typeof a;b&&
(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}a=s(this.view,a,this.littleEndian,23,4);b&&(this.offset+=4);return a};e.readFloat=e.readFloat32;e.writeFloat64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a)throw TypeError("Illegal value: "+a+" (not a number)");
if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=8;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);u(this.view,a,b-8,this.littleEndian,52,8);c&&(this.offset+=8);return this};e.writeDouble=e.writeFloat64;e.readFloat64=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==
a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+8) <= "+this.buffer.byteLength);}a=s(this.view,a,this.littleEndian,52,8);b&&(this.offset+=8);return a};e.readDouble=e.readFloat64;h.MAX_VARINT32_BYTES=5;h.calculateVarint32=function(a){a>>>=0;return 128>a?1:16384>a?2:2097152>a?3:268435456>a?4:5};h.zigZagEncode32=function(a){return((a|=0)<<1^a>>31)>>>0};h.zigZagDecode32=function(a){return a>>>1^-(a&
1)|0};e.writeVarint32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d=h.calculateVarint32(a),f;b+=d;f=this.buffer.byteLength;b>f&&this.resize((f*=2)>b?f:b);
b-=d;for(a>>>=0;128<=a;)f=a&127|128,this.view[b++]=f,a>>>=7;this.view[b++]=a;return c?(this.offset=b,this):d};e.writeVarint32ZigZag=function(a,b){return this.writeVarint32(h.zigZagEncode32(a),b)};e.readVarint32=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);
}var c=0,d=0,f;do{if(!this.noAssert&&a>this.limit)throw a=Error("Truncated"),a.truncated=!0,a;f=this.view[a++];5>c&&(d|=(f&127)<<7*c);++c}while(0!==(f&128));d|=0;return b?(this.offset=a,d):{value:d,length:c}};e.readVarint32ZigZag=function(a){a=this.readVarint32(a);"object"===typeof a?a.value=h.zigZagDecode32(a.value):a=h.zigZagDecode32(a);return a};k&&(h.MAX_VARINT64_BYTES=10,h.calculateVarint64=function(a){"number"===typeof a?a=k.fromNumber(a):"string"===typeof a&&(a=k.fromString(a));var b=a.toInt()>>>
0,c=a.shiftRightUnsigned(28).toInt()>>>0;a=a.shiftRightUnsigned(56).toInt()>>>0;return 0==a?0==c?16384>b?128>b?1:2:2097152>b?3:4:16384>c?128>c?5:6:2097152>c?7:8:128>a?9:10},h.zigZagEncode64=function(a){"number"===typeof a?a=k.fromNumber(a,!1):"string"===typeof a?a=k.fromString(a,!1):!1!==a.unsigned&&(a=a.toSigned());return a.shiftLeft(1).xor(a.shiftRight(63)).toUnsigned()},h.zigZagDecode64=function(a){"number"===typeof a?a=k.fromNumber(a,!1):"string"===typeof a?a=k.fromString(a,!1):!1!==a.unsigned&&
(a=a.toSigned());return a.shiftRightUnsigned(1).xor(a.and(k.ONE).toSigned().negate()).toSigned()},e.writeVarint64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"===typeof a)a=k.fromNumber(a);else if("string"===typeof a)a=k.fromString(a);else if(!(a&&a instanceof k))throw TypeError("Illegal value: "+a+" (not an integer or Long)");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
b+" (+0) <= "+this.buffer.byteLength);}"number"===typeof a?a=k.fromNumber(a,!1):"string"===typeof a?a=k.fromString(a,!1):!1!==a.unsigned&&(a=a.toSigned());var d=h.calculateVarint64(a),f=a.toInt()>>>0,e=a.shiftRightUnsigned(28).toInt()>>>0,g=a.shiftRightUnsigned(56).toInt()>>>0;b+=d;var t=this.buffer.byteLength;b>t&&this.resize((t*=2)>b?t:b);b-=d;switch(d){case 10:this.view[b+9]=g>>>7&1;case 9:this.view[b+8]=9!==d?g|128:g&127;case 8:this.view[b+7]=8!==d?e>>>21|128:e>>>21&127;case 7:this.view[b+6]=
7!==d?e>>>14|128:e>>>14&127;case 6:this.view[b+5]=6!==d?e>>>7|128:e>>>7&127;case 5:this.view[b+4]=5!==d?e|128:e&127;case 4:this.view[b+3]=4!==d?f>>>21|128:f>>>21&127;case 3:this.view[b+2]=3!==d?f>>>14|128:f>>>14&127;case 2:this.view[b+1]=2!==d?f>>>7|128:f>>>7&127;case 1:this.view[b]=1!==d?f|128:f&127}return c?(this.offset+=d,this):d},e.writeVarint64ZigZag=function(a,b){return this.writeVarint64(h.zigZagEncode64(a),b)},e.readVarint64=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==
typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}var c=a,d=0,f=0,e=0,g=0,g=this.view[a++],d=g&127;if(g&128&&(g=this.view[a++],d|=(g&127)<<7,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],d|=(g&127)<<14,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],d|=(g&127)<<21,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],
f=g&127,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],f|=(g&127)<<7,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],f|=(g&127)<<14,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],f|=(g&127)<<21,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],e=g&127,g&128||this.noAssert&&"undefined"===typeof g)&&(g=this.view[a++],e|=(g&127)<<7,g&128||this.noAssert&&"undefined"===typeof g))throw Error("Buffer overrun");d=k.fromBits(d|f<<28,f>>>4|
e<<24,!1);return b?(this.offset=a,d):{value:d,length:a-c}},e.readVarint64ZigZag=function(a){(a=this.readVarint64(a))&&a.value instanceof k?a.value=h.zigZagDecode64(a.value):a=h.zigZagDecode64(a);return a});e.writeCString=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);var d,f=a.length;if(!this.noAssert){if("string"!==typeof a)throw TypeError("Illegal str: Not a string");for(d=0;d<f;++d)if(0===a.charCodeAt(d))throw RangeError("Illegal str: Contains NULL-characters");if("number"!==typeof b||
0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}f=n.calculateUTF16asUTF8(m(a))[1];b+=f+1;d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=f+1;n.encodeUTF16toUTF8(m(a),function(a){this.view[b++]=a}.bind(this));this.view[b++]=0;return c?(this.offset=b,this):f};e.readCString=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==
typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}var c=a,d,f=-1;n.decodeUTF8toUTF16(function(){if(0===f)return null;if(a>=this.limit)throw RangeError("Illegal range: Truncated data, "+a+" < "+this.limit);f=this.view[a++];return 0===f?null:f}.bind(this),d=r(),!0);return b?(this.offset=a,d()):{string:d(),length:a-c}};e.writeIString=function(a,b){var c=
"undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("string"!==typeof a)throw TypeError("Illegal str: Not a string");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d=b,f;f=n.calculateUTF16asUTF8(m(a),this.noAssert)[1];b+=4+f;var e=this.buffer.byteLength;b>e&&this.resize((e*=2)>b?e:b);b-=4+f;this.littleEndian?(this.view[b+
3]=f>>>24&255,this.view[b+2]=f>>>16&255,this.view[b+1]=f>>>8&255,this.view[b]=f&255):(this.view[b]=f>>>24&255,this.view[b+1]=f>>>16&255,this.view[b+2]=f>>>8&255,this.view[b+3]=f&255);b+=4;n.encodeUTF16toUTF8(m(a),function(a){this.view[b++]=a}.bind(this));if(b!==d+4+f)throw RangeError("Illegal range: Truncated data, "+b+" == "+(b+4+f));return c?(this.offset=b,this):b-d};e.readIString=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+
a+" (not an integer)");a>>>=0;if(0>a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}var c=a,d=this.readUint32(a),d=this.readUTF8String(d,h.METRICS_BYTES,a+=4);a+=d.length;return b?(this.offset=a,d.string):{string:d.string,length:a-c}};h.METRICS_CHARS="c";h.METRICS_BYTES="b";e.writeUTF8String=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+
b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d,f=b;d=n.calculateUTF16asUTF8(m(a))[1];b+=d;var e=this.buffer.byteLength;b>e&&this.resize((e*=2)>b?e:b);b-=d;n.encodeUTF16toUTF8(m(a),function(a){this.view[b++]=a}.bind(this));return c?(this.offset=b,this):b-f};e.writeString=e.writeUTF8String;h.calculateUTF8Chars=function(a){return n.calculateUTF16asUTF8(m(a))[0]};h.calculateUTF8Bytes=function(a){return n.calculateUTF16asUTF8(m(a))[1]};
h.calculateString=h.calculateUTF8Bytes;e.readUTF8String=function(a,b,c){"number"===typeof b&&(c=b,b=void 0);var d="undefined"===typeof c;d&&(c=this.offset);"undefined"===typeof b&&(b=h.METRICS_CHARS);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal length: "+a+" (not an integer)");a|=0;if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+c+" (+0) <= "+
this.buffer.byteLength);}var f=0,e=c,g;if(b===h.METRICS_CHARS){g=r();n.decodeUTF8(function(){return f<a&&c<this.limit?this.view[c++]:null}.bind(this),function(a){++f;n.UTF8toUTF16(a,g)});if(f!==a)throw RangeError("Illegal range: Truncated data, "+f+" == "+a);return d?(this.offset=c,g()):{string:g(),length:c-e}}if(b===h.METRICS_BYTES){if(!this.noAssert){if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+a>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
c+" (+"+a+") <= "+this.buffer.byteLength);}var k=c+a;n.decodeUTF8toUTF16(function(){return c<k?this.view[c++]:null}.bind(this),g=r(),this.noAssert);if(c!==k)throw RangeError("Illegal range: Truncated data, "+c+" == "+k);return d?(this.offset=c,g()):{string:g(),length:c-e}}throw TypeError("Unsupported metrics: "+b);};e.readString=e.readUTF8String;e.writeVString=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("string"!==typeof a)throw TypeError("Illegal str: Not a string");
if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d=b,f,e;f=n.calculateUTF16asUTF8(m(a),this.noAssert)[1];e=h.calculateVarint32(f);b+=e+f;var g=this.buffer.byteLength;b>g&&this.resize((g*=2)>b?g:b);b-=e+f;b+=this.writeVarint32(f,b);n.encodeUTF16toUTF8(m(a),function(a){this.view[b++]=a}.bind(this));if(b!==d+f+e)throw RangeError("Illegal range: Truncated data, "+
b+" == "+(b+f+e));return c?(this.offset=b,this):b-d};e.readVString=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}var c=a,d=this.readVarint32(a),d=this.readUTF8String(d.value,h.METRICS_BYTES,a+=d.length);a+=d.length;return b?(this.offset=a,d.string):{string:d.string,
length:a-c}};e.append=function(a,b,c){if("number"===typeof b||"string"!==typeof b)c=b,b=void 0;var d="undefined"===typeof c;d&&(c=this.offset);if(!this.noAssert){if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+c+" (+0) <= "+this.buffer.byteLength);}a instanceof h||(a=h.wrap(a,b));b=a.limit-a.offset;if(0>=b)return this;c+=b;var f=this.buffer.byteLength;c>f&&this.resize((f*=2)>
c?f:c);c-=b;this.view.set(a.view.subarray(a.offset,a.limit),c);a.offset+=b;d&&(this.offset+=b);return this};e.appendTo=function(a,b){a.append(this,b);return this};e.assert=function(a){this.noAssert=!a;return this};e.capacity=function(){return this.buffer.byteLength};e.clear=function(){this.offset=0;this.limit=this.buffer.byteLength;this.markedOffset=-1;return this};e.clone=function(a){var b=new h(0,this.littleEndian,this.noAssert);a?(b.buffer=new ArrayBuffer(this.buffer.byteLength),b.view=new Uint8Array(b.buffer)):
(b.buffer=this.buffer,b.view=this.view);b.offset=this.offset;b.markedOffset=this.markedOffset;b.limit=this.limit;return b};e.compact=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+
b+" <= "+this.buffer.byteLength);}if(0===a&&b===this.buffer.byteLength)return this;var c=b-a;if(0===c)return this.buffer=v,this.view=null,0<=this.markedOffset&&(this.markedOffset-=a),this.limit=this.offset=0,this;var d=new ArrayBuffer(c),f=new Uint8Array(d);f.set(this.view.subarray(a,b));this.buffer=d;this.view=f;0<=this.markedOffset&&(this.markedOffset-=a);this.offset=0;this.limit=c;return this};e.copy=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==
typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}if(a===b)return new h(0,this.littleEndian,this.noAssert);var c=b-a,d=new h(c,this.littleEndian,this.noAssert);d.offset=0;d.limit=c;0<=d.markedOffset&&(d.markedOffset-=a);this.copyTo(d,0,a,b);return d};e.copyTo=function(a,
b,c,d){var f,e;if(!this.noAssert&&!h.isByteBuffer(a))throw TypeError("Illegal target: Not a ByteBuffer");b=(e="undefined"===typeof b)?a.offset:b|0;c=(f="undefined"===typeof c)?this.offset:c|0;d="undefined"===typeof d?this.limit:d|0;if(0>b||b>a.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+b+" <= "+a.buffer.byteLength);if(0>c||d>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+c+" <= "+this.buffer.byteLength);var g=d-c;if(0===g)return a;a.ensureCapacity(b+g);
a.view.set(this.view.subarray(c,d),b);f&&(this.offset+=g);e&&(a.offset+=g);return this};e.ensureCapacity=function(a){var b=this.buffer.byteLength;return b<a?this.resize((b*=2)>a?b:a):this};e.fill=function(a,b,c){var d="undefined"===typeof b;d&&(b=this.offset);"string"===typeof a&&0<a.length&&(a=a.charCodeAt(0));"undefined"===typeof b&&(b=this.offset);"undefined"===typeof c&&(c=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=
0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal begin: Not an integer");b>>>=0;if("number"!==typeof c||0!==c%1)throw TypeError("Illegal end: Not an integer");c>>>=0;if(0>b||b>c||c>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+b+" <= "+c+" <= "+this.buffer.byteLength);}if(b>=c)return this;for(;b<c;)this.view[b++]=a;d&&(this.offset=b);return this};e.flip=function(){this.limit=this.offset;this.offset=0;return this};e.mark=function(a){a="undefined"===typeof a?this.offset:a;
if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+0) <= "+this.buffer.byteLength);}this.markedOffset=a;return this};e.order=function(a){if(!this.noAssert&&"boolean"!==typeof a)throw TypeError("Illegal littleEndian: Not a boolean");this.littleEndian=!!a;return this};e.LE=function(a){this.littleEndian="undefined"!==typeof a?!!a:!0;return this};e.BE=function(a){this.littleEndian=
"undefined"!==typeof a?!a:!1;return this};e.prepend=function(a,b,c){if("number"===typeof b||"string"!==typeof b)c=b,b=void 0;var d="undefined"===typeof c;d&&(c=this.offset);if(!this.noAssert){if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+c+" (+0) <= "+this.buffer.byteLength);}a instanceof h||(a=h.wrap(a,b));b=a.limit-a.offset;if(0>=b)return this;var f=b-c;if(0<f){var e=new ArrayBuffer(this.buffer.byteLength+
f),g=new Uint8Array(e);g.set(this.view.subarray(c,this.buffer.byteLength),b);this.buffer=e;this.view=g;this.offset+=f;0<=this.markedOffset&&(this.markedOffset+=f);this.limit+=f;c+=f}else new Uint8Array(this.buffer);this.view.set(a.view.subarray(a.offset,a.limit),c-b);a.offset=a.limit;d&&(this.offset-=b);return this};e.prependTo=function(a,b){a.prepend(this,b);return this};e.printDebug=function(a){"function"!==typeof a&&(a=console.log.bind(console));a(this.toString()+"\n-------------------------------------------------------------------\n"+
this.toDebug(!0))};e.remaining=function(){return this.limit-this.offset};e.reset=function(){0<=this.markedOffset?(this.offset=this.markedOffset,this.markedOffset=-1):this.offset=0;return this};e.resize=function(a){if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal capacity: "+a+" (not an integer)");a|=0;if(0>a)throw RangeError("Illegal capacity: 0 <= "+a);}if(this.buffer.byteLength<a){a=new ArrayBuffer(a);var b=new Uint8Array(a);b.set(this.view);this.buffer=a;this.view=b}return this};
e.reverse=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}if(a===b)return this;Array.prototype.reverse.call(this.view.subarray(a,b));return this};
e.skip=function(a){if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal length: "+a+" (not an integer)");a|=0}var b=this.offset+a;if(!this.noAssert&&(0>b||b>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+a+" <= "+this.buffer.byteLength);this.offset=b;return this};e.slice=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");
a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}var c=this.clone();c.offset=a;c.limit=b;return c};e.toBuffer=function(a){var b=this.offset,c=this.limit;if(!this.noAssert){if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: Not an integer");b>>>=0;if("number"!==typeof c||0!==c%1)throw TypeError("Illegal limit: Not an integer");
c>>>=0;if(0>b||b>c||c>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+b+" <= "+c+" <= "+this.buffer.byteLength);}if(!a&&0===b&&c===this.buffer.byteLength)return this.buffer;if(b===c)return v;a=new ArrayBuffer(c-b);(new Uint8Array(a)).set((new Uint8Array(this.buffer)).subarray(b,c),0);return a};e.toArrayBuffer=e.toBuffer;e.toString=function(a,b,c){if("undefined"===typeof a)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+
")";"number"===typeof a&&(c=b=a="utf8");switch(a){case "utf8":return this.toUTF8(b,c);case "base64":return this.toBase64(b,c);case "hex":return this.toHex(b,c);case "binary":return this.toBinary(b,c);case "debug":return this.toDebug();case "columns":return this.toColumns();default:throw Error("Unsupported encoding: "+a);}};var x=function(){for(var a={},b=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,
114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],c=[],d=0,f=b.length;d<f;++d)c[b[d]]=d;a.encode=function(a,c){for(var d,f;null!==(d=a());)c(b[d>>2&63]),f=(d&3)<<4,null!==(d=a())?(f|=d>>4&15,c(b[(f|d>>4&15)&63]),f=(d&15)<<2,null!==(d=a())?(c(b[(f|d>>6&3)&63]),c(b[d&63])):(c(b[f&63]),c(61))):(c(b[f&63]),c(61),c(61))};a.decode=function(a,b){function d(a){throw Error("Illegal character code: "+a);}for(var f,e,h;null!==(f=a());)if(e=c[f],"undefined"===typeof e&&d(f),null!==(f=a())&&
(h=c[f],"undefined"===typeof h&&d(f),b(e<<2>>>0|(h&48)>>4),null!==(f=a()))){e=c[f];if("undefined"===typeof e)if(61===f)break;else d(f);b((h&15)<<4>>>0|(e&60)>>2);if(null!==(f=a())){h=c[f];if("undefined"===typeof h)if(61===f)break;else d(f);b((e&3)<<6>>>0|h)}}};a.test=function(a){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(a)};return a}();e.toBase64=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);a|=0;b|=0;if(0>a||b>this.capacity||
a>b)throw RangeError("begin, end");var c;x.encode(function(){return a<b?this.view[a++]:null}.bind(this),c=r());return c()};h.fromBase64=function(a,b){if("string"!==typeof a)throw TypeError("str");var c=new h(a.length/4*3,b),d=0;x.decode(m(a),function(a){c.view[d++]=a});c.limit=d;return c};h.btoa=function(a){return h.fromBinary(a).toBase64()};h.atob=function(a){return h.fromBase64(a).toBinary()};e.toBinary=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);
a|=0;b|=0;if(0>a||b>this.capacity()||a>b)throw RangeError("begin, end");if(a===b)return"";for(var c=[],d=[];a<b;)c.push(this.view[a++]),1024<=c.length&&(d.push(String.fromCharCode.apply(String,c)),c=[]);return d.join("")+String.fromCharCode.apply(String,c)};h.fromBinary=function(a,b){if("string"!==typeof a)throw TypeError("str");for(var c=0,d=a.length,f,e=new h(d,b);c<d;){f=a.charCodeAt(c);if(255<f)throw RangeError("illegal char code: "+f);e.view[c++]=f}e.limit=d;return e};e.toDebug=function(a){for(var b=
-1,c=this.buffer.byteLength,d,f="",e="",g="";b<c;){-1!==b&&(d=this.view[b],f=16>d?f+("0"+d.toString(16).toUpperCase()):f+d.toString(16).toUpperCase(),a&&(e+=32<d&&127>d?String.fromCharCode(d):"."));++b;if(a&&0<b&&0===b%16&&b!==c){for(;51>f.length;)f+=" ";g+=f+e+"\n";f=e=""}f=b===this.offset&&b===this.limit?f+(b===this.markedOffset?"!":"|"):b===this.offset?f+(b===this.markedOffset?"[":"<"):b===this.limit?f+(b===this.markedOffset?"]":">"):f+(b===this.markedOffset?"'":a||0!==b&&b!==c?" ":"")}if(a&&" "!==
f){for(;51>f.length;)f+=" ";g+=f+e+"\n"}return a?g:f};h.fromDebug=function(a,b,c){var d=a.length;b=new h((d+1)/3|0,b,c);for(var f=0,e=0,g,k=!1,m=!1,n=!1,p=!1,q=!1;f<d;){switch(g=a.charAt(f++)){case "!":if(!c){if(m||n||p){q=!0;break}m=n=p=!0}b.offset=b.markedOffset=b.limit=e;k=!1;break;case "|":if(!c){if(m||p){q=!0;break}m=p=!0}b.offset=b.limit=e;k=!1;break;case "[":if(!c){if(m||n){q=!0;break}m=n=!0}b.offset=b.markedOffset=e;k=!1;break;case "<":if(!c){if(m){q=!0;break}m=!0}b.offset=e;k=!1;break;case "]":if(!c){if(p||
n){q=!0;break}p=n=!0}b.limit=b.markedOffset=e;k=!1;break;case ">":if(!c){if(p){q=!0;break}p=!0}b.limit=e;k=!1;break;case "'":if(!c){if(n){q=!0;break}n=!0}b.markedOffset=e;k=!1;break;case " ":k=!1;break;default:if(!c&&k){q=!0;break}g=parseInt(g+a.charAt(f++),16);if(!c&&(isNaN(g)||0>g||255<g))throw TypeError("Illegal str: Not a debug encoded string");b.view[e++]=g;k=!0}if(q)throw TypeError("Illegal str: Invalid symbol at "+f);}if(!c){if(!m||!p)throw TypeError("Illegal str: Missing offset or limit");
if(e<b.buffer.byteLength)throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+e+" < "+d);}return b};e.toHex=function(a,b){a="undefined"===typeof a?this.offset:a;b="undefined"===typeof b?this.limit:b;if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+
this.buffer.byteLength);}for(var c=Array(b-a),d;a<b;)d=this.view[a++],16>d?c.push("0",d.toString(16)):c.push(d.toString(16));return c.join("")};h.fromHex=function(a,b,c){if(!c){if("string"!==typeof a)throw TypeError("Illegal str: Not a string");if(0!==a.length%2)throw TypeError("Illegal str: Length not a multiple of 2");}var d=a.length;b=new h(d/2|0,b);for(var f,e=0,g=0;e<d;e+=2){f=parseInt(a.substring(e,e+2),16);if(!c&&(!isFinite(f)||0>f||255<f))throw TypeError("Illegal str: Contains non-hex characters");
b.view[g++]=f}b.limit=g;return b};var n=function(){var a={MAX_CODEPOINT:1114111,encodeUTF8:function(a,c){var d=null;"number"===typeof a&&(d=a,a=function(){return null});for(;null!==d||null!==(d=a());)128>d?c(d&127):(2048>d?c(d>>6&31|192):(65536>d?c(d>>12&15|224):(c(d>>18&7|240),c(d>>12&63|128)),c(d>>6&63|128)),c(d&63|128)),d=null},decodeUTF8:function(a,c){for(var d,f,e,g,h=function(a){a=a.slice(0,a.indexOf(null));var b=Error(a.toString());b.name="TruncatedError";b.bytes=a;throw b;};null!==(d=a());)if(0===
(d&128))c(d);else if(192===(d&224))null===(f=a())&&h([d,f]),c((d&31)<<6|f&63);else if(224===(d&240))null!==(f=a())&&null!==(e=a())||h([d,f,e]),c((d&15)<<12|(f&63)<<6|e&63);else if(240===(d&248))null!==(f=a())&&null!==(e=a())&&null!==(g=a())||h([d,f,e,g]),c((d&7)<<18|(f&63)<<12|(e&63)<<6|g&63);else throw RangeError("Illegal starting byte: "+d);},UTF16toUTF8:function(a,c){for(var d,e=null;null!==(d=null!==e?e:a());)55296<=d&&57343>=d&&null!==(e=a())&&56320<=e&&57343>=e?(c(1024*(d-55296)+e-56320+65536),
e=null):c(d);null!==e&&c(e)},UTF8toUTF16:function(a,c){var d=null;"number"===typeof a&&(d=a,a=function(){return null});for(;null!==d||null!==(d=a());)65535>=d?c(d):(d-=65536,c((d>>10)+55296),c(d%1024+56320)),d=null},encodeUTF16toUTF8:function(b,c){a.UTF16toUTF8(b,function(b){a.encodeUTF8(b,c)})},decodeUTF8toUTF16:function(b,c){a.decodeUTF8(b,function(b){a.UTF8toUTF16(b,c)})},calculateCodePoint:function(a){return 128>a?1:2048>a?2:65536>a?3:4},calculateUTF8:function(a){for(var c,d=0;null!==(c=a());)d+=
128>c?1:2048>c?2:65536>c?3:4;return d},calculateUTF16asUTF8:function(b){var c=0,d=0;a.UTF16toUTF8(b,function(a){++c;d+=128>a?1:2048>a?2:65536>a?3:4});return[c,d]}};return a}();e.toUTF8=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+
a+" <= "+b+" <= "+this.buffer.byteLength);}var c;try{n.decodeUTF8toUTF16(function(){return a<b?this.view[a++]:null}.bind(this),c=r())}catch(d){if(a!==b)throw RangeError("Illegal range: Truncated data, "+a+" != "+b);}return c()};h.fromUTF8=function(a,b,c){if(!c&&"string"!==typeof a)throw TypeError("Illegal str: Not a string");var d=new h(n.calculateUTF16asUTF8(m(a),!0)[1],b,c),e=0;n.encodeUTF16toUTF8(m(a),function(a){d.view[e++]=a});d.limit=e;return d};return h});
... ...
... ... @@ -42,10 +42,10 @@ class MCU extends Emiter {
}
//MCU-发送加入会议请求
//MCU-发送加入课堂请求
_sendJoinClassRequest(){
//const classInfo = this.classInfo;
loger.log('MCU-发送加入会议请求.');
loger.log('MCU-发送加入课堂请求.');
console.log(this.classInfo);
var descriptorPdu = new pdu['RCConferenceDescriptorPdu'];
descriptorPdu.id = this.classInfo.classId;
... ... @@ -90,7 +90,7 @@ class MCU extends Emiter {
//loger.log('MCU-FirstLayer封装消息', 'type', pdu.id2type(pduMsg.type), pduMsg.type, 'sessionId', ApeConsts(pduMsg.sessionId), pduMsg.sessionId);
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);
... ... @@ -146,13 +146,13 @@ class MCU extends Emiter {
return false;
}
// 会议发送消息 -- 消息同意序列号
// 课堂发送消息 -- 消息同意序列号
send(msg) {
if (this.connected) {
loger.log('MCU-发送会议数据....');
loger.log('MCU-发送课堂数据....');
this._everSocket.send(msg.toArrayBuffer());
} else {
loger.log('MCU-发送会议数据失败,MCU底层通道不可用');
loger.log('MCU-发送课堂数据失败,MCU底层通道不可用');
this._emit(MessageTypes.MCU_ERROR,MessageTypes.ERR_SOCKET_DISCONNECT);
}
}
... ...
export default function RCPduPackage(targe_type_id) {};
RCPduPackage.RCPDU_CONNECT_PROVIDER_REQUEST = 0;//加入MCU会议的请求
RCPduPackage.RCPDU_CONNECT_PROVIDER_RESPONSE = 1;//返回MCU会议请求结果
RCPduPackage.RCPDU_CONNECT_PROVIDER_REQUEST = 0;//加入MCU课堂的请求
RCPduPackage.RCPDU_CONNECT_PROVIDER_RESPONSE = 1;//返回MCU课堂请求结果
//下面两个是在入会成功之后,创建pdu包时设置的type值
RCPduPackage.RCPDU_UNIFORM_SEND_DATA_REQUEST = 125;//发送uniform_pdu
... ...