diff --git a/src/EngineEntrance.js b/src/EngineEntrance.js
index cf8d1bb..179e136 100644
--- a/src/EngineEntrance.js
+++ b/src/EngineEntrance.js
@@ -58,7 +58,7 @@ export default class MessageEntrance extends Emiter {
   constructor() {
     super();
     //sdk 信息
-    GlobalConfig.sdkVersion = "v1.80.1.20170823";
+    GlobalConfig.sdkVersion = "v1.81.1.20170824";
     loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
 
     //设置
@@ -127,8 +127,10 @@ export default class MessageEntrance extends Emiter {
     _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)); //课堂开始录制
     _confer_ape.on(MessageTypes.CLASS_RECORD_SUCCESS, this._onClassRecordSuccess.bind(this)); //课堂开启录制成功
+
     _confer_ape.on(MessageTypes.SWITCH_MS_IP, this._switchMsIpHandler.bind(this)); //MS动态选点
     //_confer_ape.on(MessageTypes.SWITCH_RTMP_PULL_IP, this._switchRtmpPullIpHandler.bind(this)); //MS 拉流地址动态选点
     //_confer_ape.on(MessageTypes.SWITCH_HLS_IP, this._switchHlsIpHandler.bind(this)); //MS HLS动态选点
@@ -406,7 +408,7 @@ export default class MessageEntrance extends Emiter {
 
   //如果是第一次点击开始上课,需要创建录制时的文件名
   _onClassRecordStart(_param) {
-    if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
+    if (!_mcu||!_mcu.connected) {
       loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
       return;
     }
@@ -1355,6 +1357,9 @@ export default class MessageEntrance extends Emiter {
     }
 
     if (_confer_ape) {
+      //开始录制
+      _confer_ape.startRecord();
+      //开始上课
       _confer_ape.startClass(_param);
     }
   }
@@ -1476,7 +1481,7 @@ export default class MessageEntrance extends Emiter {
 
   //停止上课
   _sendCloseClass(_param) {
-    if (!_mcu.connected) {
+    if (!_mcu||!_mcu.connected) {
       loger.warn(GlobalConfig.getCurrentStatus());
       return {"code": ApeConsts.RETURN_FAILED, "data": ""};
     }
@@ -1502,7 +1507,7 @@ export default class MessageEntrance extends Emiter {
     }
     //离开课堂
     if (_confer_ape) {
-      _confer_ape.stopRecord();
+      //_confer_ape.stopRecord();//不主动调用停止录制
       _confer_ape.leaveClass();
     }
 
@@ -1618,11 +1623,13 @@ export default class MessageEntrance extends Emiter {
     //存储Sass数据到本地
     if (_data.currentInfo) {
       //根据从Sass获取的数据信息,同步最后一次保存的课堂状态信息
+      loger.log("从Saas返回的课堂状态信息数据",_data.currentInfo);
       try {
-        GlobalConfig.setClassStatusInfo(JSON.parse(_data.currentInfo));
+        let dataObj=JSON.parse(_data.currentInfo);
+        dataObj.recordStatus=false;
+        GlobalConfig.setClassStatusInfo(dataObj);
       } catch (err) {
         loger.warn("从Sass获取的课堂数据JSON转换失败->");
-        console.log("currentInfo", _data.currentInfo);
         GlobalConfig.setClassStatusInfo(_data.currentInfo);
       }
       loger.log(GlobalConfig.classStatusInfo);
diff --git a/src/EngineEntranceOld.js b/src/EngineEntranceOld.js
deleted file mode 100644
index f44d89e..0000000
--- a/src/EngineEntranceOld.js
+++ /dev/null
@@ -1,2550 +0,0 @@
-require('es6-promise').polyfill();
-require('whatwg-fetch');
-require('jquery-touchswipe');
-require('string.fromcodepoint');
-//require('messenger');
-
-import Emiter from './Emiter';
-import Sass from 'Sass';
-import IpManager from 'IpManager';
-import RecordPlayBackParse from 'RecordPlayBackParse';
-import MD5 from "md5";
-import Mcu from 'mcu';
-import MessageTypes from 'MessageTypes';
-import Loger from 'Loger';
-import ConferApe from 'apes/ConferApe';
-import ChatApe from 'apes/ChatApe';
-import VideoApe from 'apes/VideoApe';
-import AudioApe from 'apes/AudioApe';
-import DocApe from 'apes/DocApe';
-import WhiteBoardApe from 'apes/WhiteBoardApe';
-import CursorApe from 'apes/CursorApe';
-
-import EngineUtils from "EngineUtils";
-import GlobalConfig from 'GlobalConfig';
-import SystemConfig from 'SystemConfig';
-
-import ApeConsts from 'apes/ApeConsts';
-import Base64 from 'base64-js';
-import ArrayBufferUtil from 'libs/ArrayBufferUtil';
-import Server from "config/Server";
-import MediaModule from 'apes/MediaModule';
-import MediaSharedApe from 'apes/MediaSharedApe';
-import MusicSharedApe from 'apes/MusicSharedApe';
-import QuestionApe from 'apes/QuestionApe';
-import UTF8 from 'utf-8';
-
-let loger = Loger.getLoger('McuClient');
-let _sdkInfo = {"version": "v1.55.1.20170727", "author": "www.3mang.com"};
-
-//APE
-let _sass;
-let _ipManager;
-let _mcu;
-let _confer_ape;
-let _chat_ape;
-let _video_ape;
-let _audio_ape;
-let _doc_ape;
-let _whiteboard_ape;
-let _cursor_ape;
-let _recordPlayback;
-let _mediaShareApe;
-let _musicShareApe;
-let _questionApe;
-
-//MCUClient 外部实例化主类
-export default class EngineEntranceOld extends Emiter {
-  constructor() {
-    super();
-    //sdk 信息
-    this.sdkInfo = _sdkInfo;
-    loger.warn(this.sdkInfo);
-    //获取设备和系统信息
-    SystemConfig.getSystemInfo();
-
-    this.classRecordStatusUpdateTimer = 0; //课堂录制状态发生改变后同步当前所有模块数据的计时器
-    //初始化状态
-    this.isGetUserIpCallback = false; //是否获取IP信息返回
-    this.isGetFastestMcuCallback = false; //是否MCU测速结束
-    this.isGetFastestMsCallback = false; //是否MS测速结束
-    this.isGetFastestRtmpPullCallback = false; //是否RTMP拉流地址测试结束
-    this.isGetFastestHlsPullCallback = false; //是否HLS拉流地址测试结束
-    this.isGetFastestRsCallback = false; //是否录制回放HLS拉流地址测试结束
-
-    //全局的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删除文档成功
-    _sass.on(_sass.DELETE_MEDIASHARE_SUCCESS, this._sassDeleteMediaShareSuccess.bind(this)); //sass删除媒体文件成功
-    _sass.on(_sass.DELETE_MUSICSHARE_SUCCESS, this._sassDeleteMusicShareSuccess.bind(this)); //sass删除MUSIC文件成功
-
-    //选点模块
-    _ipManager = new IpManager();
-
-    // 底层MCU消息层
-    _mcu = Mcu;
-    _mcu.on('*', (type, data) => this._emit(type, data));
-    _mcu.on(MessageTypes.CLASS_JOIN_MCU_SUCCESS, this._mcuJoinMCUClassSuccessHandler.bind(this)); //加入MCU课堂完成
-    _mcu.on(MessageTypes.SWITCH_MCU_IP, this._switchMcuIpHandler.bind(this)); //切换MCU,重新选点
-
-    //录制回放
-    _recordPlayback = RecordPlayBackParse;
-    _recordPlayback.on('*', (type, data) => this._emit(type, data));
-    _recordPlayback.on(RecordPlayBackParse.CLASS_JOIN_RECORD_PLAYBACK_SUCCESS, this._joinRecordPlaybackSuccessHandler.bind(this)); //加入录制回放完成
-    _recordPlayback.on(RecordPlayBackParse.RECORD_PLAYBACK_CLEAR_DATA, this._recordPlaybackClearDataHandler.bind(this)); //录制回放状态更新
-
-    // 注册所有应用Ape
-    _confer_ape = new ConferApe();
-    _confer_ape.on('*', (type, data) => this._emit(type, data));
-    _confer_ape.on(MessageTypes.CLASS_RUN_EXIT, this._runClassExit.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)); //课堂开始录制
-    _confer_ape.on(MessageTypes.CLASS_RECORD_SUCCESS, this._onClassRecordSuccess.bind(this)); //课堂开启录制成功
-    _confer_ape.on(MessageTypes.SWITCH_MS_IP, this._switchMsIpHandler.bind(this)); //MS动态选点
-    //_confer_ape.on(MessageTypes.SWITCH_RTMP_PULL_IP, this._switchRtmpPullIpHandler.bind(this)); //MS 拉流地址动态选点
-    //_confer_ape.on(MessageTypes.SWITCH_HLS_IP, this._switchHlsIpHandler.bind(this)); //MS HLS动态选点
-    _confer_ape.on(MessageTypes.STOP_ALL_MEDIA_PUBLISH, this._stopAllMediaPublishHandler.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占用
-    _video_ape.on(MessageTypes.USER_DEVICE_STATUS_CHAANGE, this.userDeviecStatusChange.bind(this)); //监听摄像头和麦克风的开启状态
-
-    _audio_ape = new AudioApe();
-    _audio_ape.on('*', (type, data) => this._emit(type, data));
-    _audio_ape.on(MessageTypes.AUDIO_UPDATE, this.audioUpdate.bind(this)); //这个监听事件不能删除,需要通知课堂模块,检查channel占用
-    _audio_ape.on(MessageTypes.USER_DEVICE_STATUS_CHAANGE, this.userDeviecStatusChange.bind(this)); //监听摄像头和麦克风的开启状态
-
-    _mediaShareApe = new MediaSharedApe();
-    _mediaShareApe.on('*', (type, data) => this._emit(type, data));
-    _mediaShareApe.on(MediaSharedApe.MEDIASHARED_JOIN_CHANNEL_SUCCESS, this.mediaShareApeJoinChannelSuccess.bind(this));
-
-    _musicShareApe = new MusicSharedApe();
-    _musicShareApe.on('*', (type, data) => this._emit(type, data));
-    _musicShareApe.on(MusicSharedApe.MUSICSHARED_JOIN_CHANNEL_SUCCESS, this.musicShareApeJoinChannelSuccess.bind(this));
-
-    _whiteboard_ape = new WhiteBoardApe();
-    _whiteboard_ape.on('*', (type, data) => this._emit(type, data));
-
-    _cursor_ape = new CursorApe();
-    _cursor_ape.on('*', (type, data) => this._emit(type, data));
-
-    _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));
-
-    _questionApe = new QuestionApe();
-    _questionApe.on('*', (type, data) => this._emit(type, data));
-
-    //公开外部调用的方法
-    //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.getClassStatusInfo = this._getClassStatusInfo.bind(this);
-    this.sendStartClass = this._sendStartClass.bind(this);
-    this.silenceClass = this._silenceClass.bind(this);
-    this.sendPauseClass = this._sendPauseClass.bind(this);
-    this.sendCloseClass = this._sendCloseClass.bind(this);
-    this.changeHandUpStatus = this._changeHandUpStatus.bind(this); //自己切换举手状态
-    this.controlHandUpStatus = this._controlHandUpStatus.bind(this); //控制别人的举手状态
-    this.controlSilenceStatus = this._controlSilenceStatus.bind(this); //改变禁言状态
-
-    this.sceneTableChange = this._sceneTableChange.bind(this); //切换模块显示
-
-    this.kickOutRosterFormNodeId = this._kickOutRosterFormNodeId.bind(this); //把指定nodeId的人踢出课堂
-
-    this.sendThridChannelMessage = this._sendThridChannelMessage.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);
-
-    //chatApe
-    this.sendChatMsg = this._sendChatMsg.bind(this);
-
-    //屏幕共享
-    this.publishScreenShare = this._publishScreenShare.bind(this);
-    this.stopPublishScreenShare = this._stopPublishScreenShare.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.unPublishVideo = 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.unPublishAudio = this._stopPublishAudio.bind(this);
-    this.sendAudioBroadcastMsg = this.sendAudioCommandMsg.bind(this);
-
-    //whiteBoradApe
-    this.sendInsertAnnotaion = this._sendInsertAnnotaion.bind(this); //添加标注
-    this.sendDeleteAllAnnotation = this._sendDeleteAllAnnotation.bind(this); //删除所有标注
-    this.sendDeleteCurPageAnnotation = this._sendDeleteCurPageAnnotation.bind(this); //删除当前页的所有标注
-    this.sendGotoPrev = this._sendGotoPrev.bind(this); //当前页撤销上一步
-
-    // CursorApe
-    this.sendInsertCursor = this._sendInsertCursor.bind(this); //添加鼠标同步
-
-    //DocApe
-    this.sendDocumentUpload = this._sendDocumentUpload.bind(this); //上传文档
-    this.sendDocumentSwitchDoc = this._sendDocumentSwitchDoc.bind(this); //切换文档
-    this.sendDocumentSwitchPage = this._sendDocumentSwitchPage.bind(this); //翻页
-    this.sendDocumentSwitchAnimation = this._sendDocumentSwitchAnimation.bind(this); //切换当前页码的动画步骤
-    this.sendDocumentDelete = this._sassDeleteDocument.bind(this);
-    this.sendDocBroadcastMsg = this._sendDocBroadcastMsg.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); //获取文档的完整路径
-    this.getDocFullAddress = this._getDocFullAddress.bind(this); //获取文档资源地址
-
-    //媒体共享模块
-    this.mediaSharedUpload = this._sendMediaSharedUpload.bind(this); //上传
-    this.mediaSharedDelete = this._sassDeletMediaShare.bind(this); //删除,先通过Sass删除,删除成功之后才删除MCU的
-
-    this.mediaSharedPlay = this._sendMediaSharedPlay.bind(this); //播放
-    this.mediaSharedStop = this._sendMediaSharedStop.bind(this); //停止
-    this.mediaSharedUpdate = this._sendMediaSharedUpdate.bind(this); //更新媒体的状态
-
-    //音频共享模块
-    this.musicSharedUpload = this._sendMusicSharedUpload.bind(this); //上传
-    this.musicSharedDelete = this._sassDeletMusicShare.bind(this); //删除,先通过Sass删除,删除成功之后才删除MCU的
-
-    this.musicSharedPlay = this._sendMusicSharedPlay.bind(this); //Music播放
-    this.musicSharedStop = this._sendMusicSharedStop.bind(this); //Music停止
-    this.musicSharedUpdate = this._sendMusicSharedUpdate.bind(this); //Music更新媒体的状态
-
-    //答题卡
-    this.creatQuestion = this._creatQuestion.bind(this);
-    this.getQuestion = this._getQuestion.bind(this);
-    this.getQuestionResult = this._getQuestionResult.bind(this);
-    this.sendAnswer = this._sendAnswer.bind(this);
-    this.stopQuestion = this._stopQuestion.bind(this);
-
-    this.setDeviceInfo = this._setDeviceInfo.bind(this); //设置设备信息(麦克风,摄像头等等.....)
-    this.setMessageDelay = this._setMessageDelay.bind(this); //设置是否延迟消息
-    this.switchServer = this._switchMcuIpHandler.bind(this); //切换mcu服务器
-    this.switchMediaServer = this._switchMediaServer.bind(this); //手动切换ms服务器
-    this.setDebugInfo = this._setDebugInfo.bind(this); //设置debug信息
-  }
-
-  _setDebugInfo(_data) {
-    loger.log("设置debug信息-->", _data);
-    if (_data) {
-      Loger.setLogDebug(_data.isDebug);
-    }
-  }
-
-  //设置设备信息
-  _setDeviceInfo(_data) {
-    loger.log("设置设备信息-->", _data);
-    if (_data) {
-      GlobalConfig.cameras = _data.cameras || [];
-      GlobalConfig.microphones = _data.microphones || [];
-      GlobalConfig.videoQuality = parseInt(_data.videoQuality);
-      GlobalConfig.curVideoQuality = parseInt(_data.curVideoQuality);
-      GlobalConfig.micGain = _data.micGain || 50;
-      GlobalConfig.speakerVolume = _data.speakerVolume || 50;
-      GlobalConfig.micCode = _data.micCode || 0;
-      GlobalConfig.curCamera = _data.curCamera || '';
-      GlobalConfig.curMicrophone = _data.curMicrophone || '';
-
-      if (!GlobalConfig.curCamera && GlobalConfig.cameras.length > 0) {
-        GlobalConfig.curCamera = GlobalConfig.cameras[0];
-      }
-      if (!GlobalConfig.curMicrophone && GlobalConfig.microphones.length > 0) {
-        GlobalConfig.curMicrophone = GlobalConfig.microphones[0];
-      }
-      this._updateDeviceInfo();
-    }
-  }
-
-  //设置消息延迟
-  _setMessageDelay(_data) {
-    loger.warn("延迟消息-->", _data);
-    if (_data) {
-      GlobalConfig.messageDelay = _data.messageDelay || false;
-    }
-  }
-
-  //mcu异常监听
-  _mcuErrorHandler(_data, _option) {
-    let option = _option || "";
-    let errorMessage = {"code": _data, "reson": MessageTypes.ErrorReson[_data] + " " + option};
-    this._emit(MessageTypes.ERROR_EVENT, errorMessage);
-    loger.error("MCU_ERROR", errorMessage);
-  }
-
-  //获取当前的状态
-  _getMcuClientStatus() {
-    return GlobalConfig.getCurrentStatus();
-  }
-
-  //获取课堂信息
-  _getClassDetail() {
-    return GlobalConfig.getClassDetail();
-  }
-
-  //获取当前课堂的状态信息
-  _getClassStatusInfo() {
-    return GlobalConfig.classStatusInfo;
-  }
-
-  //执行离开课堂断开连接的流程
-  _runClassExit(_type) {
-    this._leaveClass(_type);
-  }
-
-  //当前的课堂状态信息发生改变,需要保存课堂状态到Sass
-  _onClassStatusInfoChange(_param) {
-    //如果MCU连接已经断开,不发送
-    if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
-      loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
-      return;
-    }
-    this._sassSaveClassStatusInfo(_param);
-  }
-
-  //如果是第一次点击开始上课,需要创建录制时的文件名
-  _onClassRecordStart(_param) {
-    if (GlobalConfig.getCurrentStatus().code != GlobalConfig.statusCode_2.code) {
-      loger.warn("不能保存课堂状态", GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_sass) {
-      _sass.saveClassRecordContrlInfo(_param);
-    }
-  }
-
-  //开启录制成功
-  _onClassRecordSuccess(_param) {
-    clearTimeout(this.classRecordStatusUpdateTimer);
-    let _this = this;
-    this.classRecordStatusUpdateTimer = setTimeout(function () {
-      clearTimeout(this.classRecordStatusUpdateTimer);
-      _this.updaterRecordAllApeStatus(_param);
-    }, 2000);
-
-  }
-
-  //录制状态发送改变,更新所有模块的当前数据发送到MCU
-  updaterRecordAllApeStatus(_param) {
-    //老师身份和非录制回放的时候执行,录制状态发送改变,需要更新当前的数据,否则已有的消息会录制不上
-    if (GlobalConfig.isHost && !GlobalConfig.isRecordPlayBack) {
-      loger.warn('录制状态发送改变->更新所有模块的当前数据发送到MCU');
-      //目前录制的模块[文档模块、白板模块、视频模块(包含屏幕共享)、音频模块、媒体共享,聊天模块]
-      if (_doc_ape) {
-        _doc_ape.updaterRecordApeStatus();
-      }
-      if (_whiteboard_ape) {
-        _whiteboard_ape.updaterRecordApeStatus();
-      }
-      if (_video_ape) {
-        _video_ape.updaterRecordApeStatus();
-      }
-      if (_audio_ape) {
-        _audio_ape.updaterRecordApeStatus();
-      }
-      if (_mediaShareApe) {
-        _mediaShareApe.updaterRecordApeStatus();
-      }
-      //聊天模块不需要更新
-    }
-  }
-
-  //有人员离开
-  _onClassDeleteRoster(_data) {
-
-  }
-
-  //当前课堂中视频或音频占用channel的nodeId ,在人员列表中不存在,这种情况是占用channel的人员掉线或离开的时候没有释放channel
-  //的占用状态导致,对于这种情况,需要释放掉
-  _onClassNonentityRoster(_param) {
-    if (GlobalConfig.isRecordPlayBack) {
-      loger.warn("录制回放中,不处理")
-      return;
-    }
-
-    if (_param == null || _param.nodeId == null) {
-      loger.warn("onClassNonentityRoster.参数错误")
-      return;
-    }
-    let data = {"nodeId": _param.nodeId};
-    if (_video_ape) {
-      _video_ape.stopPublishVideo(data);
-
-      //停止屏幕共享
-      if (GlobalConfig.nodeId == data.nodeId) {
-        _video_ape.stopPublishScreenShare(data);
-      }
-    }
-    if (_audio_ape) {
-      _audio_ape.stopPublishAudio(data);
-    }
-  }
-
-  //Sass
-  //初始化
-  _init(_param) {
-    //{"classId":"1653304953","portal":"112.126.80.182:80","userRole":"normal","userId":0,isH5:false}
-    //判断传入的参数是否存在
-    if (_param == null || EngineUtils.isEmptyObject(_param)) {
-      loger.error('初始化课堂失败->参数错误', _param);
-      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('初始化课堂失败->参数错误', _param);
-      this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_CLASS_INIT_PARAM);
-      return;
-    }
-    loger.log('初始化课堂->', _param);
-
-    //保存参数
-    GlobalConfig.isRecordPlayBack = false; //设置为非录制回放状态
-    GlobalConfig.classId = parseInt(_param.classId);
-    GlobalConfig.portal = _param.portal;
-
-    //H5处理
-    GlobalConfig.isH5 = _param.isH5 || false;//外部传入的参数,是否是H5
-    if (GlobalConfig.isH5 == true) {
-      GlobalConfig.platform = "H5";
-      GlobalConfig.deviceType = 3//3是H5
-      loger.warn("设备类型是H5");
-    }
-
-    //IOS 安卓处理,需要外部传入摄像头和麦克风信息
-    if (GlobalConfig.isMobile) {
-      GlobalConfig.cameras = _param.cameras || [];
-      GlobalConfig.microphones = _param.microphones || [];
-    }
-
-    //如果没有名字,随机起一个名字
-    GlobalConfig.userName = _param.userName || "user_" + (new Date().getTime() % 1000000);
-
-    //如果没有userId或者为"0",随机生成
-    if (!GlobalConfig.userId || GlobalConfig.userId == "0") {
-      GlobalConfig.userId = "user_" + (new Date().getTime() % 1000000);
-    }
-    //设置角色身份
-    GlobalConfig.userRole = _param.userRole || ApeConsts.normal;
-    if (GlobalConfig.userRole != ApeConsts.host &&
-      GlobalConfig.userRole != ApeConsts.presenter &&
-      GlobalConfig.userRole != ApeConsts.assistant &&
-      GlobalConfig.userRole != ApeConsts.record &&
-      GlobalConfig.userRole != ApeConsts.invisible) {
-      GlobalConfig.userRole = ApeConsts.normal;
-    }
-    //客户端决定是否延迟接收消息
-    GlobalConfig.messageDelay = _param.messageDelay || false;
-
-    //最长允许录制的时间
-    if (_param.allowRecordMaxTime) {
-      GlobalConfig.allowRecordMaxTime = parseInt(_param.allowRecordMaxTime);
-    }
-
-    //获取课堂校验信息
-    if (_sass) {
-      _sass.getJoinParams(GlobalConfig.getClassInfo());
-    }
-  }
-
-  //外部请求加入课堂
-  _joinClass(_param) {
-    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;
-    }
-    //{"userName":"名字","password":"","autoLogin":""}
-    GlobalConfig.userName = _param.userName || GlobalConfig.userName; //以登陆时的名字为主,登陆之前可以修改名字
-    GlobalConfig.autoLogin = _param.autoLogin || "";
-    GlobalConfig.password = _param.password || "";
-    GlobalConfig.hasCamera = (typeof _param.hasCamera == "boolean") ? _param.hasCamera : false;
-    GlobalConfig.hasMicrophone = (typeof _param.hasMicrophone == "boolean") ? _param.hasMicrophone : false;
-
-    //loger.log("autoLoginMd5", GlobalConfig.classId, GlobalConfig.userId, GlobalConfig.userRole);
-    let autoLoginMd5 = MD5("" + GlobalConfig.classId + GlobalConfig.userId + GlobalConfig.userRole);
-    //loger.log("joinClass-GlobalConfig.autoLogin", GlobalConfig.autoLogin, "autoLoginMd5-", autoLoginMd5);
-    if (GlobalConfig.autoLogin && autoLoginMd5 == GlobalConfig.autoLogin) {
-      // MD5(classId+userId+userRole)==m
-      //自动登录,跳过验证流程
-      loger.log("自动登录");
-      this._sassJoinSuccessHandler();
-    } else {
-      //不能自动登录,开始校验
-      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 || ApeConsts.CLASS_TYPE_1;
-
-    //host默认需要密码,Sass服务器只判断学生是否需要密码,没有判断老师的
-    GlobalConfig.passwordRequired = _data.passwordRequired || false; //md5验证的时候需要Sass返回的值,不能更改
-    loger.log('初始化课堂验证完成.');
-
-    //设置当前的课堂状态
-    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);
-  }
-
-  // 通过SASS平台验证(密码和MD5)
-  _sassJoinSuccessHandler(_data) {
-    //获取课堂最完整的数据
-    if (_sass) {
-      _sass.getClassParam();
-    }
-  }
-
-  //加载本地Server.json文件,UserIp获取ip信息,选点
-  loadServerJsonAndgetUserIpInfo() {
-    let _this = this;
-    if (_ipManager) {
-      //先加载本地Server.json文件,然后获取userIp新
-      _ipManager.loadServerJosn(function (_data) {
-        _ipManager.getUserIpInfo("", GlobalConfig.userIp, _this._getUserIpCallbackHandler.bind(_this), 2000);
-      })
-    }
-  }
-
-  //本地JOSN加载完成-获取IP信息完成
-  _getUserIpCallbackHandler(_data) {
-    //获取IP信息,返回一次就不再处理
-    if (this.isGetUserIpCallback) {
-      return;
-    }
-    this.isGetUserIpCallback = true;
-    if (_data && _data.ret == "ok") {
-      GlobalConfig.country = _data.country; //国家
-      GlobalConfig.city = _data.city; //城市
-      GlobalConfig.province = _data.province; //服务商
-      GlobalConfig.isp = _data.isp; //服务商
-    }
-
-    //根据用户的userIp信息从sever.json和Sass中选择最终mcu和推流拉流数据列表
-    this._choiceMcuAndMsListFromServerAndSass();
-    //获取MCU和MS 推流拉流、录制回放的默认地址
-    this.getMcuAndMsDefaultServerIp();
-
-    loger.warn("加入课堂之前->开始测速->选择默认服务");
-    //加入课堂之前开始第一次选点
-    let _this = this;
-
-
-    //推流地址测速
-    this._getFastestIpFromServer(GlobalConfig.msListFinal,
-      function (_data) {
-        loger.log("推流地址测速->", _data);
-        if (_data && _data.ip) {
-          GlobalConfig.MS_PUBLISH_IP = _data.ip || "";
-          GlobalConfig.MS_PUBLISH_PORT = _data.port || "";
-        }
-        _this.isGetFastestMsCallback = true;
-        _this._startConnectMCU();
-      });
-
-    //录制回放HLS拉流地址测速
-    this._getFastestIpFromServer(GlobalConfig.rsPullListFinal, function (_data) {
-      loger.log("录制回放HLS拉流地址测速->", _data);
-      if (_data && _data.ip) {
-        GlobalConfig.RS_RECORD_PLAY_IP = _data.ip || "";
-        GlobalConfig.RS_RECORD_PLAY_PORT = _data.port || "";
-      }
-      _this.isGetFastestRsCallback = true;
-      _this._startConnectMCU();
-    });
-
-    //HLS和RTMP不参与测速
-/*
-
-    //RTMP拉流地址测速
-    this._getFastestIpFromServer(GlobalConfig.rtmpPullListFinal, function (_data) {
-      loger.log("RTMP拉流地址测速->", _data);
-      if (_data && _data.ip) {
-        GlobalConfig.MS_PLAY_RTMP_IP = _data.ip || "";
-        GlobalConfig.MS_PLAY_RTMP_PORT = _data.port || "";
-      }
-      _this.isGetFastestRtmpPullCallback = true;
-      _this._startConnectMCU();
-    });
-
-    //HLS拉流地址测速
-    this._getFastestIpFromServer(GlobalConfig.hlsListFinal, function (_data) {
-      loger.log("HLS拉流地址测速->", _data);
-      if (_data && _data.ip) {
-        GlobalConfig.MS_PLAY_HLS_IP = _data.ip || "";
-        GlobalConfig.MS_PLAY_HLS_PORT = _data.port || "";
-      }
-      _this.isGetFastestHlsPullCallback = true;
-      _this._startConnectMCU();
-    });
-*/
-
-    //MCU测速
-    this._getFastestMcuServer(function (_data) {
-      loger.log("MCU测速->", _data);
-      if (_data && _data.ip) {
-        GlobalConfig.MCUServerIP = _data.ip || "";
-        GlobalConfig.MCUServerPort = _data.port || "";
-      }
-      _this.isGetFastestMcuCallback = true;
-      _this._startConnectMCU();
-    });
-  }
-
-
-  /*  //本地JOSN加载完成-获取IP信息完成
-   _getUserIpCallbackHandler(_data) {
-   //获取IP信息,返回一次就不再处理
-   if (this.isGetUserIpCallback) {
-   return;
-   }
-   this.isGetUserIpCallback = true;
-   if (_data && _data.ret == "ok") {
-   GlobalConfig.country = _data.country; //国家
-   GlobalConfig.city = _data.city; //城市
-   GlobalConfig.province = _data.province; //服务商
-   GlobalConfig.isp = _data.isp; //服务商
-   }
-
-   //合并MCU 、MS的列表
-   this._choiceMcuAndMsList();
-
-   //开始选点
-   let _this = this;
-
-   //有一些站点不需要进行MS选点,需要先检查一下
-   if (GlobalConfig.siteId_letv == GlobalConfig.siteId) {
-   //MS不需要选点
-   loger.log("MS不需要选点->siteId->", GlobalConfig.siteId);
-   _this.isGetFastestMcuCallback = true;
-   _this._startConnectMCU();
-   } else {
-   this._getFastestMsServer(function (_data) {
-   loger.log("MS选点结束->", _data);
-   if (_data && _data.ip) {
-   GlobalConfig.MS_PUBLISH_IP = _data.ip || "";
-   GlobalConfig.MS_PUBLISH_PORT = _data.port || "";
-   }
-   loger.log("当前使用的MS->", GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
-   _this.isGetFastestMcuCallback = true;
-   _this._startConnectMCU();
-   });
-   }
-
-   this._getFastestMcuServer(function (_data) {
-   loger.log("MCU选点结束->", _data);
-   if (_data && _data.ip) {
-   GlobalConfig.MCUServerIP = _data.ip || "";
-   GlobalConfig.MCUServerPort = _data.port || "";
-   }
-   loger.log("当前使用的MCU->", GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
-   _this.isGetFastestMsCallback = true;
-   _this._startConnectMCU();
-   });
-   }*/
-
-  //开始连接MCU(所有服务地址测试完成之后开始连接)
-  _startConnectMCU() {
-    if (this.isGetFastestMcuCallback &&
-      this.isGetFastestMsCallback &&
-      this.isGetFastestRtmpPullCallback &&
-      this.isGetFastestHlsPullCallback &&
-      this.isGetFastestRsCallback) {
-      //mcu完成
-      //ms推流测速完成
-      //rtmp拉流测速完成
-      //hls拉流测速完成
-      //hls录制回放拉流测速完成
-      this._joinMCU();
-    }
-  }
-
-  //从Sever和Sass中选择的mcu、ms列表,如果server.json中存在就不使用Sass
-  _choiceMcuAndMsListFromServerAndSass() {
-    //1.根据user信息获取服务器列表
-    if (_ipManager) {
-      GlobalConfig.mcuListFromServer = _ipManager.getServerListForUserInfo(
-        "MCU",
-        GlobalConfig.country,
-        GlobalConfig.province,
-        GlobalConfig.city,
-        GlobalConfig.isp,
-        Server.serverList);
-
-      GlobalConfig.msListFromServer = _ipManager.getServerListForUserInfo(
-        "MS",
-        GlobalConfig.country,
-        GlobalConfig.province,
-        GlobalConfig.city,
-        GlobalConfig.isp,
-        Server.serverList);
-
-      GlobalConfig.rtmpPullListFromServer = _ipManager.getServerListForUserInfo(
-        "RTMP_PULL",
-        GlobalConfig.country,
-        GlobalConfig.province,
-        GlobalConfig.city,
-        GlobalConfig.isp,
-        Server.serverList);
-
-      GlobalConfig.rsPullListFromServer = _ipManager.getServerListForUserInfo(
-        "RS_PULL",
-        GlobalConfig.country,
-        GlobalConfig.province,
-        GlobalConfig.city,
-        GlobalConfig.isp,
-        Server.serverList);
-
-      GlobalConfig.hlsPullListFromServer = _ipManager.getServerListForUserInfo(
-        "HLS_PULL",
-        GlobalConfig.country,
-        GlobalConfig.province,
-        GlobalConfig.city,
-        GlobalConfig.isp,
-        Server.serverList);
-    }
-
-    loger.warn("Server中获取的服务器信息;")
-    loger.warn(" GlobalConfig.mcuListFromServer", GlobalConfig.mcuListFromServer);
-    loger.warn(" GlobalConfig.msListFromServer", GlobalConfig.msListFromServer);
-    loger.warn(" GlobalConfig.rtmpPullListFromServer", GlobalConfig.rtmpPullListFromServer);
-    loger.warn(" GlobalConfig.hlsPullListFromServer", GlobalConfig.hlsPullListFromServer);
-    loger.warn(" GlobalConfig.rsPullListFromServer", GlobalConfig.rsPullListFromServer);
-
-
-    //********选择最终使用的MCU、MS 和拉流列表********
-    //****优先使用server.json中的数据,如果没有再使用Sass中的数据****
-
-    //MCU
-    GlobalConfig.mcuListFinal = [];
-    if (GlobalConfig.mcuListFromServer.length > 0) {
-      //使用server中的MCU数据
-      GlobalConfig.mcuListFinal = GlobalConfig.mcuListFromServer;
-    } else {
-      //使用Sass中的数据
-      GlobalConfig.mcuListFinal = GlobalConfig.mcuList;
-    }
-
-    //MS推流
-    GlobalConfig.msListFinal = []
-    if (GlobalConfig.msListFromServer.length > 0) {
-      GlobalConfig.msListFinal = GlobalConfig.msListFromServer;
-    } else {
-      GlobalConfig.msListFinal = GlobalConfig.msList;
-    }
-
-    //RS录制回放HLS拉流
-    GlobalConfig.rsPullListFinal = []
-    if (GlobalConfig.msListFromServer.length > 0) {
-      GlobalConfig.rsPullListFinal = GlobalConfig.rsPullListFromServer;
-    } else {
-      GlobalConfig.rsPullListFinal = GlobalConfig.rsList;
-    }
-
-    //RTMP拉流
-    GlobalConfig.rtmpPullListFinal = [];
-    if (GlobalConfig.rtmpPullListFromServer.length > 0) {
-      GlobalConfig.rtmpPullListFinal = GlobalConfig.rtmpPullListFromServer;
-    } else {
-      GlobalConfig.rtmpPullListFinal = GlobalConfig.rtmpPullList;
-    }
-
-    //HLS拉流流
-    GlobalConfig.hlsPullListFinal = [];
-    if (GlobalConfig.hlsPullListFromServer.length > 0) {
-      GlobalConfig.hlsPullListFinal = GlobalConfig.hlsPullListFromServer;
-    } else {
-      GlobalConfig.hlsPullListFinal = GlobalConfig.hlsPullList;
-    }
-
-    //拉流地址列表的特殊处理,
-    // 1.如果RTMP拉流地址没有配置,就默认使用MS推流地址列表
-    if (!GlobalConfig.rtmpPullListFinal || GlobalConfig.rtmpPullListFinal.length < 1) {
-      GlobalConfig.rtmpPullListFinal = GlobalConfig.msListFinal;
-    }
-    // 2.如果HLS拉流地址没有配置,就默认使用录制回放RS拉流地址列表中的数据
-    if (!GlobalConfig.hlsPullListFinal || GlobalConfig.hlsPullListFinal.length < 1) {
-      GlobalConfig.hlsPullListFinal = GlobalConfig.rsPullListFinal;
-      ;
-    }
-
-    loger.warn("课堂最终使用的服务列表->");
-    loger.warn(" GlobalConfig.mcuListFinal", GlobalConfig.mcuListFinal);
-    loger.warn(" GlobalConfig.msListFinal", GlobalConfig.msListFinal);
-    loger.warn(" GlobalConfig.rtmpPullListFinal", GlobalConfig.rtmpPullListFinal);
-    loger.warn(" GlobalConfig.hlsListFinal", GlobalConfig.hlsPullListFinal);
-    loger.warn(" GlobalConfig.rsListFinal", GlobalConfig.rsPullListFinal);
-
-  }
-
-  //开始测速
-  _getFastestIpFromServer(_dataArr, _callback) {
-    if (_ipManager) {
-      _ipManager.testFastestIpFromServer(_dataArr, _callback);
-    } else {
-      if (_callback) {
-        _callback({'ip': ""});
-      }
-    }
-  }
-
-  //开始MCU选点操作
-  _getFastestMcuServer(_callback) {
-    if (_ipManager) {
-      _ipManager.getFastestMcuServer(GlobalConfig.mcuListFinal, _callback);
-    } else {
-      if (_callback) {
-        _callback({'ip': ""});
-      }
-    }
-  }
-
-  //开始MS选点操作
-  _getFastestMsServer(_callback) {
-    if (_ipManager) {
-      _ipManager.getFastestMsServer(GlobalConfig.msListFinal, _callback);
-    } else {
-      if (_callback) {
-        _callback({ip: ""});
-      }
-    }
-  }
-
-  //开始MS-PULL选点操作
-  _getFastestRtmpPullServer(_callback) {
-    if (_ipManager) {
-      _ipManager.getFastestMsServer(GlobalConfig.rtmpPullListFinal, _callback);
-    } else {
-      if (_callback) {
-        _callback({ip: ""});
-      }
-    }
-  }
-
-  //开始MS-HLS选点操作
-  _getFastestHlsServer(_callback) {
-    if (_ipManager) {
-      _ipManager.getFastestMsServer(GlobalConfig.rtmpPullListFinal, _callback);
-    } else {
-      if (_callback) {
-        _callback({ip: ""});
-      }
-    }
-  }
-
-  //保存课堂状态信息
-  _sassSaveClassStatusInfo(_param) {
-    //{isForce:true}   isForce->是否强制提交(true为是)
-    //这个是特殊权限
-    let isForce = false;
-    if (_param && _param.isForce == true) {
-      isForce = true;
-    }
-
-    if (GlobalConfig.isHost || isForce) {
-      //只有加入课堂之后才能保存数据
-      if (GlobalConfig.getCurrentStatus().code == GlobalConfig.statusCode_2.code) {
-        //POST 保存数据
-        _sass.saveClassStatusInfo({"classStatusInfo": GlobalConfig.classStatusInfo}); //保存课堂状态信息
-      } else {
-        loger.error("不能保存课堂数据", GlobalConfig.getCurrentStatus());
-      }
-    } else {
-      loger.log("没有保存课堂状态信息的权限->身份", GlobalConfig.userRole);
-    }
-  }
-
-  //保存会态信息成功
-  _sassSaveClassStatusInfoSuccessHandler(_data) {
-    loger.log('保存课堂状态信息成功.');
-    loger.log(_data);
-  }
-
-  _sassSaveClassRecordInfoSuccessHandler(_data) {
-    loger.log('保存课堂录制信息成功.');
-    loger.log(_data);
-  }
-
-  //Sass校验流程结束之后,开始加入MCU
-  _joinMCU() {
-    loger.log('加入课堂->.');
-    loger.warn("最终使用课堂服务信息->");
-    loger.warn('MCU服务器地址->mcu->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
-    loger.warn('推流地址->MS->', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
-    loger.warn('RTMP拉流地址->RTMP->', GlobalConfig.MS_PLAY_RTMP_IP, GlobalConfig.MS_PLAY_RTMP_PORT);
-    loger.warn('HLS拉流地址->HLS->', GlobalConfig.MS_PLAY_HLS_IP, GlobalConfig.MS_PLAY_HLS_PORT);
-    loger.warn('HLS录制回放拉流地址->HLS->', GlobalConfig.RS_RECORD_PLAY_IP, GlobalConfig.RS_RECORD_PLAY_PORT);
-
-    if (_mcu) {
-      _mcu.joinMCU(GlobalConfig.getClassInfo());
-    }
-  }
-
-  _switchMcuIp() {
-    loger.log('切换MCU IP->.');
-    if (_mcu) {
-      _mcu.switchMCUIp(GlobalConfig.getClassInfo());
-    }
-  }
-
-  // MCU 课堂成功
-  _mcuJoinMCUClassSuccessHandler(_data) {
-    //loger.log('MCU 课堂成功.');
-    GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
-    GlobalConfig.classJoinSuccess = true;
-
-    GlobalConfig.screenWidth = window.screen.width;
-    GlobalConfig.screenHeight = window.screen.height;
-
-    //返回给客户端初始化成功的数据
-    let joinClassSuccessCallBackData = {};
-
-    joinClassSuccessCallBackData.isRecordPlayBack = GlobalConfig.isRecordPlayBack;
-
-    joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
-    joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
-
-    joinClassSuccessCallBackData.classStatus = GlobalConfig.classStatus;
-    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.maxMediaChannels = GlobalConfig.maxMediaChannels;
-    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_1;
-
-    joinClassSuccessCallBackData.country = GlobalConfig.country; //国家
-    joinClassSuccessCallBackData.city = GlobalConfig.city; //城市
-    joinClassSuccessCallBackData.province = GlobalConfig.province; //服务商
-    joinClassSuccessCallBackData.isp = GlobalConfig.isp; //服务商
-
-    joinClassSuccessCallBackData.classTimestamp = GlobalConfig.classTimestamp; //课堂进行的累积时间
-    joinClassSuccessCallBackData.recordTimestamp = GlobalConfig.recordTimestamp; //课堂录制的累积时间
-    joinClassSuccessCallBackData.recordPlaybackMaxTime = GlobalConfig.recordPlaybackMaxTime; //录制回放的总时间
-
-    joinClassSuccessCallBackData.fps = GlobalConfig.fps;
-    joinClassSuccessCallBackData.gop = GlobalConfig.gop;
-    joinClassSuccessCallBackData.videoQuality = GlobalConfig.videoQuality;
-
-    joinClassSuccessCallBackData.ssTunnelAppURL = GlobalConfig.ssTunnelAppURL;
-    joinClassSuccessCallBackData.currentSceneTableId = GlobalConfig.currentSceneTableId; //文档区域的模块显示
-    joinClassSuccessCallBackData.serverAndLoacTimeDistanc = GlobalConfig.serverAndLoacTimeDistanc;
-
-    joinClassSuccessCallBackData.deviceType = GlobalConfig.deviceType;
-    joinClassSuccessCallBackData.language = GlobalConfig.language;
-    joinClassSuccessCallBackData.explorer = GlobalConfig.explorer;
-    joinClassSuccessCallBackData.explorerVersion = GlobalConfig.explorerVersion;
-    joinClassSuccessCallBackData.os = GlobalConfig.os;
-
-    loger.log('加入课堂成功->');
-    loger.log(joinClassSuccessCallBackData);
-
-    //加入课堂成功,广播消息
-    this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
-  }
-
-  //切换MCU ->_param->{reConnect:false} //reConnect(是否立即替换当前的ip并且重新连接)
-  _switchMcuIpHandler(_param) {
-    if (GlobalConfig.isRecordPlayBack) {
-      loger.log('录制回放->不进行MCU动态选点');
-      return;
-    }
-    loger.log('MCU->动态选点');
-    let _this = this;
-    this._getFastestMcuServer(function (_data) {
-      loger.log("MCU选点结束->", _data);
-      //记录当前的IP地址,选点结束后需要判断一下是否是新的IP;
-      let oldIp = GlobalConfig.MCUServerIP;
-
-      if (_data && _data.ip) {
-        GlobalConfig.MCUServerIP = _data.ip || "";
-        GlobalConfig.MCUServerPort = _data.port || "";
-      } else {
-        //随机选择一个
-        if (GlobalConfig.mcuList && GlobalConfig.mcuList.length > 0) {
-          let index = parseInt(Math.random() * GlobalConfig.mcuList.length);
-          GlobalConfig.MCUServerIP = GlobalConfig.mcuList[index].ip || "";
-          GlobalConfig.MCUServerPort = GlobalConfig.mcuList[index].port || "";
-        }
-      }
-      if (oldIp && oldIp != GlobalConfig.MCUServerIP) {
-        loger.log('MCU->最新地址->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
-        //判断是否需要主动断开当前的连接然后重连新的服务器
-        if (_param && _param.reConnect == true) {
-          loger.log('MCU->切换到最新的IP->', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
-          _this._startConnectMCU();
-        } else {
-          //不需要断开当前的连接,更改ip即可
-          _this._switchMcuIp();
-        }
-      } else {
-        //如果选点结束后获得的ip和当前的IP相同,不需要切换
-        loger.log('MCU不需要切换->之前的IP->', oldIp, "新的IP->", GlobalConfig.MCUServerIP);
-      }
-    });
-  }
-
-  //课堂状态发生改变,需要停止当前的所有推流
-  _stopAllMediaPublishHandler(_data) {
-    loger.log('课堂状态发生改变,需要停止当前的所有推流');
-    this._emit(MessageTypes.MEDIA_STOP_PUBLISH);
-  }
-
-  //手动切换MS -> {ip;"xxx.xx.xx","port":"xxxx"}
-  _switchMediaServer(_param) {
-    if (GlobalConfig.isRecordPlayBack) {
-      //录制回放不做操作
-      loger.warn('录制回放->不能手动切换MS');
-      return;
-    }
-    if (_param && _param.ip) {
-      GlobalConfig.MS_PUBLISH_IP = _param.ip || "";
-      GlobalConfig.MS_PUBLISH_PORT = _param.port || "";
-    }
-    loger.warn('手动切换MS->', GlobalConfig.MS_PUBLISH_IP + ":" + GlobalConfig.MS_PUBLISH_PORT);
-    //更换完用户当前的MS地址,需要更新用户数据
-    if (_confer_ape) {
-      _confer_ape.updateUserInfo();
-    }
-  }
-
-  //切换MS ->_param->{reConnect:false} //reConnect(是否立即替换当前的ip并且重新连接)
-  _switchMsIpHandler(_param) {
-    if (GlobalConfig.isRecordPlayBack) {
-      //录制回放不做操作
-      loger.warn('录制回放->不进行MS动态选点');
-      return;
-    }
-    let _this = this;
-    this._getFastestMsServer(function (_data) {
-      loger.log("MS选点结束->", _data);
-      //记录当前的IP地址,选点结束后需要判断一下是否是新的IP;
-      let oldIp = GlobalConfig.MS_PUBLISH_IP;
-
-      if (_data && _data.ip) {
-
-        GlobalConfig.MS_PUBLISH_IP = _data.ip || "";
-        GlobalConfig.MS_PUBLISH_PORT = _data.port || "";
-      } else {
-        //随机选择一个
-        if (GlobalConfig.msListFinal && GlobalConfig.msListFinal.length > 0) {
-          let index = parseInt(Math.random() * GlobalConfig.msListFinal.length);
-          GlobalConfig.MS_PUBLISH_IP = GlobalConfig.msListFinal[index].ip || "";
-          GlobalConfig.MS_PUBLISH_PORT = GlobalConfig.msListFinal[index].port || "";
-        }
-      }
-
-      if (oldIp && oldIp != GlobalConfig.MS_PUBLISH_IP) {
-        //选点完成需要更新用户数据
-        if (_confer_ape) {
-          _confer_ape.updateUserInfo();
-        }
-        loger.log('MS->最新地址->', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
-      } else {
-        //如果选点结束后获得的ip和当前的IP相同,不需要切换
-        loger.log('MS不需要切换->IP', GlobalConfig.MS_PUBLISH_IP);
-      }
-    });
-  }
-
-  //切换MS -PULL地址
-  _switchRtmpPullIpHandler(_param) {
-    if (GlobalConfig.isRecordPlayBack) {
-      //录制回放不做操作
-      loger.warn('录制回放->不进行MS-PULL动态选点');
-      return;
-    }
-    if(!GlobalConfig.rtmpPullListFinal||GlobalConfig.rtmpPullListFinal.length<1){
-      return;
-    }
-    let _this = this;
-    this._getFastestRtmpPullServer(function (_data) {
-      loger.log("MS->PULL->选点结束->", _data);
-      if (_data && _data.ip) {
-        GlobalConfig.MS_PLAY_RTMP_IP = _data.ip || "";
-        GlobalConfig.MS_PLAY_RTMP_PORT = _data.port || "";
-      } else {
-         //随机选择一个
-         if (GlobalConfig.rtmpPullListFinal && GlobalConfig.rtmpPullListFinal.length > 0) {
-         let index = parseInt(Math.random() * GlobalConfig.rtmpPullListFinal.length);
-         GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.rtmpPullListFinal[index].ip || "";
-         GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.rtmpPullListFinal[index].port || "";
-         }
-      }
-      //如果RTMP没有配置地址,那么还是使用推流的地址
-      if(!GlobalConfig.MS_PLAY_RTMP_IP){
-        GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.MS_PUBLISH_IP;
-        GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.MS_PUBLISH_PORT;
-      }
-    });
-  }
-
-  //切换MS HLS地址
-  _switchHlsIpHandler(_param) {
-    if (GlobalConfig.isRecordPlayBack) {
-      //录制回放不做操作
-      loger.warn('录制回放->不进行MS-HLS动态选点');
-      return;
-    }
-    if(!GlobalConfig.hlsPullListFinal||GlobalConfig.hlsPullListFinal.length<1){
-      return;
-    }
-    let _this = this;
-    this._getFastestHlsServer(function (_data) {
-      loger.log("HLS选点结束->", _data);
-      if (_data && _data.ip) {
-        GlobalConfig.MS_PLAY_HLS_IP = _data.ip || "";
-        GlobalConfig.MS_PLAY_HLS_PORT = _data.port || "";
-      } else {
-        //随机选择一个
-         if (GlobalConfig.hlsPullListFinal && GlobalConfig.hlsPullListFinal.length > 0) {
-         let index = parseInt(Math.random() * GlobalConfig.hlsPullListFinal.length);
-         GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.hlsPullListFinal[index].ip || "";
-         GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.hlsPullListFinal[index].port || "";
-         }
-      }
-      //如果HLS没有配置地址,那么还是使用推流的地址
-      if(!GlobalConfig.MS_PLAY_HLS_IP){
-        GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.RS_RECORD_PLAY_IP;
-        GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.RS_RECORD_PLAY_PORT;
-      }
-    });
-  }
-
-  //先通过Sass删除文档数据,删除成功之后才能删除MCU的
-  _sassDeleteDocument(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-
-    //判断传入的参数是否存在
-    if (_param == null || EngineUtils.isEmptyObject(_param)) {
-      loger.error('删除文档失败->参数错误', _param);
-      this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
-      return;
-    }
-    //判断必要的参数字段值
-    if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.docId == null || _param.docId == "") {
-      loger.error('删除文档失败->', _param);
-      this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_DOC_DELETE_FAILED_PARAM);
-      return;
-    }
-    loger.log('删除文档->', _param);
-
-    if (_sass) {
-      _sass.sassDeleteDocument(_param);
-    }
-  }
-
-  _sendDocBroadcastMsg(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_doc_ape) {
-      _doc_ape.sendDocBroadcastMsg(_param);
-    }
-  }
-
-  //Sass删除文档成功之后,同步删除MCU数据
-  _sassDeleteDocumentSuccess(_param) {
-    loger.log('删除文档成功->', _param);
-    this._sendDocumentDelete(_param);
-  }
-
-  _sassDeleteMediaShareSuccess(_param) {
-    loger.log('删除媒体文件成功->', _param);
-    this._sendMediaSharedDelete(_param);
-  }
-
-  _sassDeleteMusicShareSuccess(_param) {
-    loger.log('删除Music文件成功->', _param);
-    this._sendMusicSharedDelete(_param);
-  }
-
-  //ConferApe
-  //开始上课
-  _sendStartClass(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-
-    if (_confer_ape) {
-      _confer_ape.startClass(_param);
-    }
-  }
-
-  //ConferApe
-  //全局禁言
-  _silenceClass(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-
-    if (_confer_ape) {
-      _confer_ape.silenceClass(_param);
-    }
-  }
-
-  //暂停上课
-  _sendPauseClass(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_confer_ape) {
-      _confer_ape.pauseClass(_param);
-    }
-  }
-
-  //更新设备信息
-  _updateDeviceInfo(_param) {
-    if (!_mcu.connected) {
-      loger.warn('更新设备信息->失败', GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (!GlobalConfig.classJoinSuccess) {
-      loger.warn('更新设备信息->失败->还没有加入课堂成功', GlobalConfig.getCurrentStatus());
-    }
-    if (_confer_ape) {
-      _confer_ape.updateDeviceInfo(_param);
-    }
-  }
-
-  //文档-媒体共享-屏幕共享模块切换
-  _sceneTableChange(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_confer_ape) {
-      _confer_ape.sceneTableChange(_param);
-    }
-  }
-
-  //通过第三方消息通道发送消息
-  _sendThridChannelMessage(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_confer_ape) {
-      _confer_ape.onThirdReciveParentMessage(_param);
-    }
-  }
-
-  //将指定nodeId的人踢出课堂
-  _kickOutRosterFormNodeId(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_confer_ape) {
-      _confer_ape.kickOutRosterFormNodeId(_param);
-    }
-  }
-
-  // 禁言控制
-  _controlSilenceStatus(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_confer_ape) {
-      _confer_ape.controlSilenceStatus(_param);
-    }
-  }
-
-  //举手状态控制
-  _controlHandUpStatus(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_confer_ape) {
-      _confer_ape.controlHandUpStatus(_param);
-    }
-  }
-
-  //举手状态切换
-  _changeHandUpStatus(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_confer_ape) {
-      _confer_ape.changeHandUpStatus(_param);
-    }
-  }
-
-  //停止上课
-  _sendCloseClass(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_confer_ape) {
-      _confer_ape.closeClass(_param);
-    }
-  }
-
-  // 离开课堂 {type:1}   type=1被踢出课堂;type=0自己主动离开
-  _leaveClass(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-
-    //停止推流
-    if (_video_ape) {
-      _video_ape.stopPublishVideo();
-      _video_ape.stopPublishScreenShare();
-    }
-    if (_audio_ape) {
-      _audio_ape.stopPublishAudio();
-    }
-    //离开课堂
-    if (_confer_ape) {
-      _confer_ape.stopRecord();
-      _confer_ape.leaveClass();
-    }
-
-    let callBack = {};
-    if (_param && _param.type) {
-      callBack = _param;
-    } else {
-      callBack.type = 0;
-    }
-    loger.warn('离开课堂->', MessageTypes.CLASS_EXIT, callBack);
-    this._emit(MessageTypes.CLASS_EXIT, callBack);
-
-    //断开MCU连接
-    if (_mcu) {
-      _mcu.leaveMCU();
-      GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_3);
-    }
-  }
-
-  //获取课堂所有参数(20170727新规则) api/meeting/detail.do? flash中的接口文件是 getClassParam.do
-  _sassGetClassParamSuccessHandler(_data) {
-    loger.log('获取课堂课堂信息完成.');
-    //包含整个课堂最全的信息,储存数据
-    if (_data) {
-      GlobalConfig.mcuDelay = _data.h5Delay || 0; //mcu消息延迟的时间间隔,单位(秒),结合客户端传的messageDelay的值使用
-      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.maxMediaChannels = Math.max(GlobalConfig.maxVideoChannels, GlobalConfig.maxAudioChannels);
-
-      GlobalConfig.ssTunnelAppURL = _data.ssTunnelAppURL || ''; //屏幕共享插件的地址
-
-      //视频质量相关设置,每次加入课堂都按最新的获取设置
-      GlobalConfig.fps = _data.fps || 15;
-      GlobalConfig.gop = _data.gop || 3;
-      GlobalConfig.videoQuality = parseInt(_data.videoQuality);
-      GlobalConfig.curVideoQuality = GlobalConfig.videoQuality;
-
-      //是否自动开始(身份是host的时候才用到的)
-      GlobalConfig.isAutoStartClass = _data.autoRecord || 0;
-
-      GlobalConfig.serverTime = _data.serverTime || new Date().getTime(); //获取服务器时间戳
-      GlobalConfig.serverAndLoacTimeDistanc = (new Date().getTime() - GlobalConfig.serverTime) / 1000; //当前系统时间和服务器时间的差值 (秒)
-      loger.warn("服务器时间:" + GlobalConfig.serverTime + "  系统时间:" + new Date().getTime() + "  时间差:" + GlobalConfig.serverAndLoacTimeDistanc);
-
-
-      GlobalConfig.setDocListPrepare(_data.docListPrepare); //提前上传的文档列表
-      GlobalConfig.setRecordList(_data.recordList); //录制回放地址
-      GlobalConfig.setDocList(_data.docList); //文档地址
-      GlobalConfig.setMusicList(_data.musicList); //
-      GlobalConfig.setMusicListPrepare(_data.musicListPrepare); //提前上传的声音文件列表
-      GlobalConfig.setVideoCDNAddr(_data.videoCDNAddr); //cdn加速的拉流地址,直播的时候才使用
-      GlobalConfig.setMediaShareList(_data.sharedMediaList); //提前上传的媒体共享文件列表
-
-      //存从Sass获取的MS和MCU服务列表
-      if (_data.msList2) {
-        GlobalConfig.setMsList(_data.msList2.msList); //储存Sass ms拉流地址
-        GlobalConfig.setRtmpPullList(_data.msList2.rtmpPullArray); //储存Sass ms拉流地址
-        GlobalConfig.setHlsPullList(_data.msList2.hlsPullArray); //储存Sass ms拉流地址
-        GlobalConfig.setRsList(_data.msList2.rsList); //储存Sass 录制回放hls拉流地址
-      }
-      //Sass mcu
-      GlobalConfig.setMcuList(_data.mcuList); //mcu
-
-      loger.warn('从Sass获取的推流拉流列表数据:');
-      loger.warn('Sass->msList->', GlobalConfig.msList);
-      loger.warn('Sass->rtmpPullList->', GlobalConfig.rtmpPullList);
-      loger.warn('Sass->hlsPullList->', GlobalConfig.hlsPullList);
-      loger.warn('Sass->rsList->', GlobalConfig.rsList);
-
-      //没有加载server.json之前,最终的服务列表按Sass的为准,server.json加载完成后会选点
-      GlobalConfig.msListFinal=GlobalConfig.msList;
-      GlobalConfig.rtmpPullListFinal=GlobalConfig.rtmpPullList;
-      GlobalConfig.hlsPullListFinal=GlobalConfig.hlsPullList;
-      GlobalConfig.rsPullListFinal=GlobalConfig.rsList;
-      GlobalConfig.mcuListFinal=GlobalConfig.mcuList;
-    }
-
-    //课堂获取Sass数据完成
-    this._emit(MessageTypes.CLASS_GET_INFO_SUCCESS, GlobalConfig.getClassInfo());
-
-    if (_data.currentInfo) {
-      //根据从Sass获取的数据信息,同步最后一次保存的课堂状态信息
-      try {
-        GlobalConfig.setClassStatusInfo(JSON.parse(_data.currentInfo));
-      } catch (err) {
-        loger.warn("从Sass获取的课堂数据JSON转换失败->");
-        console.log("currentInfo", _data.currentInfo);
-        GlobalConfig.setClassStatusInfo(_data.currentInfo);
-      }
-      loger.log(GlobalConfig.classStatusInfo);
-    } else {
-      loger.log("还没有保存过课堂状信息");
-    }
-
-    //课堂数据获取完成->进入课堂或进入录制回放
-    //录制回放不需要获取ip信息和选点
-    if (GlobalConfig.isRecordPlayBack) {
-      if (_recordPlayback) {
-        //获取MCU和MS 推流拉流、录制回放的默认地址
-        this.getMcuAndMsDefaultServerIp();
-        //开启录制回放流程
-        loger.warn("开启录制回放流程");
-        _recordPlayback.readyRecordPlay();
-      } else {
-        loger.warn("开启录制回放流程失败->还未创建模块");
-      }
-    } else {
-      //根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU
-      this.loadServerJsonAndgetUserIpInfo();
-    }
-  }
-
-  //获取各个服务的默认ip,之后会进行测速选择更快的ip
-  getMcuAndMsDefaultServerIp() {
-    //MCU地址
-    if (GlobalConfig.mcuListFinal && GlobalConfig.mcuListFinal.length > 0) {
-      //还未开始选点之前随机选择一个
-      let index = parseInt(Math.random() * GlobalConfig.mcuListFinal.length);
-      GlobalConfig.MCUServerIP = GlobalConfig.mcuListFinal[index].ip || "";
-      GlobalConfig.MCUServerPort = GlobalConfig.mcuListFinal[index].port || "";
-    }
-
-    //录制回放时m3u8播流地址
-    if (GlobalConfig.rsPullListFinal && GlobalConfig.rsPullListFinal.length > 0) {
-      //还未开始选点之前随机选择一个
-      let index = parseInt(Math.random() * GlobalConfig.rsPullListFinal.length);
-      GlobalConfig.RS_RECORD_PLAY_IP = GlobalConfig.rsPullListFinal[index].ip || "";
-      GlobalConfig.RS_RECORD_PLAY_PORT = GlobalConfig.rsPullListFinal[index].port || "";
-    }
-
-    //推流地址
-    if (GlobalConfig.msListFinal && GlobalConfig.msListFinal.length > 0) {
-      //还未开始选点之前随机选择一个
-      let index = parseInt(Math.random() * GlobalConfig.msListFinal.length);
-      GlobalConfig.MS_PUBLISH_IP = GlobalConfig.msListFinal[index].ip || "";
-      GlobalConfig.MS_PUBLISH_PORT = GlobalConfig.msListFinal[index].port || "";
-    }
-
-    //RTMP拉流
-    if (GlobalConfig.rtmpPullListFinal && GlobalConfig.rtmpPullListFinal.length > 0) {
-      // //还未开始选点之前随机选择一个
-      let index = parseInt(Math.random() * GlobalConfig.rtmpPullListFinal.length);
-      GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.rtmpPullListFinal[index].ip || "";
-      GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.rtmpPullListFinal[index].port || "";
-    } else {
-      //如果没有单独的rtmp拉流地址,和推流地址一样即可
-      GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.MS_PUBLISH_IP;
-      GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.MS_PUBLISH_PORT;
-    }
-
-    //课堂中HLS拉流地址
-    if (GlobalConfig.hlsPullListFinal && GlobalConfig.hlsPullListFinal.length > 0) {
-      //有单独的hls拉流地址
-      let index = parseInt(Math.random() * GlobalConfig.hlsPullListFinal.length);
-      GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.hlsPullListFinal[index].ip || "";
-      GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.hlsPullListFinal[index].port || "";
-    } else {
-      //没有单独的hls拉流地址,和录制回放地址一样即可
-      GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.RS_RECORD_PLAY_IP;
-      GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.RS_RECORD_PLAY_PORT;
-    }
-
-
-    //文档服务器地址
-    if (GlobalConfig.docList && GlobalConfig.docList.length > 0) {
-      //doc上传地址,随机获取一个
-      let index = parseInt(Math.random() * GlobalConfig.docList.length);
-      GlobalConfig.DOCServerIP = GlobalConfig.docList[index].ip || "";
-      GlobalConfig.DOCServerPort = GlobalConfig.docList[index].port || "";
-
-    }
-    //录制回放文件的下载地址
-    if (GlobalConfig.recordList && GlobalConfig.recordList.length > 0) {
-      let index = parseInt(Math.random() * GlobalConfig.recordList.length);
-      GlobalConfig.RecordServerIP = GlobalConfig.recordList[index].ip || "";
-      GlobalConfig.RecordServerPort = GlobalConfig.recordList[index].port || "";
-
-    }
-    loger.warn('默认->MCU地址->.', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
-
-    loger.warn('默认->MS推流地址->.', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
-    loger.warn('默认->HLS点播地址->.', GlobalConfig.RS_RECORD_PLAY_IP, GlobalConfig.RS_RECORD_PLAY_PORT);
-    loger.warn('默认->HLS拉流地址->.', GlobalConfig.MS_PLAY_HLS_IP, GlobalConfig.MS_PLAY_HLS_PORT);
-    loger.warn('默认->RTMP拉流地址->.', GlobalConfig.MS_PLAY_RTMP_IP, GlobalConfig.MS_PLAY_RTMP_PORT);
-
-    loger.warn('默认->文档服务器地址->.', GlobalConfig.DOCServerIP, GlobalConfig.DOCServerPort);
-    loger.warn('默认->录制回放文件下载地址->.', GlobalConfig.RecordServerIP, GlobalConfig.RecordServerPort);
-  }
-
-  //获取课堂所有参数 api/meeting/detail.do? flash中的接口文件是 getClassParam.do(20170727之前的规则)
-  /*_sassGetClassParamSuccessHandler(_data) {
-   loger.log('获取课堂课堂信息完成.');
-   //包含整个课堂最全的信息,储存数据
-   if (_data) {
-   GlobalConfig.mcuDelay = _data.h5Delay || 0; //mcu消息延迟的时间间隔,单位(秒),结合客户端传的messageDelay的值使用
-   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.maxMediaChannels = Math.max(GlobalConfig.maxVideoChannels, GlobalConfig.maxAudioChannels);
-
-   GlobalConfig.ssTunnelAppURL = _data.ssTunnelAppURL || ''; //屏幕共享插件的地址
-
-   //视频质量相关设置,每次加入课堂都按最新的获取设置
-   GlobalConfig.fps = _data.fps || 15;
-   GlobalConfig.gop = _data.gop || 3;
-   GlobalConfig.videoQuality = parseInt(_data.videoQuality);
-   GlobalConfig.curVideoQuality = GlobalConfig.videoQuality;
-
-   //是否自动开始(身份是host的时候才用到的)
-   GlobalConfig.isAutoStartClass = _data.autoRecord || 0;
-
-   GlobalConfig.serverTime = _data.serverTime || new Date().getTime(); //获取服务器时间戳
-   GlobalConfig.serverAndLoacTimeDistanc = (new Date().getTime() - GlobalConfig.serverTime) / 1000; //当前系统时间和服务器时间的差值 (秒)
-   loger.warn("服务器时间:" + GlobalConfig.serverTime + "  系统时间:" + new Date().getTime() + "  时间差:" + GlobalConfig.serverAndLoacTimeDistanc);
-
-   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); //提前上传的声音文件列表
-   GlobalConfig.setVideoCDNAddr(_data.videoCDNAddr); //cdn加速的拉流地址,直播的时候才使用
-   GlobalConfig.setMediaShareList(_data.sharedMediaList); //提前上传的媒体共享文件列表
-
-   //MCU地址
-   if (_data.mcuList && _data.mcuList.length > 0) {
-   //随机选择一个
-   let index = parseInt(Math.random() * _data.mcuList.length);
-   GlobalConfig.MCUServerIP = _data.mcuList[index].ip || "";
-   GlobalConfig.MCUServerPort = _data.mcuList[index].port || "";
-   loger.log('初始->MCU->.', GlobalConfig.MCUServerIP, GlobalConfig.MCUServerPort);
-   }
-
-   //录制回放时m3u8播流地址
-   if (_data.rsList && _data.rsList.length > 0) {
-   let index = parseInt(Math.random() * _data.rsList.length);
-   GlobalConfig.RS_RECORD_PLAY_IP = _data.rsList[index].ip || "";
-   GlobalConfig.RS_RECORD_PLAY_PORT = _data.rsList[index].port || "";
-   loger.log('初始->RS->.', GlobalConfig.RS_RECORD_PLAY_IP, GlobalConfig.RS_RECORD_PLAY_PORT);
-   }
-
-   //上课中音视频推流地址
-   if (GlobalConfig.msList && GlobalConfig.msList.length > 0) {
-   let index = parseInt(Math.random() * GlobalConfig.msList.length);
-   GlobalConfig.MS_PUBLISH_IP = GlobalConfig.msList[index].ip || "";
-   GlobalConfig.MS_PUBLISH_PORT = GlobalConfig.msList[index].port || "";
-   }
-   loger.log('初始->MS->.', GlobalConfig.MS_PUBLISH_IP, GlobalConfig.MS_PUBLISH_PORT);
-
-   //播流的地址和推流地址需要分开的时候,单独设置拉流的地址 rtmp(目前乐视使用)
-   if (GlobalConfig.rtmpPullList && GlobalConfig.rtmpPullList.length > 0) {
-   //有单独的rtmp拉流地址
-   let index = parseInt(Math.random() * GlobalConfig.rtmpPullList.length);
-   GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.rtmpPullList[index].ip || "";
-   GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.rtmpPullList[index].port || "";
-   } else {
-   //如果没有单独的rtmp拉流地址,和推流地址一样即可
-   GlobalConfig.MS_PLAY_RTMP_IP = GlobalConfig.MS_PUBLISH_IP;
-   GlobalConfig.MS_PLAY_RTMP_PORT = GlobalConfig.MS_PUBLISH_PORT;
-   }
-
-   loger.log('初始->MSPull->.', GlobalConfig.MS_PLAY_RTMP_IP, GlobalConfig.MS_PLAY_RTMP_PORT);
-
-   //播流的地址和推流地址需要分开的时候,单独设置拉流的地址 hls(目前乐视使用)
-   if (GlobalConfig.hlsList && GlobalConfig.hlsList.length > 0) {
-   //有单独的hls拉流地址
-   let index = parseInt(Math.random() * GlobalConfig.hlsList.length);
-   GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.hlsList[index].ip || "";
-   GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.hlsList[index].port || "";
-   } else {
-   //没有单独的hls拉流地址,和录制回放地址一样即可
-   GlobalConfig.MS_PLAY_HLS_IP = GlobalConfig.RS_RECORD_PLAY_IP;
-   GlobalConfig.MS_PLAY_HLS_PORT = GlobalConfig.RS_RECORD_PLAY_PORT;
-   }
-   loger.log('初始->MSHls->.', GlobalConfig.MS_PLAY_HLS_IP, GlobalConfig.MS_PLAY_HLS_PORT);
-
-   //直播的时候,拉流(rtmp和hls)需要从 videoCDNAddr中获取
-   //20170531-新规则,所有课堂类型都支持加速
-   // if(GlobalConfig.classType==ApeConsts.CLASS_TYPE_2&&GlobalConfig.videoCDNAddrList.length>0){
-
-   //20170629-直播课堂和移动端设备的时候支持
-   if (GlobalConfig.classType == ApeConsts.CLASS_TYPE_2 || GlobalConfig.isMobile) {
-   if (GlobalConfig.videoCDNAddrList.length > 0) {
-   //videoCDNAddrList中rtmppush和hls是混在一起的,需要分离开;
-   let listLen = GlobalConfig.videoCDNAddrList.length;
-   for (let i = 0; i < listLen; i++) {
-   let ipItem = GlobalConfig.videoCDNAddrList[i];
-   if (ipItem) {
-   if (ipItem.indexOf('hls') >= 0) {
-   //直播的时候m3u8拉流地址
-   GlobalConfig.MS_PLAY_HLS_IP = ipItem; //ip包含了端口
-   GlobalConfig.MS_PLAY_HLS_PORT = "";
-   loger.log('videoCDNAddr>初始->MSHls', GlobalConfig.MS_PLAY_HLS_IP);
-   }
-   if (ipItem.indexOf('rtmppull')>= 0) {
-   //直播的时候rtmp拉流地址
-   GlobalConfig.MS_PLAY_RTMP_IP = ipItem; //ip包含了端口
-   GlobalConfig.MS_PLAY_RTMP_PORT = '';
-   loger.log('videoCDNAddr->初始->MSPull', GlobalConfig.MS_PLAY_RTMP_IP);
-   }
-   }
-   }
-   } else {
-   loger.error('videoCDNAddr数据无效->', GlobalConfig.videoCDNAddr);
-   }
-   } else {
-   loger.warn('非直播课堂或不是移动端->不需要videoCDN加速');
-   }
-
-   //文档地址
-   if (_data.docList && _data.docList.length > 0) {
-   //doc上传地址,随机获取一个
-   let index = parseInt(Math.random() * _data.docList.length);
-   loger.log("docServer->", _data.docList[index]);
-   GlobalConfig.DOCServerIP = _data.docList[index].ip || "";
-   GlobalConfig.DOCServerPort = _data.docList[index].port || "";
-   loger.log('初始->DOC->.', GlobalConfig.DOCServerIP, GlobalConfig.DOCServerPort);
-   }
-
-   //record
-   if (_data.recordList && _data.recordList.length > 0) {
-   let index = parseInt(Math.random() * _data.recordList.length);
-   GlobalConfig.RecordServerIP = _data.recordList[index].ip || "";
-   GlobalConfig.RecordServerPort = _data.recordList[index].port || "";
-   loger.log('初始->RECORD->.', GlobalConfig.RecordServerIP, GlobalConfig.RecordServerPort);
-   }
-
-   }
-   //这里需要考虑是否加延迟处理,课堂信息刚获取完成,客户端需要根据数据创建界面UI,等创建完成后再加入课堂是最合适的(目前没有加延迟)
-   this._emit(MessageTypes.CLASS_GET_INFO_SUCCESS, GlobalConfig.getClassInfo());
-
-   if (_data.currentInfo) {
-   //根据从Sass获取的数据信息,同步最后一次保存的课堂状态信息
-   loger.log("本地同步最后一次保存过的课堂状态信息");
-   try {
-   GlobalConfig.setClassStatusInfo(JSON.parse(_data.currentInfo));
-   } catch (err) {
-   loger.warn("从Sass获取的课堂数据JSON转换失败->");
-   console.log("currentInfo", _data.currentInfo);
-   GlobalConfig.setClassStatusInfo(_data.currentInfo);
-   }
-   loger.log(GlobalConfig.classStatusInfo);
-   } else {
-   loger.log("还没有保存过课堂状信息");
-   }
-
-   //录制回放不需要获取ip信息和选点
-   if (GlobalConfig.isRecordPlayBack) {
-   if (_recordPlayback) {
-   //开启录制回放流程
-   loger.log("开启录制回放流程");
-   _recordPlayback.readyRecordPlay();
-   } else {
-   loger.warn("开启录制回放流程失败->还未创建模块");
-   }
-   } else {
-   //根据用户的userIp获取信息,选点
-   this.getUserIpInfo();
-   }
-   }*/
-
-  //ChatApe
-  // 发送聊天消息
-  _sendChatMsg(_messageInfo) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_messageInfo === null || EngineUtils.isEmptyObject(_messageInfo)) {
-      loger.log('发送聊天消息失败->参数错误', _messageInfo);
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_chat_ape) {
-      _chat_ape.sendChatMsg(_messageInfo);
-    }
-  }
-
-  //监听摄像头麦克风状态
-  userDeviecStatusChange(_data) {
-    /*   nodeId:GlobalConfig.nodeId,
-     userRole:GlobalConfig.userRole,
-     userName:GlobalConfig.userName,
-     userId:GlobalConfig.userId,
-     openCamera:GlobalConfig.openCamera,
-     openMicrophones:GlobalConfig.openMicrophones*/
-    if (_confer_ape) {
-      _confer_ape.updaterUserDeviecStatusChange(_data);
-    }
-  }
-
-  //屏幕共享
-  //开始屏幕共享
-  _publishScreenShare(_param) {
-    if (_video_ape) {
-      _video_ape.publishScreenShare(_param);
-    }
-  }
-
-  //停止屏幕共享
-  _stopPublishScreenShare(_param) {
-    if (_video_ape) {
-      _video_ape.stopPublishScreenShare(_param);
-    }
-  }
-
-  //VidoeApe
-  videoUpdate(_data) {
-    //视频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
-    if (_confer_ape) {
-      _confer_ape.updaterRosterStatus(_data);
-    }
-  }
-
-  _sendVideoBroadcastMsg(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_video_ape) {
-      return _video_ape.sendVideoBroadcastMsg(_param);
-    }
-  }
-
-  _getVideoPlayPath(_param) {
-    if (_video_ape) {
-      return _video_ape.getPlayVideoPath(_param);
-    }
-  }
-
-  _getVideoPublishPath(_param) {
-    if (_video_ape) {
-      return _video_ape.getPublishVideoPath(_param);
-    }
-  }
-
-  _getVideoAllChannelInfo(_param) {
-    if (_video_ape) {
-      return _video_ape.getAllChannelInfo(_param);
-    }
-  }
-
-  _publishVideo(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_video_ape) {
-      return _video_ape.publishVideo(_param);
-    }
-  }
-
-  _stopPublishVideo(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_video_ape) {
-      return _video_ape.stopPublishVideo(_param);
-    }
-  }
-
-  //AudioApe
-  audioUpdate(_data) {
-    //音频同步的消息发送改变,需要通知ferApe模块中的用户更新状态
-    if (_confer_ape) {
-      _confer_ape.updaterRosterStatus(_data);
-    }
-  }
-
-  sendAudioCommandMsg(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_audio_ape) {
-      return _audio_ape.sendAudioBroadcastMsg(_param);
-    }
-  }
-
-  _getPlayAudioPath(_param) {
-    if (_audio_ape) {
-      return _audio_ape.getAudioPlayPath(_param);
-    }
-  }
-
-  _getPublishAudioPath(_param) {
-    if (_audio_ape) {
-      return _audio_ape.getAudioPublishPath(_param);
-    }
-  }
-
-  _getAudioAllChannelInfo(_param) {
-    if (_audio_ape) {
-      return _audio_ape.getAllChannelInfo(_param);
-    }
-  }
-
-  _publishAudio(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    if (_audio_ape) {
-      return _audio_ape.publishAudio(_param);
-    }
-  }
-
-  _stopPublishAudio(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return {"code": ApeConsts.RETURN_FAILED, "data": ""};
-    }
-    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);
-    }
-  }
-
-  //CursorApe
-  // 添加鼠标同步
-  _sendInsertCursor(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_cursor_ape) {
-      _cursor_ape.sendInsertCursor(_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
-  //获取文档的所有资源地址
-  _getDocFullAddress(_param) {
-    if (_doc_ape) {
-      return _doc_ape.getDocFullAddress(_param);
-    } else {
-      loger.error("文档模块还没有创建无法获取");
-      return {"code": ApeConsts.RETURN_FAILED, "data": "文档模块还没有创建无法获取"};
-    }
-  }
-
-  //获取文档完整路径
-  _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);
-    }
-  }
-
-  //操作文档(页码上的动画步骤操作)
-  _sendDocumentSwitchAnimation(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_doc_ape) {
-      _doc_ape.documentSwitchAnimation(_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 && !GlobalConfig.isRecordPlayBack) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    //loger.log('Doc UpdateId ->');
-    //loger.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, "当前总人数:", GlobalConfig.rosterNumber, "sassDoclength=", GlobalConfig.docListPrepare.length);
-    //loger.log("docJoinChannelSuccess  docListPrepare=");
-    //如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
-    if (GlobalConfig.docListPrepare && GlobalConfig.docListPrepare.length > 0) {
-      //如果当前身份是老师或者当前课堂内只有一个人,有权限同步文档到MCU
-      if (GlobalConfig.isHost || GlobalConfig.rosterNumber <= 1) {
-        for (let i = 0; i < GlobalConfig.docListPrepare.length; i++) {
-          let value = GlobalConfig.docListPrepare[i];
-          if (value) {
-            //loger.log("判断是否需要把提前上传的文档上传到mcu", value);
-            let paramInfo = {
-              "pageNum": value.pdfSize,
-              "fileName": value.name,
-              "fileType": value.type,
-              "relativeUrl": value.relativeLocation,
-              "url": value.absoluteLocation,
-              "creatUserId": value.createUserID,
-              "docId": value.id,
-              "md5": value.MD5,
-              "visible": false
-            };
-            this._sendDocumentUpload(paramInfo);
-          }
-        }
-      }
-    }
-  }
-
-  //媒体共享模块的接口
-  //上传
-  _sendMediaSharedUpload(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_mediaShareApe) {
-      _mediaShareApe.mediaSharedUpload(_param);
-    }
-  }
-
-  //音乐共享模块的接口
-  //上传
-  _sendMusicSharedUpload(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_musicShareApe) {
-      _musicShareApe.musicSharedUpload(_param);
-    }
-  }
-
-  //Sass删除媒体文件数据
-  _sassDeletMediaShare(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-
-    //判断传入的参数是否存在
-    if (_param == null || EngineUtils.isEmptyObject(_param)) {
-      loger.error('删除媒体文件失败->参数错误', _param);
-      this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM);
-      return;
-    }
-    //判断必要的参数字段值
-    if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.fileId == null || _param.fileId == "") {
-      loger.error('删除媒体文件失败->', _param);
-      this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MEDIASHARE_DELETE_FAILED_PARAM);
-      return;
-    }
-    loger.log('删除媒体文件->', _param);
-
-    if (_sass) {
-      _sass.sassDeletMediaShare(_param);
-    }
-  }
-
-  // 删除Music
-  _sassDeletMusicShare(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-
-    //判断传入的参数是否存在
-    if (_param == null || EngineUtils.isEmptyObject(_param)) {
-      loger.error('删除媒体文件失败->参数错误', _param);
-      this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MUSICSHARE_DELETE_FAILED_PARAM);
-      return;
-    }
-    //判断必要的参数字段值
-    if (_param.itemIdx == null || isNaN(_param.itemIdx) || _param.fileId == null || _param.fileId == "") {
-      loger.error('删除媒体文件失败->', _param);
-      this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_MUSICSHARE_DELETE_FAILED_PARAM);
-      return;
-    }
-    loger.log('删除媒体文件->', _param);
-
-    if (_sass) {
-      _sass.sassDeletMusicShare(_param);
-    }
-  }
-
-  //删除媒体
-  _sendMediaSharedDelete(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_mediaShareApe) {
-      _mediaShareApe.mediaSharedDelete(_param);
-    }
-  }
-
-  //删除媒体
-  _sendMusicSharedDelete(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_musicShareApe) {
-      _musicShareApe.musicSharedDelete(_param);
-    }
-  }
-
-  //音乐更新
-  _sendMusicSharedUpdate(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_musicShareApe) {
-      _musicShareApe.musicSharedUpdate(_param);
-    }
-  }
-
-  //音乐播放
-  _sendMusicSharedPlay(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_musicShareApe) {
-      _musicShareApe.musicSharedPlay(_param);
-    }
-  }
-
-  //音乐停止
-  _sendMusicSharedStop(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_musicShareApe) {
-      _musicShareApe.musicSharedStop(_param);
-    }
-  }
-
-  //更新媒体文件的状态信息
-  _sendMediaSharedUpdate(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_mediaShareApe) {
-      _mediaShareApe.mediaSharedUpdate(_param);
-    }
-  }
-
-  //播放
-  _sendMediaSharedPlay(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_mediaShareApe) {
-      _mediaShareApe.mediaSharedPlay(_param);
-    }
-  }
-
-  //停止
-
-  _sendMediaSharedStop(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_mediaShareApe) {
-      _mediaShareApe.mediaSharedStop(_param);
-    }
-  }
-
-  //音乐共享模块加入频道成功,同步到MCU服务器上的数据
-  musicShareApeJoinChannelSuccess() {
-    loger.log("伴音MUSIC模块加入频道成功->isHost=", GlobalConfig.isHost, "length=", GlobalConfig.musicListPrepare.length);
-    console.log("伴音MUSIC模块共享模数据->", GlobalConfig.musicListPrepare);
-    //如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
-    if (GlobalConfig.isHost && GlobalConfig.musicListPrepare.length > 0) {
-      for (let i = 0; i < GlobalConfig.musicListPrepare.length; i++) {
-        let value = GlobalConfig.musicListPrepare[i];
-        if (value) {
-          let paramInfo = {
-            "status": 0,
-            "creatUserId": value.creatUserId,
-            "creatUserName": value.createUserName,
-            "url": value.url || value.absoluteLocation,//伴音上传的接口有差异,课堂内上传返回的是url字段,后台带入的字段是absoluteLocation
-            "fileType": value.type,
-            "fileId": "" + value.id,
-            "fileName": value.name,
-            "seek": 0
-          };
-          this._sendMusicSharedUpload(paramInfo);
-        }
-      }
-    }
-  }
-
-  //媒体共享模块加入频道成功,同步到MCU服务器上的数据
-  mediaShareApeJoinChannelSuccess() {
-    loger.log("媒体共享模块加入频道成功->isHost=", GlobalConfig.isHost, "length=", GlobalConfig.sharedMediaList.length);
-    console.log("媒体共享模数据->", GlobalConfig.sharedMediaList);
-    //如果是主持人,那么需要判断一下文档模块同步的数据和从sass获取的文档数据是否相同,如果mcu服务器不存在的,需要上传
-    if (GlobalConfig.isHost && GlobalConfig.sharedMediaList.length > 0) {
-      for (let i = 0; i < GlobalConfig.sharedMediaList.length; i++) {
-        let value = GlobalConfig.sharedMediaList[i];
-        if (value) {
-          let paramInfo = {
-            "status": 0,
-            "creatUserId": value.creatUserId,
-            "creatUserName": value.createUserName,
-            "url": value.url,
-            "fileType": value.type,
-            "fileId": "" + value.id,
-            "fileName": value.name,
-            "seek": 0
-          };
-          this._sendMediaSharedUpload(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 (_recordPlayback) {
-      _recordPlayback.startRecordPlayback(_param);
-    }
-  }
-
-  //停止录制回放
-  _stopRecordPlayback(_param) {
-    if (_recordPlayback) {
-      _recordPlayback.stopRecordPlayback(_param);
-    }
-  }
-
-  //暂停录制回放
-  _pauseRecordPlayback(_param) {
-    if (_recordPlayback) {
-      _recordPlayback.pauseRecordPlayback(_param);
-    }
-  }
-
-  //seek录制回放
-  _seekRecordPlayback(_param) {
-    if (_recordPlayback) {
-      _recordPlayback.seekRecordPlayback(_param);
-    }
-  }
-
-  //录制回放状态更新
-  _recordPlaybackClearDataHandler(_param) {
-    loger.log("录制回放状态更新->")
-    if (_doc_ape) {
-      _doc_ape.clearData();
-    }
-    if (_whiteboard_ape) {
-      _whiteboard_ape.clearData();
-    }
-    if (_video_ape) {
-      _video_ape.clearData();
-    }
-  }
-
-  //录制回放加入 课堂成功
-  _joinRecordPlaybackSuccessHandler(_data) {
-    loger.log('加入录制回放成功.');
-    GlobalConfig.setCurrentStatus(GlobalConfig.statusCode_2);
-
-    //返回给客户端初始化成功的数据
-    let joinClassSuccessCallBackData = {};
-
-    joinClassSuccessCallBackData.isRecordPlayBack = GlobalConfig.isRecordPlayBack;
-
-    joinClassSuccessCallBackData.DOCServerIP = GlobalConfig.DOCServerIP;
-    joinClassSuccessCallBackData.DOCServerPort = GlobalConfig.DOCServerPort;
-
-    joinClassSuccessCallBackData.classStatus = GlobalConfig.classStatus;
-    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.maxMediaChannels = GlobalConfig.maxMediaChannels;
-
-    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_1;
-
-    joinClassSuccessCallBackData.country = GlobalConfig.country; //国家
-    joinClassSuccessCallBackData.city = GlobalConfig.city; //城市
-    joinClassSuccessCallBackData.province = GlobalConfig.province; //服务商
-    joinClassSuccessCallBackData.isp = GlobalConfig.isp; //服务商
-
-    joinClassSuccessCallBackData.classTimestamp = GlobalConfig.classTimestamp; //课堂进行的累积时间
-    joinClassSuccessCallBackData.recordTimestamp = GlobalConfig.recordTimestamp; //录制累积的总时间
-    joinClassSuccessCallBackData.recordPlaybackMaxTime = GlobalConfig.recordPlaybackMaxTime; //录制回放的总时间
-
-    joinClassSuccessCallBackData.fps = GlobalConfig.fps;
-    joinClassSuccessCallBackData.gop = GlobalConfig.gop;
-    joinClassSuccessCallBackData.videoQuality = GlobalConfig.videoQuality;
-
-    joinClassSuccessCallBackData.ssTunnelAppURL = GlobalConfig.ssTunnelAppURL;
-    joinClassSuccessCallBackData.currentSceneTableId = GlobalConfig.currentSceneTableId; //文档区域的模块显示
-    joinClassSuccessCallBackData.serverAndLoacTimeDistanc = GlobalConfig.serverAndLoacTimeDistanc;
-
-    joinClassSuccessCallBackData.deviceType = GlobalConfig.deviceType;
-    joinClassSuccessCallBackData.language = GlobalConfig.language;
-    joinClassSuccessCallBackData.explorer = GlobalConfig.explorer;
-    joinClassSuccessCallBackData.explorerVersion = GlobalConfig.explorerVersion;
-    joinClassSuccessCallBackData.os = GlobalConfig.os;
-
-    loger.log(joinClassSuccessCallBackData);
-    //和加入课堂成功使用同样的消息处理
-    this._emit(MessageTypes.CLASS_JOIN_SUCCESS, joinClassSuccessCallBackData);
-  }
-
-  // //答题卡
-  _creatQuestion(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_questionApe) {
-      _questionApe.creatQuestion(_param);
-    }
-  }
-
-  _getQuestion(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_questionApe) {
-      _questionApe.getQuestion(_param);
-    }
-  }
-
-  _getQuestionResult(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_questionApe) {
-      _questionApe.getQuestionResult(_param);
-    }
-  }
-
-  _stopQuestion(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_questionApe) {
-      _questionApe.stopQuestion(_param);
-    }
-  }
-
-  _sendAnswer(_param) {
-    if (!_mcu.connected) {
-      loger.warn(GlobalConfig.getCurrentStatus());
-      return;
-    }
-    if (_questionApe) {
-      _questionApe.sendAnswer(_param);
-    }
-  }
-
-}
-
diff --git a/src/GlobalConfig.js b/src/GlobalConfig.js
index 5c51830..99a3eae 100644
--- a/src/GlobalConfig.js
+++ b/src/GlobalConfig.js
@@ -135,7 +135,8 @@ class GlobalConfig {
     this.classTimestamp = data.classTimestamp || this.classTimestamp; //相对于点开始课堂的时间戳
 
 
-    this.recordStatus = data.recordStatus || this.recordStatus; //当前录制状态
+    //this.recordStatus = data.recordStatus || this.recordStatus; //当前录制状态
+    this.recordStatus = data.recordStatus ||false; //当前录制状态
     this.recordTimestamp = data.recordTimestamp || this.recordTimestamp; //相对于首次开始录制的时间戳
     this.recordFileName = data.recordFileName || this.recordFileName; //录制的文件名
     this.recordDownloadUrl = data.recordDownloadUrl || this.recordDownloadUrl; //下载地址
@@ -522,7 +523,7 @@ GlobalConfig.recordReplaytickValues = {}; // 滚动条关键点,用于快进�
 
 GlobalConfig.isAutoStartClass = 0; //是否自动开始上课 0-否 ;1 是
 
-GlobalConfig.updateClassInfoDelay = 30; //(秒),每隔30秒同步一次课堂状态的并保存到Sass
+GlobalConfig.updateClassInfoDelay = 20; //(秒),每隔30秒同步一次课堂状态的并保存到Sass
 GlobalConfig.msDynamicChooseIpDelay = 60 * 3; //(秒)MS动态选点的间隔
 //GlobalConfig.serverTimestamp=0;//当前的系统时间戳 用get  set 获取
 
@@ -540,7 +541,7 @@ GlobalConfig.classDetail = {}; //Sass直接返回的当前课堂基本信息
 
 
 GlobalConfig.isRecordPlayBack = false; //是否是录制回放,默认是否
-GlobalConfig.allowRecordMaxTime = 24*60*60; //(秒)允许录制的最长时间
+GlobalConfig.allowRecordMaxTime = 48*60*60; //(秒)允许录制的最长时间
 
 GlobalConfig.siteId_letv = 'shchuanbao'; //乐视,MS不需要动态选点的站点
 GlobalConfig.ssTunnelAppURL = ''; //屏幕共享插件的地址
diff --git a/src/apes/ConferApe.js b/src/apes/ConferApe.js
index e723bc1..366675f 100644
--- a/src/apes/ConferApe.js
+++ b/src/apes/ConferApe.js
@@ -7,7 +7,6 @@ import ApeConsts from './ApeConsts';
 import ThirdMessage from './ThirdMessage';
 import MessageTypes from 'MessageTypes';
 import pdu from 'pdus';
-//import { Zlib } from 'zlibjs/bin/zlib.min';
 import UTF8 from 'utf-8';
 import Loger from 'Loger';
 import GlobalConfig from 'GlobalConfig';
@@ -28,6 +27,7 @@ class ConferApe extends Ape {
     this.rosters = {}; //用户列表
     this.rosterLen = 0;//当前课堂人数
     this.timerCounter = new TimerCounter(); //计时器
+    this.startClassTimer;//开始课堂和开始录制的计时器
 
     //第三方消息控制 parent和Iframe直接的通讯
     this.thirdMessage = new ThirdMessage();
@@ -246,7 +246,6 @@ class ConferApe extends Ape {
 
     //保存当前的录制状态
     GlobalConfig.recordStatus = _param.recordStatus || false;
-
     let conferRecordSendPdu = new pdu['RCConferenceRecordRequestPdu'];
     conferRecordSendPdu.type = pdu.RCPDU_CONFERENCE_RECORD_REQUEST;
     conferRecordSendPdu.peer = 0; //channel 为0
@@ -257,9 +256,12 @@ class ConferApe extends Ape {
     //conferRecordSendPdu.classTime = GlobalConfig.classTimestamp;//不能使用课堂进行时间,这个时间结束课堂的时候会被清除
     conferRecordSendPdu.classTime = GlobalConfig.recordTimestamp; //课堂录制的累积时间,不会被清除
     conferRecordSendPdu.filename = GlobalConfig.recordFileName || GlobalConfig.classId + "_" + EngineUtils.creatTimestampYMD() + ".rec";
+    if(GlobalConfig.recordStatus){
+      loger.log("发送录制的指令->开启",conferRecordSendPdu);
+    }else {
+      loger.log("发送录制的指令->停止",conferRecordSendPdu);
+    }
     this.sendChatUniform(conferRecordSendPdu);
-    // to, message
-    loger.warn('发送录制消息-》', _param);
   }
 
   //开启录制
@@ -270,22 +272,27 @@ class ConferApe extends Ape {
       return;
     }
 
-    loger.warn('开启录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
-    //如果是host
-    if (GlobalConfig.isHost) {
-      GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
-      this.sendConferRecordMsg({"recordStatus": true});
-      this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
-      this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制
+    //如果是host或者当前课堂只有1个人
+    if (GlobalConfig.isHost||this.rosterLen<=1) {
+      if(GlobalConfig.recordStatus){
+        loger.warn("课堂已经是录制状态不->不需要再开启,isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus,"当前人数:"+this.rosterLen);
+      }else{
+        loger.warn('开启录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus,"当前人数:"+this.rosterLen);
+        GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
+        this.sendConferRecordMsg({"recordStatus": true});
+        this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
+        this._emit(MessageTypes.CLASS_RECORD_START); //课堂开始录制
+      }
+
     }
   }
 
   //停止录制
   stopRecord(isForce) {
-    loger.warn('停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
-    if (isForce && isForce == true) {
+   /* if (isForce && isForce == true) {
       //强制停止,可以是host之外的身份(比如当前课堂老师异常退出,没有老师,会随机选择一个人来做释放操作)
       if (GlobalConfig.recordStatus) {
+        loger.warn('停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
         GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
         this.sendConferRecordMsg({"recordStatus": false});
         this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
@@ -297,6 +304,15 @@ class ConferApe extends Ape {
         this.sendConferRecordMsg({"recordStatus": false});
         this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
       }
+    }*/
+    //身份是host
+    if (GlobalConfig.isHost) {
+      loger.warn('停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
+      GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
+      this.sendConferRecordMsg({"recordStatus": false});
+      this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
+    }else {
+      loger.warn('没有权限停止录制', "isHost", GlobalConfig.isHost, "recordStatus", GlobalConfig.recordStatus);
     }
   }
 
@@ -339,9 +355,10 @@ class ConferApe extends Ape {
     GlobalConfig.classTimestamp = 0;
     GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_WAIT;
     GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
-    this.stopRecord();
+    //this.stopRecord();//停止录制的接口单独调用
     this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
-    this.sendUpdaterClassStatusInfo({"actionType": 0, isStopAllPublishMedia: true});
+    //this.sendUpdaterClassStatusInfo({"actionType": 0, isStopAllPublishMedia: true});
+    this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_WAIT, isStopAllPublishMedia: false});
     loger.log('restorClass');
   }
 
@@ -376,7 +393,6 @@ class ConferApe extends Ape {
   //开始上课
   startClass(_param) {
     if (GlobalConfig.isHost) {
-
       let timestamp = EngineUtils.creatTimestampStr();
       GlobalConfig.classStopTime = timestamp;
 
@@ -391,13 +407,13 @@ class ConferApe extends Ape {
       }
 
       GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_STARTED;
-      //开始录制
-      this.startRecord();
-      //课堂状态改变
-      this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
+      ////开始录制
+      //this.startRecord();
+      ////课堂状态改变
+      //this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
       //同步课堂状态
-      this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: true});
-
+      //this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: true});
+      this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
       //开始计时
       this.startTimerCounter();
     } else {
@@ -414,9 +430,10 @@ class ConferApe extends Ape {
     GlobalConfig.classStatus = ApeConsts.CLASS_STATUS_PAUSE;
     GlobalConfig.classStopTime = EngineUtils.creatTimestampStr();
 
-    this.stopRecord();
+    //this.stopRecord();
     this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE, _param);
-    this.sendUpdaterClassStatusInfo({"actionType": 2, isStopAllPublishMedia: true});
+    //this.sendUpdaterClassStatusInfo({"actionType": 2, isStopAllPublishMedia: true});
+    this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_PAUSE, isStopAllPublishMedia: false});
     this.stopTimerCounter();
   }
 
@@ -426,11 +443,12 @@ class ConferApe extends Ape {
       loger.warn('还没有开始,不能点关闭');
       return;
     }
-
+    loger.warn("调用关闭课堂->");
     this.stopTimerCounter();
     this.restorClass();
     //把所有人都踢出课堂
     this.sendConferMsg({"to": 0, "message": "所有人退出课堂", "actionType": ApeConsts.CLASS_ACTION_CLOSE_ALL});
+    this.stopRecord();//关闭课堂的时候停止录制
   }
 
   //更新设备信息
@@ -525,7 +543,7 @@ class ConferApe extends Ape {
         //保存数据到Sass
         this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
         //同步消息给其他人
-        this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: false});
+        this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
       }
     }
 
@@ -542,7 +560,6 @@ class ConferApe extends Ape {
     }
     let itemIdx = ApeConsts.CONFERENCE_OBJ_TABLE_ID; // itemIdx=_param.itemIdx;
     let modelPdu = this.packPdu(_param, itemIdx);
-    loger.log(modelPdu);
     if (modelPdu == null) {
       loger.log('发送更新课堂信息->参数错误');
       this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
@@ -582,14 +599,32 @@ class ConferApe extends Ape {
   /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
   //加入channel成功
   onJoinChannelHandlerSuccess() {
-    loger.log('ConferApe.onJoinChannelHandlerSuccess', GlobalConfig.classStatus);
+    if(GlobalConfig.isRecordPlayBack){
+      loger.log('课堂模块初始完成->当前是录制回放:'+ GlobalConfig.classStatus);
+      return;
+    }
+    loger.log('课堂模块初始完成->当前课堂状态:'+ GlobalConfig.classStatus,"recordStatus:"+GlobalConfig.recordStatus);
     this.timerCounter.addTimerCallBack(this.timerCounterUptate.bind(this), 1);
-    //如果当前课堂正在进行中,开启计时器
+    //2秒后执行开始上课和开始录制的判断逻辑
+    clearTimeout(this.startClassTimer);
+    this.startClassTimer=setTimeout(()=>{
+      //开启录制,录制接口中会自动判断是否需要录制
+      this.startRecord();
+      //如果当前课堂正在进行中,开启计时器
+      if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
+        //开始计时
+        this.startTimerCounter();
+        //this.startRecord();
+      } else {
+        loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:", GlobalConfig.isHost, " isAutoStartClass:", GlobalConfig.isAutoStartClass, " isRecordPlayBack:", GlobalConfig.isRecordPlayBack);
+        this.startClass();
+      }
+    },2000);
+
+   /* //如果当前课堂正在进行中,开启计时器
     if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
       //开始计时
       this.startTimerCounter();
-
-      //如果是host ,开始录制
       this.startRecord();
     } else if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_WAIT &&
       GlobalConfig.isHost && GlobalConfig.isAutoStartClass && !GlobalConfig.isRecordPlayBack) {
@@ -597,7 +632,8 @@ class ConferApe extends Ape {
       //1.如果自己是host,2.Sass配置的是自动开始上课,3.并且当前是未开始状态,4.当前不是录制回放,开始自动上课
       loger.log('自动开始上课->classStatus:', GlobalConfig.classStatus, " isHost:", GlobalConfig.isHost, " isAutoStartClass:", GlobalConfig.isAutoStartClass, " isRecordPlayBack:", GlobalConfig.isRecordPlayBack);
       this.startClass();
-    }
+    }*/
+
   }
 
   //开启计时器
@@ -606,7 +642,6 @@ class ConferApe extends Ape {
     if (this.timerCounter) {
       this.timerCounter.startTimer();
     }
-
   }
 
   //停止计时器
@@ -621,46 +656,92 @@ class ConferApe extends Ape {
     if (!this.mcu.connected) {
       loger.warn('MCU 连接已经断开');
       this.stopTimerCounter();
-    }
-    //如果还没开始或已经暂停、关闭,不做计时处理
-    if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {
-      loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);
       return;
     }
-    GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时
+    //课堂开始的状态下,课堂进行时间和录制时间都需要更加,录制时间会大于或等于课堂开始的累积时间
+    if (GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
+      GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时
+      //老师身份的时候要记录录制的时间
+      if (GlobalConfig.isHost||this.rosterLen<=1) {
+        GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
+      }
+      //向应用层更新当前课堂进行的时间长度 (秒)
+      this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
+
+      //以一定的时间间隔同步课堂内所有人的累积上课时间
+      if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
+        //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
+        if (GlobalConfig.isHost||this.rosterLen<=1) {
+          //保存数据到Sass
+          this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
+          //同步消息给其他人
+          this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
+        }
+      }
 
-    //老师身份的时候要记录录制的时间
-    if (GlobalConfig.isHost) {
-      GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
+      //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
+      if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
+        //MS推流选点
+        this._emit(MessageTypes.SWITCH_MS_IP);
+        //MS拉流选点
+        this._emit(MessageTypes.SWITCH_RTMP_PULL_IP);
+        //HLS拉流选点
+        this._emit(MessageTypes.SWITCH_HLS_IP);
+      }
+    }else {
+      //课堂暂停或未开始的情况下,如果已经开始录制,需要更新录制的时间
+      if (GlobalConfig.isHost||this.rosterLen<=1) {
+        GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
+        //以一定的时间间隔同步课堂内所有人的累积上课时间
+        if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
+            //保存数据到Sass
+            this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
+            //同步消息给其他人
+            this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
+        }
+      }
     }
-    //loger.log('课堂进行时间',GlobalConfig.classTimestamp);
-    this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
 
-    if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
-      //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
-      if (GlobalConfig.isHost) {
-        //保存数据到Sass
-        this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
+   /* //如果还没开始或已经暂停、关闭,不做计时处理
+     if (GlobalConfig.classStatus != ApeConsts.CLASS_STATUS_STARTED) {
+     loger.warn('当前课堂已经暂停或者未开始,不计时', "classStatus-->", GlobalConfig.classStatus);
+     return;
+     }
+     GlobalConfig.classTimestamp = GlobalConfig.classTimestamp + 1; //计时
 
-        //同步消息给其他人
-        this.sendUpdaterClassStatusInfo({"actionType": 1, isStopAllPublishMedia: false});
-      }
-    }
+     //老师身份的时候要记录录制的时间
+     if (GlobalConfig.isHost) {
+     GlobalConfig.recordTimestamp = GlobalConfig.recordTimestamp + 1;
+     }
+     //向应用层更新当前课堂进行的时间长度 (秒)
+     this._emit(MessageTypes.CLASS_UPDATE_TIMER, {"classTimestamp": GlobalConfig.classTimestamp});
+
+     //以一定的时间间隔同步课堂内所有人的累积上课时间
+     if (GlobalConfig.classTimestamp % GlobalConfig.updateClassInfoDelay == 0) {
+     //如果是host身份,需要同步时间给其他人,同时把当前的状态上传到服务器
+     if (GlobalConfig.isHost) {
+     //保存数据到Sass
+     this._emit(MessageTypes.CLASS_STATUS_INFO_CHANGE);
+     //同步消息给其他人
+     this.sendUpdaterClassStatusInfo({"actionType": ApeConsts.CLASS_STATUS_STARTED, isStopAllPublishMedia: false});
+     }
+     }
 
-    //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
-    if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
-      //MS推流选点
-      this._emit(MessageTypes.SWITCH_MS_IP);
-      //MS拉流选点
-      this._emit(MessageTypes.SWITCH_RTMP_PULL_IP);
-      //HLS拉流选点
-      this._emit(MessageTypes.SWITCH_HLS_IP);
-    }
+     //进行MS动态选点,选择最快的MS服务器地址(录制回放不做处理)
+     if (!GlobalConfig.isRecordPlayBack && GlobalConfig.classTimestamp % GlobalConfig.msDynamicChooseIpDelay == 0) {
+     //MS推流选点
+     this._emit(MessageTypes.SWITCH_MS_IP);
+     //MS拉流选点
+     this._emit(MessageTypes.SWITCH_RTMP_PULL_IP);
+     //HLS拉流选点
+     this._emit(MessageTypes.SWITCH_HLS_IP);
+     }*/
   }
 
   tableUpdateHandler(owner, itemIdx, itemData) {
     try {
       let model = this.unPackPdu(owner, itemIdx, itemData);
+      loger.log("课堂更新->",model);
       //处理课堂更新的信息
       if (model && model.classStatusInfo) {
         try {
@@ -668,9 +749,7 @@ class ConferApe extends Ape {
         } catch (err) {
 
         }
-
         GlobalConfig.setClassStatusInfo(model.classStatusInfo);
-
         if (model.classStatusInfo.isStopAllPublishMedia) {
           //课堂状态发送改变 需要对当前正在推的流进行停止,因为录制的问题;
           this._emit(MessageTypes.STOP_ALL_MEDIA_PUBLISH);
@@ -697,16 +776,11 @@ class ConferApe extends Ape {
         this.stopTimerCounter();
       }
     } catch (err) {
-      loger.warn('ConferApe table update got exception->err', err.message);
+      loger.warn('课堂更新->error', err.message);
     }
   }
 
   conferMsgComingHandler(_data) {
-    //flash    RCConferenceSendDataRequestPdu
-    //loger.warn('conferMsgComingHandler needs to be handled.');
-    //const recordInfo = pdu['RCWhiteboardDataRequestPdu'].decode(pdu);
-    //loger.log("conferMsgComingHandler",recordInfo);
-
     let chatReceivePdu = pdu['RCConferenceSendDataRequestPdu'].decode(_data);
 
     let chatMsg = {};
@@ -823,19 +897,26 @@ class ConferApe extends Ape {
 
   //------------------第三方消息 end-----------------------------------------
 
+  //监听MCU录制状态消息
   onSendConferRecordRequestHandler(_data) {
     try {
       let conferRecordSendPdu = pdu['RCConferenceRecordRequestPdu'].decode(_data);
-      // {"initiator":820461225,"record":false,"classTime":3213,"filename":"h5dev/20170410/1437784290_20170410.rec"}
-      loger.log("录制回放控制操作成功->", conferRecordSendPdu);
-      if (conferRecordSendPdu && conferRecordSendPdu.record == true || conferRecordSendPdu.record == "true") {
-        //每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件
-        this._emit(MessageTypes.CLASS_RECORD_SUCCESS);
+      //{"initiator":564398684,"record":true,"classTime":39,"filename":"markettest/20170823/1096250804_20170823.rec"}//开启成功
+      //{"initiator":564398684,"record":false,"classTime":39,"filename":"markettest/20170823/1096250804_20170823.rec"} //停止成功
+      loger.warn("录制回放控制操作成功->", conferRecordSendPdu);
+      if (conferRecordSendPdu ){
+        if(conferRecordSendPdu.record == true || conferRecordSendPdu.record == "true") {
+          //每次开启录制的时候,需要把当前显示的文档数据更新一次,否则无法录制已经显示的文件
+          loger.warn("MCU已经开启录制");
+          this._emit(MessageTypes.CLASS_RECORD_SUCCESS);
+        }else{
+          //停止录制成功
+          loger.warn("MCU已经停止录制");
+        }
       }
     } catch (err) {
-      loger.warn("录制回放控制操作错误->", err.message);
+      loger.error("录制回放控制操作错误->", err.message);
     }
-
   }
 
   rosterInsertHandler(nodeId, nodeData) {
@@ -858,10 +939,10 @@ class ConferApe extends Ape {
       // 1.当前课堂只有自己;2.自己的身份不是host;3当前的课堂状态为(CLASS_STATUS_STARTED= 1;//直播中)
       this.rosterLen = Object.keys(this.rosters).length;
       GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
-      if (this.rosterLen < 1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
+      if (this.rosterLen <=1 && !GlobalConfig.isHost && GlobalConfig.classStatus == ApeConsts.CLASS_STATUS_STARTED) {
         loger.warn("当前课堂没有老师->暂停课堂");
         this.pauseClass({isForce: true});
-        this.stopRecord(true);
+        //this.stopRecord(true);
       }
       //处理用户信息
       this.unPackRosterInfo(nodeId, nodeData);
@@ -882,10 +963,11 @@ class ConferApe extends Ape {
         deviceType: nodeData.deviceType
       }
       if (nodeData.role == ApeConsts.NR_HOST && GlobalConfig.isHost) {
+        loger.warn("相同身份的人进入->自己被踢出->进入的人员信息", nodeData);
         this.kickOutRoster(newUserInfo);
         return;
       } else if (nodeData.userId == GlobalConfig.userId && GlobalConfig.userId != "0") {
-        loger.log("异地登陆->userId->", GlobalConfig.userId);
+        loger.warn("异地登陆->userId->", GlobalConfig.userId);
         this._emit(MessageTypes.MCU_ERROR, {type:MessageTypes.ERR_CLASS_REMOTE_LANDING, data:newUserInfo});
         this._emit(MessageTypes.CLASS_RUN_EXIT, {'type': 1});
       }
@@ -929,14 +1011,14 @@ class ConferApe extends Ape {
     newNodeData.userData = userDataObj;
     //如果是监课,不告诉其他人
     if (nodeData.role == ApeConsts.NR_INVISIBLE && GlobalConfig.userRole != ApeConsts.invisible) {
-      loger.log("NR_INVISIBLE");
+      loger.log("监课进入或更新数据");
       return;
     }
     if (!rosterExists) {
       this.rosterLen = Object.keys(this.rosters).length;
       GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
       newNodeData.rosterLen = this.rosterLen;
-      //loger.log("人员加入->", newNodeData);
+      loger.log("人员加入->", newNodeData);
       this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
       this.emitRosterChange();
     } else {
@@ -944,7 +1026,9 @@ class ConferApe extends Ape {
       this.rosterLen = Object.keys(this.rosters).length;
       GlobalConfig.rosterNumber = this.rosterLen;//记录当前的总人数
       newNodeData.rosterLen = this.rosterLen;
-      loger.log("人员更新信息->", newNodeData);
+      if(nodeId!=GlobalConfig.nodeId){
+        loger.log("人员更新信息->", newNodeData);
+      }
       this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
     }
   }
@@ -970,33 +1054,6 @@ class ConferApe extends Ape {
       loger.log("媒体模块被占用->占有人已经不存在课堂中->释放->", _param);
       this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
     }
-
-    /* if (_param && _param.status == ApeConsts.CHANNEL_STATUS_OPENING) {
-     if(this.rosters[_param.fromNodeId] == null){
-     loger.log("媒体模块被占用,占有人已经不存在课堂中,释放Channel,_param->", _param);
-     this._emit(MessageTypes.CLASS_NONENTITY_ROSTER, {"nodeId": _param.fromNodeId});
-     }
-
-     //如果音视频消息是自己的,需要设置麦克风和摄像头状态
-     if(_param.fromNodeId==GlobalConfig.nodeId){
-     if(_param.mediaId==ApeConsts.MEDIA_TYPE_AUDIO){
-     GlobalConfig.openMicrophones=EngineUtils.creatTimestamp();
-     GlobalConfig.openCamera=0;
-     }else {
-     GlobalConfig.openCamera=EngineUtils.creatTimestamp();
-     GlobalConfig.openMicrophones=GlobalConfig.openCamera;
-     }
-     this.updateUserInfo();
-     }
-
-     }else  if (_param && _param.status == ApeConsts.CHANNEL_STATUS_RELEASED) {
-     //如果音视频消息是自己的,需要设置麦克风和摄像头状态
-     if(_param.fromNodeId==GlobalConfig.nodeId){
-     GlobalConfig.openCamera=0;
-     GlobalConfig.openMicrophones=0;
-     this.updateUserInfo();
-     }
-     }*/
   }
 
   //设备状态更新
@@ -1034,8 +1091,10 @@ class ConferApe extends Ape {
 
           if (user && user.role == ApeConsts.NR_HOST) {
             this.pauseClass();
-            //强制停止录制
-            this.stopRecord(true);
+
+           /* //强制停止录制
+            this.stopRecord(true)*/;
+
           }
         } else {
           loger.warn(GlobalConfig.nodeId, "没有权限检查离开的人员是否占用channel");
@@ -1080,7 +1139,7 @@ class ConferApe extends Ape {
     classStatusInfo.serverTimestamp = GlobalConfig.serverTimestamp; //当前的系统时间戳
     classStatusInfo.activeDocId = GlobalConfig.activeDocId; //当前激活的文档id
     classStatusInfo.activeDocCurPage = GlobalConfig.activeDocCurPage; //当前激活的文档的当前页
-    classStatusInfo.isStopAllPublishMedia = _param.isStopAllPublishMedia || false;
+    classStatusInfo.isStopAllPublishMedia = Boolean(_param.isStopAllPublishMedia) || false;
     classStatusInfo.currentSceneTableId = GlobalConfig.currentSceneTableId;
     classStatusInfo.silence = GlobalConfig.silence;
     classStatusInfo.silenceUsers = JSON.stringify(GlobalConfig.silenceUsers);
diff --git a/src/ss.js b/src/ss.js
deleted file mode 100644
index 51c7432..0000000
--- a/src/ss.js
+++ /dev/null
@@ -1 +0,0 @@
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.share=t():e.share=t()}(this,function(){return function(e){function t(n){if(_[n])return _[n].exports;var a=_[n]={exports:{},id:n,loaded:!1};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var _={};return t.m=e,t.c=_,t.p="",t(0)}([function(e,t,_){e.exports=_(2)},function(e,t){"use strict";function _(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var _=0;_<t.length;_++){var n=t[_];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,_,n){return _&&e(t.prototype,_),n&&e(t,n),t}}(),a=function(){function e(){_(this,e),this.MAPS={}}return n(e,[{key:"on",value:function(e,t){if(e&&t){var _=this.MAPS[e];if(!_)return this.MAPS[e]=[t];_.push(t)}}},{key:"off",value:function(e,t){if(e){var _=this.MAPS[e];if(_){if(t)return _.splice(_.indexOf(t),1);_.length=0}}}},{key:"emit",value:function(e,t){if(e){var _=this.MAPS["*"];_&&_.length&&_.forEach(function(_){_(e,t)});var n=this.MAPS[e];n&&n.length&&n.forEach(function(e){e(t)})}}}]),e}();t.default=a},function(e,t,_){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function a(e){var t,_,n,a;n=e.length,t=new Uint8Array(3*n);var r=0;for(_=0;_<n;_++)a=e.charCodeAt(_),a>=1&&a<=127?t[r++]=a:a>2047?(t[r++]=224|a>>12&15,t[r++]=128|a>>6&63,t[r++]=128|a>>0&63):(t[r++]=192|a>>6&31,t[r++]=128|a>>0&63);return new Uint8Array(t.buffer,0,r)}function r(e){var t,_,n,a,r,o;for(t="",n=e.length,_=0;_<n;)switch(a=e[_++],a>>4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:t+=String.fromCharCode(a);break;case 12:case 13:r=e[_++],t+=String.fromCharCode((31&a)<<6|63&r);break;case 14:r=e[_++],o=e[_++],t+=String.fromCharCode((15&a)<<12|(63&r)<<6|(63&o)<<0)}return t}function o(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",_=new Object;if(_.data_len=0,_.data="",_.name=e,"mov_start"==e)_.type=1;else if("mov_stop"==e)_.type=2;else if("mov_pause"==e){if(_.type=3,pos=t,pos.length>0){_.data_len=4;var n=new ArrayBuffer(_.data_len),r=new Uint32Array(n,0,1);r[0]=parseInt(pos),_.data=new Uint8Array(n,0,4)}}else if("mov_resume"==e)_.type=4;else if("mov_seek"==e){if(_.type=5,pos=t,pos.length>0){_.data_len=4;var n=new ArrayBuffer(_.data_len),r=new Uint32Array(n,0,1);r[0]=parseInt(pos),_.data=new Uint8Array(n,0,4)}}else if("ss_start"==e)_.type=6,_.data=a(t),_.data_len=_.data.length;else if("ss_stop"==e)_.type=7;else if("ss_version"==e)_.type=14;else if("get_mic"==e)_.type=26;else{if("ds_start"==e){_.type=27,_.data_len=536;var n=new ArrayBuffer(_.data_len),o=new Uint32Array(n,0,6);coordstr=t;var i=coordstr.split(",");if(4!=i.length)return;o[0]=parseInt(i[0]),o[1]=parseInt(i[1]),o[2]=parseInt(i[2]),o[3]=parseInt(i[3]);var s=new Uint8Array(n,24,256);window_name=t;for(var S=a(window_name),E=0;E<S.length;E++)s[E]=S[E];o[4]=S.length,o[5]=0;new Uint8Array(n,280,256);return _.data=new Uint8Array(n,0,_.data_len),void A(_)}if("ds_stop"==e)_.type=28;else{if("aud_start"==e){_.type=29,_.data_len=520;var n=new ArrayBuffer(_.data_len),l=new Uint32Array(n,0,1),C=t;l[0]=C.length;var f=new Uint32Array(n,4,1);f[0]=0;for(var c=new Uint8Array(n,8,256),O=a(C),E=0;E<O.length;E++)c[E]=O[E];new Uint8Array(n,264,256);return _.data=new Uint8Array(n,0,_.data_len),void A(_)}if("aud_stop"==e)_.type=30;else if("get_cam"==e)_.type=41;else{if("cam_start"==e){_.type=42,_.data_len=520;var n=new ArrayBuffer(_.data_len),I=new Uint32Array(n,0,1),T=t;I[0]=T.length;var f=new Uint32Array(n,4,1);f[0]=0;for(var U=new Uint8Array(n,8,256),u=a(T),E=0;E<u.length;E++)U[E]=u[E];new Uint8Array(n,264,256);return _.data=new Uint8Array(n,0,_.data_len),void A(_)}"cam_stop"==e?_.type=43:"set_videoparam"==e?(_.type=46,_.data=a(t),_.data_len=_.data.length):"get_videoparam"==e?(_.type=47,_.data=a(t),_.data_len=_.data.length):"start_record"==e?(_.type=48,_.data=a(t),_.data_len=_.data.length):"stop_record"==e?(_.type=49,_.data=a(t),_.data_len=_.data.length):"start_push"==e?(_.type=50,_.data=a(t),_.data_len=_.data.length):"stop_push"==e?(_.type=51,_.data=a(t),_.data_len=_.data.length):"get_rtmp_port"==e?_.type=52:"set_mic_vol"==e?(_.type=53,_.data=a(t),_.data_len=_.data.length):"get_mic_vol"==e&&(_.type=54)}}}A(_)}function A(e){var t=8+e.data_len,_=new ArrayBuffer(t),n=new Uint16Array(_,0,1),a=new Uint8Array(_,2,1),r=new Uint32Array(_,4,1);if(n[0]=e.type,a[0]=0,r[0]=e.data_len,e.data_len>0)for(var o=new Uint8Array(_,8,e.data_len),A=0;A<e.data_len;A++)o[A]=e.data[A];R&&R.send(_)}function i(){try{R&&(R.close(),R=R.onopen=R.onclose=R.onerror=R.onmessage=null,C.emit(C.CLOSE))}catch(e){console.log(e)}}function s(){i()}function S(){R&&i(),R=new WebSocket("ws://"+p+":"+L),g=setTimeout(function(){clearTimeout(g),i()},1500),R.timeout=1500,R.binaryType="arraybuffer",R.onopen=function(){clearTimeout(g),o("get_rtmp_port"),o("get_mic"),o("get_cam"),o("get_mic_vol"),C.emit(C.OPEN)},R.onclose=function(){i()},R.onerror=function(){i()},R.onmessage=function(e){var t=e.data;if("string"==typeof e.data)console.log("on message [string] ignore.");else{var _=new DataView(t),n=_.getUint16(0,!0);console.log("onmessage code->",n);var a=(_.getUint8(2,!0),_.getUint32(4,!0));if(n>=0&&n<f.length){f[n]}if(0==n||6==n||8==n)console.log("mov_start,mov_pause,mov_seek success");else if(10==n){if(a>36){var o=new Uint32Array(t,8,8),A="width:"+o[0]+" height:"+o[1];A="framerate:"+o[2]+" duration:"+o[3],A="playpos:"+o[4]+" filesize:"+o[5],c=A;var i=o[6],s=new Uint8Array(t,40,i),S=r(s);c.filename=S,C.emit(C.MOVIE_INFO_CHANGE,c)}}else if(11==n)console.log("ss_start success"),C.emit(C.SS_START);else if(24<=n&&26>=n){if(a>=4){var E=_.getUint32(8,!0);O=E.toString(),C.emit(C.VERSION_INFO_CHANGE,O)}}else if(55==n)console.log("ds_start success");else if(59==n)console.log("as start success");else if(83==n){if(console.log("get camera sucess"),a>4){var l=_.getUint32(8,!0),R=12;I.length=0;for(var p=0;p<l;p++){var L=_.getUint32(R,!0);R+=4;var g=new Uint8Array(t,R,L-1);R+=L;var y=r(g);I.push(y)}C.emit(C.CAMERA_INFO_CHANGE,I)}}else if(53==n){if(a>4){var v=_.getUint32(8,!0),R=12;T.length=0;for(var p=0;p<v;p++){var M=_.getUint32(R,!0);R+=4;var P=new Uint8Array(t,R,M-1);R+=M;var y=r(P);T.push(y)}C.emit(C.MIC_INFO_CHANGE,T)}}else if(85==n)console.log("cam_share success");else if(95==n){console.log("get_videoparam success");var N=new Uint8Array(t,8,t.byteLength-8-1),y=r(N);U=y,C.emit(C.VIDEO_INFO_CHANGE,U)}else if(105==n){console.log("get_rtmp_port_success");var N=new Uint8Array(t,8,t.byteLength-8-1),y=r(N);u=y,C.emit(C.RTMP_PORT_CHANGE,u)}else if(109==n){console.log("get_mic_vol success");var N=new Uint8Array(t,8,t.byteLength-8-1),y=r(N);d=y,C.emit(C.MIC_VOL_CHANGE,d)}else if(111<=n&&114>=n){var N=new Uint8Array(t,8,t.byteLength-8),V=r(N);console.log("url->",V)}else if(13==n)C.emit(C.SS_STOP);else{var N=new Uint8Array(t,8,t.byteLength-8),y=r(N);console.log("data ->",y)}}}}Object.defineProperty(t,"__esModule",{value:!0});var E=_(1),l=n(E),C=new l.default,f=["MOV_START_SUC","MOV_START_FAIL","MOV_STOP_SUC","MOV_STOP_FAIL","MOV_PAUSE_SUC","MOV_PAUSE_FAIL","MOV_RESUME_SUC","MOV_RESUME_FAIL","MOV_SEEK_SUC","MOV_SEEK_FAIL","MOV_PROPERTY","SS_START_SUC","SS_START_FAIL","SS_STOP_SUC","SS_STOP_FAIL","REC_START_SUC","REC_START_FAIL","REC_STOP_SUC","REC_STOP_FAIL","REC_PAUSE_SUC","REC_PAUSE_FAIL","REC_RESUME_SUC","REC_RESUME_FAIL","MOV_PLAY_FINISH","MOV_VERSION","SS_VERSION","REC_VERSION","MOV_SELECT_FILE_CANCEL","QAV_LOGIN_SUC","QAV_LOGIN_FAIL","QAV_LOGOUT_SUC","QAV_LOGOUT_FAIL","QAV_ENTERROOM_SUC","QAV_ENTERROOM_FAIL","QAV_LEAVEROOM_SUC","QAV_LEAVEROOM_FAIL","QAV_OPEN_MIC_SUC","QAV_OPEN_MIC_FAIL","QAV_OPEN_MIC_NODEV","QAV_CLOSE_MIC_SUC","QAV_CLOSE_MIC_FAIL","QAV_CLOSE_MIC_NODEV","QAV_OPEN_PLAYER_SUC","QAV_OPEN_PLAYER_FAIL","QAV_OPEN_PLAYER_NODEV","QAV_CLOSE_PLAYER_SUC","QAV_CLOSE_PLAYER_FAIL","QAV_CLOSE_PLAYER_NODEV","QAV_MUTE_AUDIO_SUC","QAV_MUTE_AUDIO_FAIL","QAV_UNMUTE_AUDIO_SUC","QAV_UNMUTE_AUDIO_FAIL","REC_SAVE_FILE_CANCEL","GET_MIC_SUC","GET_MIC_FAIL","DS_START_SUC","DS_START_FAIL","DS_STOP_SUC","DS_STOP_FAIL","AUD_START_SUC","AUD_START_FAIL","AUD_STOP_SUC","AUD_STOP_FAIL","AUD_DATA","SS_DATA","MOV_DATA","PEN_START_SUC","PEN_START_FAIL","PEN_STOP_SUC","PEN_STOP_FAIL","PEN_VERSION","QAV_DEVICE_SUC","QAV_DEVICE_FAIL","CBD_QUERY_SUC","CBD_QUERY_FAIL","CBD_GET_SUC","CBD_GET_FAIL","FILE_GET_SUC","FILE_GET_FAIL","FILE_SET_SUC","FILE_SET_FAIL","RESTART_SUC","RESTART_FAIL","GET_CAM_SUC","GET_CAM_FAIL","CAM_START_SUC","CAM_START_FAIL","CAM_STOP_SUC","CAM_STOP_FAIL","SWITCH_SCENE_SUC","SWITCH_SCENE_FAIL","PUSH_STREAM_FAIL","SHOW_UI_SUC","SET_VIDEO_PARAM_SUC","SET_VIDEO_PARAM_FAIL","GET_VIDEO_PARAM_SUC","GET_VIDEO_PARAM_FAIL","START_RECORD_SUC","START_RECORD_FAIL","STOP_RECORD_SUC","STOP_RECORD_FAIL","START_PUSH_SUC","START_PUSH_FAIL","STOP_PUSH_SUC","STOP_PUSH_FAIL","GET_RTMP_PORT_SUC","GET_RTMP_PORT_FAIL","SET_MIC_VOL_SUC","SET_MIC_VOL_FAIL","GET_MIC_VOL_SUC","GET_MIC_VOL_FAIL","RTMP_CONNECTING","RTMP_CONNECT_SUC","RTMP_CONNECT_FAIL","RTMP_CONNECT_CLOSED"],c=null,O="",I=[],T=[],U="",u="",d="",R=null,p="127.0.0.1",L=8090,g=0;C.infos={movieInfo:c,versionInfo:O,cameraInfo:I,micInfo:T,videoInfo:U,rtmpPort:u,micVol:d},C.MOVIE_INFO_CHANGE="MOVIE_INFO_CHANGE",C.VERSION_INFO_CHANGE="VERSION_INFO_CHANGE",C.CAMERA_INFO_CHANGE="CAMERA_INFO_CHANGE",C.MIC_INFO_CHANGE="MIC_INFO_CHANGE",C.VIDEO_INFO_CHANGE="VIDEO_INFO_CHANGE",C.RTMP_PORT_CHANGE="RTMP_PORT_CHANGE",C.MIC_VOL_CHANGE="MIC_VOL_CHANGE",C.SS_START="SS_START",C.SS_STOP="SS_STOP",C.OPEN="OPEN",C.CLOSE="CLOSE",C.ERROR="ERROR",C.getRTMPPort=function(){o("get_rtmp_port")},C.getMicInfo=function(){o("get_mic")},C.getCamInfo=function(){o("get_cam")},C.getMicVol=function(){o("get_mic_vol")},C.start=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"127.0.0.1",t=arguments[1];p=e,L=t,S()},C.stop=function(){s()},C.startShareScreen=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";o("ss_start",e)},C.stopShareScreen=function(){o("ss_stop")},t.default=C}])});
\ No newline at end of file