From 897f32a99a5e8259755cee342efd08a4310bf233 Mon Sep 17 00:00:00 2001
From: liyong <liyong@3mang.com>
Date: Mon, 27 Nov 2017 19:11:50 +0800
Subject: [PATCH] 1.人员信息中增加摄像头和麦克风是否被禁用的字段;2.修改用户名长度;3.增加禁用摄像头和麦克风的按钮功能

---
 src/EngineEntrance.js       |  26 ++++++++++++++++++++++----
 src/GlobalConfig.js         |   4 ++++
 src/apes/ConferApe.js       |  34 +++++++++++++++++++++++++++++++---
 src/apes/WebRtcApe.js       | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------
 src/assets/css/mcuStyle.css |  45 ++++++++++++++++++++++++++++++++++++---------
 src/pdus/pro.js             |   2 ++
 6 files changed, 312 insertions(+), 68 deletions(-)

diff --git a/src/EngineEntrance.js b/src/EngineEntrance.js
index 1c814cb..1e0253c 100644
--- a/src/EngineEntrance.js
+++ b/src/EngineEntrance.js
@@ -63,7 +63,7 @@ export default class MessageEntrance extends Emiter {
     super();
     this.lastClassActiveTime=0;//最后一次课堂激活的时间戳
     //sdk 信息
-    GlobalConfig.sdkVersion = "v2.33.6.20171123";
+    GlobalConfig.sdkVersion = "v2.34.5.20171127";
     loger.warn("sdkVersion:" + GlobalConfig.sdkVersion);
     console.log("sdkVersion:" + GlobalConfig.sdkVersion);
     //设置
@@ -102,7 +102,8 @@ export default class MessageEntrance extends Emiter {
     _webRtc.on(MessageTypes.USER_DEVICE_STATUS_CHAANGE, this.userDeviecStatusChange.bind(this)); //监听摄像头和麦克风的开启状态
     _webRtc.on(MessageTypes.MEDIA_PUBLISH_STATUS_CHANGE, this.mediaPublishStatusChange.bind(this)); //webRtc推流状态发生改变
     _webRtc.on(WebRtcApe.RE_JOIN_CHANNEL, this._webRtcRejoinChannel.bind(this)); //重先加入音视频频道
-    _webRtc.on(MessageTypes.MEDIA_ENABLED_CHANGE, this._mediaEnabledChange.bind(this)); //音视频禁用状态改变
+    _webRtc.on(MessageTypes.MEDIA_ENABLED_CHANGE, this._mediaEnabledChange.bind(this)); //音视频禁用状态改变  广播消息
+    _webRtc.on(MessageTypes.UPDATE_USER_MEDIA_MUTED_STATUS, this._updateUserMediaMutedStatus.bind(this)); //音视频禁用状态改变(自己),同步更新
 
     // Sass平台层
     _sass = Sass;
@@ -647,20 +648,26 @@ export default class MessageEntrance extends Emiter {
 
     //如果没有名字的时候需要随机生成
     let randUserId =parseInt(Math.random()*1000)+"_"+parseInt(Math.random()*1000)+"_"+parseInt(Math.random()*1000);
+    let randUserName=EngineUtils.creatRandomNum(2,".");
     if (GlobalConfig.userRole == ApeConsts.host) {
       randUserId = "T" + randUserId;
+      randUserName= "T" + randUserName;
     } else if (GlobalConfig.userRole == ApeConsts.assistant) {
       randUserId = "A" + randUserId;
+      randUserName= "A" + randUserName;
     } else if (GlobalConfig.userRole == ApeConsts.presenter) {
       randUserId = "P" + randUserId;
+      randUserName= "O" + randUserName;
     } else  if (GlobalConfig.userRole == ApeConsts.invisible) {
       randUserId = "I" + randUserId;
+      randUserName= "I" + randUserName;
     } else {
       randUserId = "S" + randUserId;
+      randUserName= "S" + randUserName;
     }
 
     //如果没有名字,随机起一个名字
-    GlobalConfig.userName = _param.userName || randUserId;
+    GlobalConfig.userName = _param.userName || randUserName;
     //如果没有userId或者为"0",随机生成
     if (!GlobalConfig.userId || GlobalConfig.userId == "0") {
       GlobalConfig.userId = randUserId;
@@ -1417,7 +1424,7 @@ export default class MessageEntrance extends Emiter {
       return;
     }
     if(_webRtc){
-      _webRtc.webRtcMeiaEnabledChange(_data);
+      _webRtc.receiveWebRtcMeiaEnabledChange(_data);
     }
   }
   //手动切换MS -> {ip;"xxx.xx.xx","port":"xxxx"}
@@ -2179,6 +2186,17 @@ export default class MessageEntrance extends Emiter {
       _confer_ape.sendMediaEnabledChange(_data);
     }
   }
+  /*
+   * 同步媒体的禁用状态
+   * */
+  _updateUserMediaMutedStatus(_data){
+    if (!_mcu.connected||GlobalConfig.isRecordPlayBack) {
+      return;
+    }
+    if(_confer_ape){
+      _confer_ape.sendUpdateUserMediaMutedStatus(_data);
+    }
+  }
 
   //监听摄像头麦克风状态
   userDeviecStatusChange(_data) {
diff --git a/src/GlobalConfig.js b/src/GlobalConfig.js
index e72b29c..83a3435 100644
--- a/src/GlobalConfig.js
+++ b/src/GlobalConfig.js
@@ -557,6 +557,10 @@ GlobalConfig.handUpTime = 0;
 GlobalConfig.level = 0;
 GlobalConfig.openCamera = 0;
 GlobalConfig.openMicrophones = 0;
+//音视频是否被禁用
+GlobalConfig.videoEnabled =true;
+GlobalConfig.audioEnabled=true;
+
 GlobalConfig.selfDisEnableDrawTime = 1;//记录是否禁用画笔,0为启用画笔,大于0时被禁用的时间戳
 
 //视频质量相关设置
diff --git a/src/apes/ConferApe.js b/src/apes/ConferApe.js
index 8bd0277..97fd555 100644
--- a/src/apes/ConferApe.js
+++ b/src/apes/ConferApe.js
@@ -121,6 +121,9 @@ class ConferApe extends Ape {
     nodeInfoRecordPdu.videoQuality = GlobalConfig.videoQuality;
     nodeInfoRecordPdu.userIp = GlobalConfig.userIp;
 
+    nodeInfoRecordPdu.videoEnabled = GlobalConfig.videoEnabled;
+    nodeInfoRecordPdu.audioEnabled =GlobalConfig.audioEnabled;
+
     nodeInfoRecordPdu.curVideoQuality = GlobalConfig.curVideoQuality;
     nodeInfoRecordPdu.micGain = GlobalConfig.micGain;
     nodeInfoRecordPdu.micNoise = GlobalConfig.micNoise;
@@ -1056,6 +1059,14 @@ class ConferApe extends Ape {
       if(!GlobalConfig.isH5){
         this._emit(MessageTypes.CLASS_INSERT_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
         this.emitRosterChange();
+
+        //更新webRtc模块的音视频禁用状态
+        //{nodeId: uid, video: true, audio: false}
+        //消息自己的不处理
+        if(nodeId!=GlobalConfig.nodeId&&(newNodeData.openCamera>0||newNodeData.openMicrophones>0)){
+          this.receiveChangeUserMediaEnabledStatus({nodeId:nodeId,video:newNodeData.videoEnabled,audio:newNodeData.audioEnabled});
+        }
+
       }
     } else {
       //loger.log("更新人员列表数据,rosterExists已经存在",rosterExists);
@@ -1069,8 +1080,14 @@ class ConferApe extends Ape {
       }
       if(!GlobalConfig.isH5){
         this._emit(MessageTypes.CLASS_UPDATE_ROSTER, {"nodeId": nodeId, "nodeData": newNodeData});
-      }
 
+        //更新webRtc模块的音视频禁用状态
+        //{nodeId: uid, video: true, audio: false}
+        //消息自己的不处理
+        if(nodeId!=GlobalConfig.nodeId){
+          this.receiveChangeUserMediaEnabledStatus({nodeId:nodeId,video:newNodeData.videoEnabled,audio:newNodeData.audioEnabled});
+        }
+      }
     }
   }
 
@@ -1128,11 +1145,22 @@ class ConferApe extends Ape {
     }catch (err){
       loger.warn("发送->媒体开启或禁用->失败",_data,err.message);
     }
-
   }
 
   /*
-   * 收到媒体开启或禁用控制
+   * 同步用户的媒体禁用状态
+   * */
+  sendUpdateUserMediaMutedStatus(_data){
+    if(!_data){
+      return;
+    }
+    loger.log('发送同步用户的媒体禁用状态->', _data);
+    GlobalConfig.videoEnabled =Boolean(_data.video);
+    GlobalConfig.audioEnabled =Boolean(_data.audio);
+    this.updateUserInfo();
+  }
+  /*
+   * 收到媒体开启或禁用控制消息或同步消息
    * */
   receiveChangeUserMediaEnabledStatus(_data){
     this._emit(MessageTypes.RECEIVE_MEDIA_ENABLED_CHANGE,_data);
diff --git a/src/apes/WebRtcApe.js b/src/apes/WebRtcApe.js
index 31f822d..8fe00b3 100644
--- a/src/apes/WebRtcApe.js
+++ b/src/apes/WebRtcApe.js
@@ -36,6 +36,7 @@ class WebRtcApe extends Emiter {
     this.channelId = "";
     this.uid = 0;
     this.info = ""
+    this.videAndAudioMutedStatusData={};//记录当前自己的摄像头和麦克风禁用状态
 
     this.reAddRemoteStreamDelay = 0;//重连远程视频的计时器
     this.rePublishDelay = 0;//重新推流的间隔
@@ -88,6 +89,14 @@ class WebRtcApe extends Emiter {
     this.invisibleVideoHeight = SIZE_360;
     this.xdyRemote = "xdy_remote";
 
+    this.audioMutedIdName = "audioMutedIdName_";
+    this.videoMutedIdName = "videoMutedIdName_";
+
+    this.closeCameraTitle="close Camera";
+    this.openCameraTitle="open Camera";
+    this.closeMicrophoneTitle="close Microphone";
+    this.openMicrophoneTitle="open Microphone";
+
     this.localWebRtcVideoClass = 'localWebRtcVideoClass';//本地视图统一的class名称
     this.invisibleWebRtcVideoClass = 'invisibleWebRtcVideoClass';
     this.normalWebRtcVideoClass = 'normalWebRtcVideoClass';
@@ -217,31 +226,47 @@ class WebRtcApe extends Emiter {
         $("#" + this.xdyRemote + uid).remove();
       }
       let audioMutedDiv = "";
+      let videoMutedDiv="";
+      let videoAndAudioBox=""
       if (GlobalConfig.isTeachOrAssistant || GlobalConfig.isInvisible) {
-        audioMutedDiv = `<div class="audioMuted audioOpen" id=${"audioMuted_"+uid}></div>`;
+        if(user&&user.videoEnabled==true){
+          videoMutedDiv = `<div class="audioAndVideMuted cameraOn" id=${this.videoMutedIdName + uid} title="${this.closeCameraTitle}"></div>`
+        }else{
+          videoMutedDiv = `<div class="audioAndVideMuted cameraOff" id=${this.videoMutedIdName + uid} title="${this.closeCameraTitle}"></div>`
+        }
+        if(user&&user.audioEnabled==true){
+          audioMutedDiv = `<div class="audioAndVideMuted microphoneOn " id=${this.audioMutedIdName + uid} title="${this.closeMicrophoneTitle}"></div>`;
+        }else{
+          audioMutedDiv = `<div class="audioAndVideMuted microphoneff " id=${this.audioMutedIdName + uid} title="${this.closeMicrophoneTitle}"></div>`;
+        }
+        videoAndAudioBox=`<div class="audioAndVideBox unOpenVideo">${videoMutedDiv+audioMutedDiv}</div>`;
       }
 
       if (userRole == ApeConsts.invisible) {
-        let nameDiv = `<div style=${this.invisibleVideoWidth}px;height:22px; position: absolute;bottom: 2px; z-index: 1;overflow:hidden;font-size: 14px;text-align: right; vertical-align: middle;background-color: #2926251a;color: #e7e7e7display:${this.nameDisplay}">${userName + audioMutedDiv}</div>`;
+        let nameDiv = `<div style=${this.invisibleVideoWidth}px;height:22px; position: absolute;bottom: 2px; right:4px; z-index: 1;overflow:hidden;font-size: 14px;text-align: right; vertical-align: middle;background-color: #2926251a;color: #e7e7e7display:${this.nameDisplay}">${userName}</div>`;
         //把远程视频添加到监课列表
         loger.log("获取远程视频流成功->监课:" + userName + "->" + uid, new Date().getTime());
-        let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.invisibleWebRtcVideoClass}" style="width:${this.invisibleVideoWidth * this.videoScale}px;height:${this.invisibleVideoHeight * this.videoScale}px;float: left;margin-right: 1px;">${nameDiv}</div>`;
+        let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.invisibleWebRtcVideoClass}" style="width:${this.invisibleVideoWidth * this.videoScale}px;height:${this.invisibleVideoHeight * this.videoScale}px;float: left;margin-right: 1px;">${nameDiv + videoAndAudioBox}</div>`;
         $(this.invisibleViewId).append(viewDiv);
       } else if (userRole == ApeConsts.host || userRole == ApeConsts.assistant || userRole == ApeConsts.presenter) {
-        let nameDiv = `<div style="width:${this.hostRemoteVideoWidth}px;height:22px; position: absolute;bottom: 2px; z-index: 1;overflow:hidden;font-size: 14px;text-align: right;vertical-align: middle; background-color: #2926251a;color: #e7e7e7;display:${this.nameDisplay}">${userName + audioMutedDiv}</div>`;
+        let nameDiv = `<div style="width:${this.hostRemoteVideoWidth}px;height:22px; position: absolute;bottom: 2px;right:4px z-index: 1;overflow:hidden;font-size: 14px;text-align: right;vertical-align: middle; background-color: #2926251a;color: #e7e7e7;display:${this.nameDisplay}">${userName }</div>`;
         //把远程视图添加到老师列表
         loger.log("获取远程视频流成功->userRole:" + userRole + ":" + userName + "->" + uid, new Date().getTime());
-        let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.hostWebRtcVideoClass}" style="width:${this.hostRemoteVideoWidth * this.videoScale}px;height:${this.hostRemoteVideoHeight * this.videoScale}px;float: left;margin-right: 1px;">${nameDiv}</div>`;
+        let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.hostWebRtcVideoClass}" style="width:${this.hostRemoteVideoWidth * this.videoScale}px;height:${this.hostRemoteVideoHeight * this.videoScale}px;float: left;margin-right: 1px;">${nameDiv + videoAndAudioBox}</div>`;
         $(this.hostRemoteViewId).prepend(viewDiv);
       } else {
-        let nameDiv = `<div style="width:${this.normalRemoteVideoWidth}px;height:22px; position: absolute;bottom: 2px; z-index: 1;overflow:hidden;font-size: 14px;text-align: right;vertical-align: middle;background-color: #2926251a;color: #e7e7e7;display:${this.nameDisplay}">${userName + audioMutedDiv}</div>`;
+        let nameDiv = `<div style="width:${this.normalRemoteVideoWidth}px;height:22px; position: absolute;bottom: 2px;right:4px z-index: 1;overflow:hidden;font-size: 14px;text-align: right;vertical-align: middle;background-color: #2926251a;color: #e7e7e7;display:${this.nameDisplay}">${userName}</div>`;
         //把视图添加到学生列表
         loger.log("获取远程视频流成功->学生:" + userName + "->" + uid, new Date().getTime());
-        let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.normalWebRtcVideoClass}" style="width:${this.normalRemoteVideoWidth * this.videoScale}px;height:${this.normalRemoteVideoHeight * this.videoScale}px;float: left;margin-right: 1px;">${nameDiv}</div>`;
+        let viewDiv = `<div id="${this.xdyRemote + uid}" class="${this.normalWebRtcVideoClass}" style="width:${this.normalRemoteVideoWidth * this.videoScale}px;height:${this.normalRemoteVideoHeight * this.videoScale}px;float: left;margin-right: 1px;">${nameDiv + videoAndAudioBox}</div>`;
         $(this.normalRemoteViewId).append(viewDiv);
       }
-      $("#audioMuted_" + uid).off("click", this._clickAudioMuted.bind(this));
-      $("#audioMuted_" + uid).on("click", this._clickAudioMuted.bind(this));
+      $("#" + this.videoMutedIdName + uid).off("click", this._clickVideoMuted.bind(this));
+      $("#" + this.audioMutedIdName + uid).off("click", this._clickAudioMuted.bind(this));
+
+      $("#" + this.videoMutedIdName + uid).on("click", this._clickVideoMuted.bind(this));
+      $("#" + this.audioMutedIdName + uid).on("click", this._clickAudioMuted.bind(this));
+
       //播放视频,隐藏控制条
       try {
         $("#bar_" + stream.getId()).hide();
@@ -554,14 +579,28 @@ class WebRtcApe extends Emiter {
       if (user) {
         userName = user.name || "";
       }
+   /*   let audioMutedDiv = "";
+      if (GlobalConfig.isTeachOrAssistant) {
+        audioMutedDiv = `<div class="audioAndVideMuted microphoneOn openVideo" id=${this.audioMutedIdName + this.uid}></div>`;
+      }
+*/
       let audioMutedDiv = "";
+      let videoMutedDiv="";
+      let videoAndAudioBox=""
       if (GlobalConfig.isTeachOrAssistant) {
-        audioMutedDiv = `<div class="audioMuted audioOpen" id=${"audioMuted_"+this.uid}></div>`;
+        videoMutedDiv =`<div class="audioAndVideMuted cameraOn " id=${this.videoMutedIdName + this.uid} title="${this.closeCameraTitle}"></div>`;
+        audioMutedDiv =`<div class="audioAndVideMuted microphoneOn " id=${this.audioMutedIdName + this.uid} title="${this.closeMicrophoneTitle}"></div>`;
+        videoAndAudioBox=`<div class="audioAndVideBox openVideo">${videoMutedDiv+audioMutedDiv}</div>`;
       }
-      let nameDiv = `<div id="${"videoOwnerName_" + this.uid}"  class="localVideoOwnerName" style="width:${this.localVideoWidth}px;height:22px; position: absolute;bottom: 2px; z-index: 1;overflow:hidden;font-size: 14px;text-align: right; vertical-align: middle;background-color: #2926251a;color: #e7e7e7;display:${this.nameDisplay}">${userName + audioMutedDiv}</div>`;
+
+      let nameDiv = `<div id="${"videoOwnerName_" + this.uid}"  class="localVideoOwnerName" style="width:${this.localVideoWidth}px;height:26px; position: absolute;bottom: 2px;right:4px; z-index: 1;overflow:hidden;font-size: 14px;text-align: right; vertical-align:bottom;color: #e7e7e7;display:${this.nameDisplay}">${videoAndAudioBox+userName}</div>`;
       $(this.localViewId).prepend(nameDiv);
-      $(".audioMuted").off("click", this._clickAudioMuted.bind(this));
-      $(".audioMuted").on("click", this._clickAudioMuted.bind(this));
+
+      $("#" + this.videoMutedIdName + this.uid).off("click", this._clickVideoMuted.bind(this));
+      $("#" + this.audioMutedIdName + this.uid).off("click", this._clickAudioMuted.bind(this));
+
+      $("#" + this.videoMutedIdName + this.uid).on("click", this._clickVideoMuted.bind(this));
+      $("#" + this.audioMutedIdName + this.uid).on("click", this._clickAudioMuted.bind(this));
 
       loger.log("webRtc->推流->", viewName, new Date().getTime());
       this.localStream.play(viewName);
@@ -819,35 +858,67 @@ class WebRtcApe extends Emiter {
       this._emit(MessageTypes.GET_DEVICES_SUCCESS, _deviceData);
     });
   }
-
+  /*
+  *
+  * 点击禁用和开启视频
+  * */
+  _clickVideoMuted(evt) {
+    let className = evt.currentTarget.className;
+    loger.log("点击禁用和开启视频", evt.currentTarget.id);
+    let idArr = (evt.currentTarget.id).split("_");
+    let uid = 10000000;//默认设置一个不存在的uid
+    if (idArr && idArr.length > 1) {
+      uid = parseInt(idArr[1]);
+    }
+    if (className.indexOf("cameraOn") > 0) {
+      loger.log("点击禁用视频->" + uid);
+      this.sendChangeUserMediaEnabled({nodeId: uid, video: false, audio: true});
+      /*if (uid != GlobalConfig.nodeId) {
+        this.sendChangeUserMediaEnabled({nodeId: uid, video: false, audio: true});
+        this.setUidVideoEnabledStatus(uid,false);
+      } else {
+        this.disableVideo(uid);
+      }*/
+    } else {
+      loger.log("点击开启视频");
+      this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: true});
+     /* if (uid != GlobalConfig.nodeId) {
+        this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: true});
+        this.setUidVideoEnabledStatus(uid,true);
+      } else {
+        this.enableVideo(uid);
+      }*/
+    }
+  }
+  /*
+  * 点击禁音和开启按钮切换
+  * */
   _clickAudioMuted(evt) {
     let className = evt.currentTarget.className;
-    console.log("点击禁音",evt.currentTarget.id);
+    loger.log("点击禁音和开启按钮切换", evt.currentTarget.id);
     let idArr = (evt.currentTarget.id).split("_");
     let uid = 10000000;//默认设置一个不存在的uid
     if (idArr && idArr.length > 1) {
       uid = parseInt(idArr[1]);
     }
-    if (className.indexOf("audioOpen") > 0) {
-      loger.log("点击禁音->"+uid);
-      // evt.currentTarget.className="audioMuted audioClose";
-      if (uid != GlobalConfig.nodeId) {
+    if (className.indexOf("microphoneOn") > 0) {
+      loger.log("点击禁音->" + uid);
+      this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: false});
+      /*if (uid != GlobalConfig.nodeId) {
         this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: false});
-        $("#audioMuted_" + uid).removeClass();
-        $("#audioMuted_" + uid).addClass("audioMuted audioClose");
+        this.setUidAudioEnabledStatus(uid,false);
       } else {
         this.disableAudio(uid);
-      }
+      }*/
     } else {
       loger.log("点击开启声音");
-      //evt.currentTarget.className="audioMuted audioOpen";
-      if (uid != GlobalConfig.nodeId) {
+      this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: true});
+      /*if (uid != GlobalConfig.nodeId) {
         this.sendChangeUserMediaEnabled({nodeId: uid, video: true, audio: true});
-        $("#audioMuted_" + uid).removeClass();
-        $("#audioMuted_" + uid).addClass("audioMuted audioOpen");
+        this.setUidAudioEnabledStatus(uid,true);
       } else {
         this.enableAudio(uid);
-      }
+      }*/
     }
   }
 
@@ -861,29 +932,53 @@ class WebRtcApe extends Emiter {
   /*
    * 收到控制音视频禁用消息
    * */
-  webRtcMeiaEnabledChange(_data) {
-    loger.log("收到控制音视频禁用消息",_data);
-   // {nodeId: uid, video: true, audio: false}
-    if(!_data){
+  receiveWebRtcMeiaEnabledChange(_data) {
+    loger.log("收到控制音视频禁用消息", _data);
+    // {nodeId: uid, video: true, audio: false}
+    if (!_data) {
       return;
     }
-    if(_data.nodeId!=GlobalConfig.nodeId){
-      if(_data.audio==false){
-        $("#audioMuted_" + _data.nodeId).removeClass();
-        $("#audioMuted_" + _data.nodeId).addClass("audioMuted audioClose");
-      }else {
-        $("#audioMuted_" + _data.nodeId).removeClass();
-        $("#audioMuted_" + _data.nodeId).addClass("audioMuted audioOpen");
+    this.videAndAudioMutedStatusData=_data;
+    if (_data.nodeId != GlobalConfig.nodeId) {
+      //不是自己的只设置状态显示即可
+      //音频
+      if (_data.audio == false) {
+        //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOn");
+        //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOff");
+        this.setUidAudioEnabledStatus(_data.nodeId,false);
+      } else {
+        //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOff");
+        //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOn");
+        this.setUidAudioEnabledStatus(_data.nodeId,true);
       }
-
-    }else{
-      if(_data.audio==false){
+      //视频
+      if (_data.video == false) {
+        //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOn");
+        //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOff");
+        this.setUidVideoEnabledStatus(_data.nodeId,false);
+      } else {
+        //$("#" + this.audioMutedIdName + _data.nodeId).removeClass("microphoneOff");
+        //$("#" + this.audioMutedIdName + _data.nodeId).addClass("audioAndVideMuted microphoneOn");
+        this.setUidVideoEnabledStatus(_data.nodeId,true);
+      }
+    } else {
+      //控制自己的音频
+      if (_data.audio == false) {
         this.disableAudio(_data.nodeId);
-      }else {
+      } else {
         this.enableAudio(_data.nodeId);
       }
+      //控制自己的视频
+      if (_data.video == false) {
+        this.disableVideo(_data.nodeId);
+      } else {
+        this.enableVideo(_data.nodeId);
+      }
+      //更新同步用户的媒体禁用状态
+     if(this.videAndAudioMutedStatusData){
+         this._emit(WebRtcApe.UPDATE_USER_MEDIA_MUTED_STATUS,this.videAndAudioMutedStatusData);
+     }
     }
-
   }
 
   /*
@@ -893,8 +988,9 @@ class WebRtcApe extends Emiter {
     loger.log("开启禁音:" + uid);
     if (parseInt(uid) == GlobalConfig.nodeId) {
       if (this.localStream) {
-        $("#audioMuted_" + uid).removeClass();
-        $("#audioMuted_" + uid).addClass("audioMuted audioClose");
+        //$("#" + this.audioMutedIdName + uid).removeClass("microphoneOn");
+        //$("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOff");
+        this.setUidAudioEnabledStatus(uid,false);
         this.localStream.disableAudio();
       }
     }
@@ -903,22 +999,91 @@ class WebRtcApe extends Emiter {
   /*
    * 开启音频
    * */
-  enableAudio(_uid) {
-    loger.log("开启音频:" + _uid);
-    if (parseInt(_uid) == GlobalConfig.nodeId) {
+  enableAudio(uid) {
+    loger.log("开启音频:" + uid);
+    if (parseInt(uid) == GlobalConfig.nodeId) {
       if (this.localStream) {
         this.localStream.enableAudio();
-        $("#audioMuted_" + _uid).removeClass();
-        $("#audioMuted_" + _uid).addClass("audioMuted audioOpen");
+        //$("#" + this.audioMutedIdName + _uid).removeClass("microphoneOff");
+        //$("#" + this.audioMutedIdName + _uid).addClass("audioAndVideMuted microphoneOn");
+        this.setUidAudioEnabledStatus(uid,true);
+      }
+    }
+  }
+
+  /*
+   * 设置音频禁用按钮的状态
+   * uid  nodeId
+   * isEnable   true开启   false 禁用
+   *
+   * */
+  setUidAudioEnabledStatus(uid, isEnable){
+    loger.log("设置音频禁用按钮的状态",uid,isEnable);
+    if(isEnable==true){
+      $("#" + this.audioMutedIdName + uid).removeClass("microphoneOff");
+      $("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOn");
+      $("#" + this.audioMutedIdName + uid).attr("title",this.closeMicrophoneTitle);
+    }else{
+      $("#" + this.audioMutedIdName + uid).removeClass("microphoneOn");
+      $("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOff");
+      $("#" + this.audioMutedIdName + uid).attr("title",this.openMicrophoneTitle);
+    }
+  }
+
+  /*
+   * 禁用摄像头
+   * */
+  disableVideo(uid) {
+    loger.log("禁用摄像头:" + uid);
+    if (parseInt(uid) == GlobalConfig.nodeId) {
+      if (this.localStream) {
+        //$("#" + this.audioMutedIdName + uid).removeClass("microphoneOn");
+        //$("#" + this.audioMutedIdName + uid).addClass("audioAndVideMuted microphoneOff");
+        this.setUidVideoEnabledStatus(uid,false);
+        this.localStream.disableVideo();
       }
     }
   }
 
+  /*
+   * 开启摄像头
+   * */
+  enableVideo(uid) {
+    loger.log("开启摄像头:" + uid);
+    if (parseInt(uid) == GlobalConfig.nodeId) {
+      if (this.localStream) {
+        this.localStream.enableVideo();
+        //$("#" + this.audioMutedIdName + _uid).removeClass("microphoneOff");
+        //$("#" + this.audioMutedIdName + _uid).addClass("audioAndVideMuted microphoneOn");
+        this.setUidVideoEnabledStatus(uid,true);
+      }
+    }
+  }
+  /*
+  * 设置视频禁用按钮的状态
+   * uid  nodeId
+   * isEnable   true开启   false 禁用
+   *
+  * */
+  setUidVideoEnabledStatus(uid, isEnable){
+    loger.log("设置视频禁用按钮的状态",uid,isEnable);
+    if(isEnable==true){
+      //开启
+      $("#" + this.videoMutedIdName + uid).removeClass("cameraOff");
+      $("#" + this.videoMutedIdName + uid).addClass("audioAndVideMuted cameraOn");
+      $("#" + this.videoMutedIdName + uid).attr("title",this.closeCameraTitle);
+    }else{
+      //禁用
+      $("#" + this.videoMutedIdName + uid).removeClass("cameraOn");
+      $("#" + this.videoMutedIdName + uid).addClass("audioAndVideMuted cameraOff");
+      $("#" + this.videoMutedIdName + uid).attr("title",this.openCameraTitle);
+    }
+  }
+
   //组织数据,发送给服务器,控制录制和开启录制-推流和停止推流  status:0 停止推流  1:开始推流(同时开启录制),2:停止录制(同时停止推流)
   packMediaInfoData(_status) {
     let curTimestamp = new Date().getTime();
     let data = `appId=${GlobalConfig.appId}&channel=${GlobalConfig.channelId}&channelKey=${GlobalConfig.appCertificate}&uid=${GlobalConfig.userUid}&status=${_status}&userId=${GlobalConfig.userId}&userName=${GlobalConfig.userName}&userRole=${GlobalConfig.userRole}&timestamp=${curTimestamp}&recordTimestamp=${GlobalConfig.recordTimestamp}`;
-
     //markettest_623790840_T9540_1508207080
     let streamId = GlobalConfig.siteId + "_" + GlobalConfig.classId + "_" + GlobalConfig.userId + "_" + curTimestamp;
     //mcu记录一份数据
@@ -1024,7 +1189,7 @@ WebRtcApe.prototype.RECORD_STATUS_0 = WebRtcApe.RECORD_STATUS_0 = 0; //停止推
 WebRtcApe.prototype.RECORD_STATUS_1 = WebRtcApe.RECORD_STATUS_1 = 1; //开始推流
 WebRtcApe.prototype.RECORD_STATUS_2 = WebRtcApe.RECORD_STATUS_2 = 2; //停止录制
 WebRtcApe.prototype.RE_JOIN_CHANNEL = WebRtcApe.RE_JOIN_CHANNEL = "reJoninChanel";//重加入频道
-
+WebRtcApe.prototype.UPDATE_USER_MEDIA_MUTED_STATUS = WebRtcApe.UPDATE_USER_MEDIA_MUTED_STATUS = "updateUserMediaMutedStatus";
 export default new WebRtcApe;
 
 
diff --git a/src/assets/css/mcuStyle.css b/src/assets/css/mcuStyle.css
index f150bdc..e46a00a 100644
--- a/src/assets/css/mcuStyle.css
+++ b/src/assets/css/mcuStyle.css
@@ -1,18 +1,45 @@
 @charset "utf-8";
 
-/*禁音按钮*/
-.audioMuted{
-    margin-left: 6px;
-    float: right;
+.audioAndVideBox{
+    position: absolute;
+    left: 2px;
+    bottom: 2px;
+    z-index: 2;
+}
+/*已经推流时按钮图标的左边距离*/
+.openVideo{
+    left: 36px;
+}
+/*没有推流时按钮图标的左边距离*/
+.unOpenVideo{
+    left: 2px;
+}
+
+/*音视频开启禁用和开启的按钮图标属性*/
+.audioAndVideMuted{
+    /*position: absolute;*/
+    /*bottom: 2px;*/
+    /*z-index: 2;*/
+    float: left;
+    margin: 2px;
     width: 20px;
     height: 20px;
     cursor: pointer;
-    background-size: auto;
+    background-size: 100%;
     background-repeat: no-repeat;
 }
-.audioClose {
-    background-image: url(../../assets/img/audioClose.png);
+/*禁音频按钮*/
+.microphoneOff {
+    background-image: url(../../assets/img/microphoneOff_22.png);
+}
+.microphoneOn {
+    background-image: url(../../assets/img/microphoneOn_22.png);
+}
+
+/*禁视频按钮*/
+.cameraOff {
+    background-image: url(../../assets/img/cameraOff_22.png);
 }
-.audioOpen {
-    background-image: url(../../assets/img/audioOpen.png);
+.cameraOn {
+    background-image: url(../../assets/img/cameraOn_22.png);
 }
\ No newline at end of file
diff --git a/src/pdus/pro.js b/src/pdus/pro.js
index f0cae72..705793e 100644
--- a/src/pdus/pro.js
+++ b/src/pdus/pro.js
@@ -936,6 +936,8 @@ message RCNodeInfoRecordPdu {
     optional uint32 micNoise=37;
     optional bool autoGain=38;
     optional uint32 selfDisEnableDrawTime = 39;
+    optional bool videoEnabled=40;
+    optional bool audioEnabled=41;
 }
 
 message RCVotingPollSettingsPdu {
--
libgit2 0.24.0