diff --git a/src/EngineEntrance.js b/src/EngineEntrance.js
index e0d3e18..5759b59 100644
--- a/src/EngineEntrance.js
+++ b/src/EngineEntrance.js
@@ -35,6 +35,7 @@ import QuestionApe from 'apes/QuestionApe';
 import UTF8 from 'utf-8';
 import LogManager from 'LogManager';
 import  WebRtcApe from 'apes/WebRtcApe';
+import  Base64Module from 'Base64Module';
 
 let loger = Loger.getLoger('McuClient');
 
@@ -54,12 +55,14 @@ let _mediaShareApe;
 let _musicShareApe;
 let _questionApe;
 let _webRtc;
+let _base64;
+
 //MCUClient 外部实例化主类
 export default class MessageEntrance extends Emiter {
   constructor() {
     super();
     //sdk 信息
-    GlobalConfig.sdkVersion = "v2.2.7.20170904";
+    GlobalConfig.sdkVersion = "v2.2.16.20170905";
     loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
 
     //设置
@@ -112,6 +115,7 @@ export default class MessageEntrance extends Emiter {
 
     //选点模块
     _ipManager = new IpManager();
+    _base64=new Base64Module();
 
     // 底层MCU消息层
     _mcu = Mcu;
@@ -138,7 +142,7 @@ export default class MessageEntrance extends Emiter {
     _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_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)); //课堂状态发生改变,需要停止当前的所有推流
@@ -283,6 +287,9 @@ export default class MessageEntrance extends Emiter {
     this.setLocalMediaView=this._setLocalMediaView.bind(this);
     this.setRemoteMediaView=this._setRemoteMediaView.bind(this);
     this.setInvisibleMediaView=this._setInvisibleMediaView.bind(this);
+    this.setAppConfig=this._setAppConfig.bind(this);
+    this.recordControl=this._recordControl.bind(this);
+
 
     this.setDeviceInfo = this._setDeviceInfo.bind(this); //设置设备信息(麦克风,摄像头等等.....)
     this.setMessageDelay = this._setMessageDelay.bind(this); //设置是否延迟消息
@@ -722,6 +729,7 @@ export default class MessageEntrance extends Emiter {
     //加入课堂之前开始第一次选点
     let _this = this;
     loger.warn('=====================STEP7=======================');
+    loger.log("加入课堂之前开始第一次选点");
     //推流地址测速
     this._getFastestIpFromServer(GlobalConfig.msListFinal,
       function (_data) {
@@ -861,6 +869,16 @@ export default class MessageEntrance extends Emiter {
     loger.warn(" RTMP-List", GlobalConfig.rtmpPullListFinal);
     loger.warn(" HLS-List", GlobalConfig.hlsPullListFinal);
     loger.warn(" RS-List", GlobalConfig.rsPullListFinal);
+
+    //使用webRtc不需要再使用MS列表中的数据---------
+    GlobalConfig.msListFinal=[];//清空数据
+    GlobalConfig.rtmpPullListFinal=[];
+    //不是录制回放的时候hls的也清空
+    if(!GlobalConfig.isRecordPlayBack){
+      GlobalConfig.hlsPullListFinal=[];
+      GlobalConfig.rsPullListFinal=[]
+    }
+    //-------------------------------------------
   }
 
   //从Sass中选择的mcu、ms列表
@@ -925,6 +943,17 @@ export default class MessageEntrance extends Emiter {
     loger.warn(" HLS-List", GlobalConfig.hlsPullListFinal);
     loger.warn(" RS-List", GlobalConfig.rsPullListFinal);
 
+
+    //使用webRtc不需要再使用MS列表中的数据---------
+    GlobalConfig.msListFinal=[];//清空数据
+    GlobalConfig.rtmpPullListFinal=[];
+    //不是录制回放的时候hls的也清空
+    if(!GlobalConfig.isRecordPlayBack){
+      GlobalConfig.hlsPullListFinal=[];
+      GlobalConfig.rsPullListFinal=[]
+    }
+    //-------------------------------------------
+
   }
 
 
@@ -1651,10 +1680,17 @@ export default class MessageEntrance extends Emiter {
       GlobalConfig.setVideoCDNAddr(_data.videoCDNAddr); //cdn加速的拉流地址,直播的时候才使用
       GlobalConfig.setMediaShareList(_data.sharedMediaList); //提前上传的媒体共享文件列表
 
+      let appConfigStr=_data.appConfig;
+      appConfigStr=_base64.decode(appConfigStr);
+      let appConfig={};
+      try{
+        appConfig=JSON.parse(appConfigStr);
+        //储存app相关信息
+        this._setAppConfig(appConfig);
+      }catch (err){
+        loger.warn("appConfig->解析失败",appConfigStr);
+      }
 
-      GlobalConfig.appId = 'eb253cc7b40c4a8b82f0a5b6f93c2ce0';
-      GlobalConfig.appCertificate = "";
-      GlobalConfig.appRecordingKey = "";
 
       //文档服务器地址
       if (GlobalConfig.docList && GlobalConfig.docList.length > 0) {
@@ -1731,7 +1767,9 @@ export default class MessageEntrance extends Emiter {
     } else {
 
       //初始化音视频通话sdk
-      this._initWebRtcSdk(null,()=>{
+      this._initWebRtcSdk({
+        appId:GlobalConfig.appId
+      },()=>{
         //音视频通话SDK初始化完成之后,根据用户的userIp获取信息,获取服务列表选点,选点测速完成后才加入MCU
         this.loadServerJsonAndgetUserIpInfo();
       });
@@ -1808,7 +1846,6 @@ export default class MessageEntrance extends Emiter {
     }
 
     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);
@@ -2674,11 +2711,13 @@ export default class MessageEntrance extends Emiter {
         openCamera: GlobalConfig.openCamera,
         openMicrophones: GlobalConfig.openMicrophones
       });
+      this._recordControl({"recordStatus":true});
       return ;
     }
 
    if(_webRtc){
       _webRtc.publish(_params);
+     this._recordControl({"recordStatus":true});
     }
   }
   /*
@@ -2751,6 +2790,30 @@ export default class MessageEntrance extends Emiter {
       _webRtc.setInvisibleMediaView(_params);
     }
   }
+  //设置app相关数据
+  _setAppConfig(_params){
+    if(!_params){
+      return;
+    }
+    loger.log("设置appConfig",_params);
+    GlobalConfig.appId=_params.appId||"eb253cc7b40c4a8b82f0a5b6f93c2ce0";
+    GlobalConfig.appCertificate=_params.appCertificate||"";
+    GlobalConfig.appRecordingKey=_params.appRecordingKey||"";
+    GlobalConfig.recordInterfaces=_params.recordInterfaces||"";
+    GlobalConfig.getChannelToken=_params.getChannelToken||"";
+  }
+  //录制控制
+  _recordControl(_params){
+    if(!GlobalConfig.recordInterfaces){
+      loger.log("录制控制->失败->接口地址无效",_params);
+      return ;
+    }
+    if(_params&&_params.recordStatus==true){
+      if(_sass){
+        _sass.startServerRecord();
+      }
+    }
+  }
   //webRtc-----------------end --------------------------------
 }
 
diff --git a/src/GlobalConfig.js b/src/GlobalConfig.js
index 7de3d7d..0f84d31 100644
--- a/src/GlobalConfig.js
+++ b/src/GlobalConfig.js
@@ -563,6 +563,7 @@ GlobalConfig.appRecordingKey = "";
 GlobalConfig.channelId = "";
 GlobalConfig.channelKey = null;
 GlobalConfig.userUid = 0;
-
+GlobalConfig.recordInterfaces="";//控制开启录制的接口
+GlobalConfig.getChannelToken="";//获取token的地址
 export default GlobalConfig;
 
diff --git a/src/Sass.js b/src/Sass.js
index 380d915..08c072d 100644
--- a/src/Sass.js
+++ b/src/Sass.js
@@ -243,8 +243,8 @@ class Sass extends Emiter {
      siteId String  站点号
      meetingNumber  String  课堂号 对应的是classId
      */
-    var timestamp = new Date().getTime();
-    var authId = MD5(GlobalConfig.classId + "" + timestamp); //课堂号+时间戳 的字符串,转成MD5
+    let timestamp = new Date().getTime();
+    let authId = MD5(GlobalConfig.classId + "" + timestamp); //课堂号+时间戳 的字符串,转成MD5
     //let url = `http://${GlobalConfig.portal}/3m/api/meeting/detail.do?meetingNumber=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
     let url = `${GlobalConfig.locationProtocol+GlobalConfig.portal}/3m/api/meeting/detail.do?meetingNumber=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
 
@@ -296,8 +296,8 @@ class Sass extends Emiter {
       loger.log('录制回放中,能删除文档');
       return;
     }
-    var timestamp = new Date().getTime();
-    var authId = MD5(_param.docId + "" + _param.classId + "" + timestamp); // docId+classId+timestamp的字符串,转成MD5
+    let timestamp = new Date().getTime();
+    let authId = MD5(_param.docId + "" + _param.classId + "" + timestamp); // docId+classId+timestamp的字符串,转成MD5
     //let url = `http://${GlobalConfig.portal}/3m/api/document/deleteRelation.do?docId=${_param.docId}&classId=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
     let url = `${GlobalConfig.locationProtocol+GlobalConfig.portal}/3m/api/document/deleteRelation.do?docId=${_param.docId}&classId=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
 
@@ -338,8 +338,8 @@ class Sass extends Emiter {
       return;
     }
     console.warn('删除Music共享实现...');
-    var timestamp = new Date().getTime();
-    var authId = MD5(_param.fileId + "" + _param.classId + "" + timestamp); // docId+classId+timestamp的字符串,转成MD5
+    let timestamp = new Date().getTime();
+    let authId = MD5(_param.fileId + "" + _param.classId + "" + timestamp); // docId+classId+timestamp的字符串,转成MD5
     //let url = `http://${GlobalConfig.portal}/3m/api/media/deleteRelation.do?mediaId=${_param.fileId}&classId=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
     let url = `${GlobalConfig.locationProtocol+GlobalConfig.portal}/3m/api/media/deleteRelation.do?mediaId=${_param.fileId}&classId=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
 
@@ -380,8 +380,8 @@ class Sass extends Emiter {
       loger.log('录制回放中,能删除文件');
       return;
     }
-    var timestamp = new Date().getTime();
-    var authId = MD5(_param.fileId + "" + _param.classId + "" + timestamp); // docId+classId+timestamp的字符串,转成MD5
+    let timestamp = new Date().getTime();
+    let authId = MD5(_param.fileId + "" + _param.classId + "" + timestamp); // docId+classId+timestamp的字符串,转成MD5
     //let url = `http://${GlobalConfig.portal}/3m/api/sharedMedia/deleteRelation.do?fileId=${_param.fileId}&classId=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
     let url = `${GlobalConfig.locationProtocol+GlobalConfig.portal}/3m/api/sharedMedia/deleteRelation.do?fileId=${_param.fileId}&classId=${GlobalConfig.classId}&timestamp=${timestamp}&authId=${authId}`;
 
@@ -434,8 +434,8 @@ class Sass extends Emiter {
       return;
     }
     //{"classStatusInfo":classStatusInfo}
-    var timestamp = new Date().getTime();
-    var authId = MD5(GlobalConfig.classId + "" + timestamp); // (classId+timestamp)的字符串,转成MD5
+    let timestamp = new Date().getTime();
+    let authId = MD5(GlobalConfig.classId + "" + timestamp); // (classId+timestamp)的字符串,转成MD5
     let classStatusInfo = JSON.stringify(_param.classStatusInfo);
     //let url = `http://${GlobalConfig.portal}/3m/api/meeting/saveInfo.do`;
     let url = `${GlobalConfig.locationProtocol+GlobalConfig.portal}/3m/api/meeting/saveInfo.do`;
@@ -537,6 +537,63 @@ class Sass extends Emiter {
         loger.error(`保存开始录制信息异常.状态码:${err}`);
       });
   }
+  //调用服务器端开启录制
+  startServerRecord(){
+    if(!GlobalConfig.recordInterfaces){
+      loger.log("调用服务器端开启录制->失败->接口地址无效")
+    }
+    fetch(encodeURI(GlobalConfig.recordInterfaces), {
+      method: 'POST',
+      headers: {
+        "Content-Type": "application/x-www-form-urlencoded"
+      },
+      body: `appID=${GlobalConfig.appId}&channel=${GlobalConfig.channelId}&channelKey=${GlobalConfig.channelKey}&uid=${GlobalConfig.userUid}`,
+      timeout: 4000
+    })
+      .then(ret => {
+        if (ret.ok) {
+          return ret.json();
+        } else {
+          loger.error(`调用服务器端开启录制-网络异常.状态码:${ret.status}`);
+          throw '';
+        }
+      })
+      .then(ret => {
+        if (ret.errorCode === 0) {
+          loger.log('调用服务器端开启录制 完成');
+          this._emit(Sass.CLASS_SAVE_RECORD_INFO_SUCCESS, _param);
+        } else {
+          loger.warn('调用服务器端开启录制 失败.', ret);
+        }
+      })
+      .catch(err => {
+        loger.error(`调用服务器端开启录制.状态码:${err}`);
+      });
+
+    /*let userIpInfo={
+      "appID":GlobalConfig.appId,
+      "channel":GlobalConfig.channelId,
+      "channelKey": GlobalConfig.channelKey,
+      "uid": GlobalConfig.userUid
+    }
+    let location=GlobalConfig.recordInterfaces;//'http://123.56.73.119:3000/users/Recording';
+    loger.log("调用服务器端开启录制->",location,userIpInfo);
+    $.ajax(
+      {
+        type:'post',
+        url : location,
+        dataType : 'json',
+        data: userIpInfo,
+        success  : function(data) {
+          loger.log("调用服务器端开启录制->success",data);
+        },
+        error : function(data) {
+          //alert(data.code);
+          loger.log("调用服务器端开启录制->error",data);
+        }
+      }
+    );*/
+  }
 
   //答题卡-------------------------------------------------------
   //创建答题数据
@@ -559,7 +616,7 @@ class Sass extends Emiter {
         return;
       }
       let classId = GlobalConfig.classId; //课堂号
-      var timestamp = new Date().getTime();
+      let timestamp = new Date().getTime();
       let authId = MD5(classId + "" + timestamp);
 
       let type = parseInt(_param.type); //1单选,2多选,3判断,4点名
@@ -635,7 +692,7 @@ class Sass extends Emiter {
       userName  String 用户名字*/
 
       let classId = GlobalConfig.classId; //课堂号
-      var timestamp = new Date().getTime();
+      let timestamp = new Date().getTime();
       let authId = MD5(classId + "" + timestamp);
 
       let type = parseInt(_param.type); //1单选,2多选,3判断,4点名
diff --git a/src/apes/ConferApe.js b/src/apes/ConferApe.js
index 90a6d19..ff2849d 100644
--- a/src/apes/ConferApe.js
+++ b/src/apes/ConferApe.js
@@ -129,7 +129,7 @@ class ConferApe extends Ape {
     nodeInfoRecordPdu.city = GlobalConfig.city; //城市
     nodeInfoRecordPdu.province = GlobalConfig.province; //服务商
     nodeInfoRecordPdu.isp = GlobalConfig.isp; //服务商
-
+    nodeInfoRecordPdu.msList=[];
     //用户的MS列表
     let msListAll = GlobalConfig.msListFinal;
     for (let k = 0; k < msListAll.length; k++) {
diff --git a/src/apes/WebRtcApe.js b/src/apes/WebRtcApe.js
index 3f4cfba..bfbc262 100644
--- a/src/apes/WebRtcApe.js
+++ b/src/apes/WebRtcApe.js
@@ -36,6 +36,12 @@ class WebRtcApe extends Emiter {
 
     this.isPublish=false;//当前是否正在推流
 
+    this.localVideoWidth=320;
+    this.localVideoHeight=240;
+
+    this.remoteVideoWidth=320;
+    this.remoteVideoHeight=240;
+
     this.localViewId = "";
     this.localStyle = "";
 
@@ -113,7 +119,7 @@ class WebRtcApe extends Emiter {
       let stream = evt.stream;
       if(stream){
         loger.log("获取远程视频流成功: " + stream.getId());
-        let viewDiv=`<div id="${this.xdyRemote + stream.getId()}" style="width:320px;height:240px;"></div>`;
+        let viewDiv=`<div id="${this.xdyRemote + stream.getId()}" style="width:${this.remoteVideoWidth}px;height:${this.remoteVideoHeight}px;"></div>`;
         if(GlobalConfig.getUserRoleFromeNodeId(stream.getId())==ApeConsts.invisible){
           //显示隐藏用户
           $(this.invisibleViewId).append(viewDiv);
@@ -286,8 +292,10 @@ class WebRtcApe extends Emiter {
    * */
   setLoaclView(_params) {
     loger.log("设置本地回显视图");
-    this.localViewId = _params.divId||"";;
-    this.localStyle = _params.styleStr||"";;
+    this.localViewId = _params.divId||"";
+    this.localStyle = _params.styleStr||"";
+    this.localVideoWidth=parseInt(_params.width)||320;
+    this.localVideoHeight=parseInt(_params.height)||240;
   }
 
   /*
@@ -297,6 +305,8 @@ class WebRtcApe extends Emiter {
     loger.log("设置其他人的video视图容器");
     this.remoteViewId = _params.divId||"";
     this.remoteStyle = _params.styleStr||"";
+    this.remoteVideoWidth=parseInt(_params.width)||320;
+    this.remoteVideoHeight=parseInt(_params.height)||240;
   }
 
   /*
@@ -367,9 +377,15 @@ class WebRtcApe extends Emiter {
         let device = devices[i];
         //{"deviceId":"default","kind":"audiooutput","label":"默认","groupId":"cf49a03ca26700235629fc13d3e6630bd34407c66438d157056a34dd3ae03ef5"}
         if (device.kind == 'audioinput') {
+          if(!device.label){
+            device.label="麦克风_"+i;
+          }
           this.microphones.push(device);
           GlobalConfig.microphones.push(device.label);
         } else if (device.kind == 'videoinput') {
+          if(!device.label){
+            device.label="摄像头_"+i;
+          }
           this.cameras.push(device);
           GlobalConfig.cameras.push(device.label);
         } else {