WebRtcApe.js 10.9 KB
//*
// WebRtc
// */
import Emiter from 'Emiter';
import Loger from "Loger";
import $ from "jquery";
import GlobalConfig from 'GlobalConfig';
import ApeConsts from './ApeConsts';
import EngineUtils from 'EngineUtils';
import MessageTypes from 'MessageTypes';
var AgoraRTC = require('../AgoraRTCSDK-1.12.0');
let loger = Loger.getLoger('WebRtcApe');

class WebRtcApe extends Emiter {
  constructor() {
    super();
    this.appId = 'eb253cc7b40c4a8b82f0a5b6f93c2ce0';
    this.appCertificate = "";
    this.appRecordingKey = "";

    this.channelKey=null;
    this.channelId = "";
    this.uid = 0;
    this.info = ""

    this.mode = "interop";
    this.client = null;
    this.localStream = null;
    this.cameras = [];
    this.microphones = [];
    this.curCameraId = "";
    this.curMicrophoneId = "";

    this.videoResolution = "240P";
    this.isOpenVideo = true;

    this.isPublish=false;//当前是否正在推流

    this.localViewId = "";
    this.localStyle = "";

    this.remoteViewId = "";
    this.remoteStyle = "";

    this.invisibleViewId ="";
    this.invisibleStyle ="";

    this.xdyRemote = "xdy_remote";
    //webRtc sdk
    this.client = AgoraRTC.createClient({mode: this.mode});

    this.getDevices(null,(devices)=>{
      if (this.cameras && this.cameras.length > 0) {
        this.curCameraId = this.cameras[0].deviceId || "";
        GlobalConfig.curCamera =this.cameras[0].label || "";
      }
      if (this.microphones && this.microphones.length > 0) {
        this.curMicrophoneId = this.microphones[0].deviceId || "";
        GlobalConfig.curMicrophone = this.microphones[0].label || "";
      }
    });
  }

  initApp(_params,_callback) {
    loger.log("初始化WebRtc");
    if (_params) {
      this.appId = _params.appId;
    }
    if (this.client) {
      this.client.init(this.appId, () => {
        loger.log("初始化WebRtc->成功");
        if(_callback){
          _callback({isSuccess:true});
        }
      }, (err)=> {
        loger.error("初始化WebRtc->失败", err);
        if(_callback){
          _callback({isSuccess:false,error:err});
        }
      });
      this.addEvent();
    }
  }

  addEvent() {
    loger.log("监听webRtc消息");
    if (!this.client) {
      loger.log("addEvent error:client is null");
      return;
    }
    this.channelKey = "";
    this.client.on('error', (err) => {
      loger.log("WebRtc异常:", err.reason);
      if (err.reason === 'DYNAMIC_KEY_TIMEOUT') {
        this.client.renewChannelKey(this.channelKey, ()=> {
          loger.log("Renew channel key successfully");
        }, (err)=> {
          loger.log("Renew channel key failed: ", err);
        });
      }
    });

    this.client.on('stream-added', (evt)=> {
      let stream = evt.stream;
      loger.log("New stream added: " + stream.getId());
      loger.log("Subscribe ", stream);
      this.client.subscribe(stream, (err)=> {
        loger.log("Subscribe stream failed", err);
      });
    });

    this.client.on('stream-subscribed', (evt)=> {
      let stream = evt.stream;
      if(stream){
        loger.log("获取远程视频流成功: " + stream.getId());
        let viewDiv=`<div id="${this.xdyRemote + stream.getId()}" style="width:320px;height:240px;"></div>`;
        if(GlobalConfig.getUserRoleFromeNodeId(stream.getId())==ApeConsts.invisible){
          //显示隐藏用户
          $(this.invisibleViewId).append(viewDiv);
        }else {
          $(this.remoteViewId).append(viewDiv);
        }
        stream.play(this.xdyRemote + stream.getId());
      }

    });

    this.client.on('stream-removed', (evt)=> {
      let stream = evt.stream;
      stream.stop();
      $('#' + this.xdyRemote + stream.getId()).remove();
      loger.log("Remote stream is removed " + stream.getId());
    });

    this.client.on('peer-leave', (evt)=> {
      let stream = evt.stream;
      if (stream) {
        stream.stop();
        $('#' + this.xdyRemote + stream.getId()).remove();
        loger.log(evt.uid + " ->离开视频通话频道");
      }
    });
    this.client.on("active-speaker", (evt)=> {
      let uid = evt.uid;
      loger.log("当前正在讲话的uid:" + uid);
    });
  }

  joinChannel(_params) {
    this.channelId = _params.channelId||"";
    this.uid = parseInt(_params.uid)||0;
    this.info =_params.info || "";
    this.channelKey  = _params.channelKey||null;

    loger.log("加入视频通话频道->channelId:"+this.channelId,"uid:"+this.uid);
    this.client.join(this.channelKey , ""+this.channelId, this.uid, (uid)=> {
      this.uid = uid;
      loger.log("加入视频通话频道->成功->channelId:"+this.channelId,"uid:"+this.uid);
      this._emit(MessageTypes.WEB_RTC_JOIN_SUCCESS);
      this.openLoaclStream();
    }, (err)=> {
      loger.error("加入视频通话频道->失败->", err);
      this._emit(MessageTypes.WEB_RTC_JOIN_FAILED);
    });
  }
  //重新获取摄像头和麦克风并重新推流
  reGetLoaclStream(){
    if(this.isPublish){
      loger.log("重新获取摄像头和麦克风并重新推流");
      this.unpublish();
      this.openLoaclStream();
      //切换设备后自动重推流
      this.rePublishDelay=setTimeout(()=>{
        this.publish();
      },1200);
      this.publish();
    }else {
      this.openLoaclStream();
    }
  }

  openLoaclStream() {
   /* if(this.localStream){
      this.localStream.close();
      this.localStream=null;
    }*/
    this.localStream = AgoraRTC.createStream({
      streamID: this.uid,
      audio: true,
      microphoneId: this.curMicrophoneId,
      cameraId: this.curCameraId,
      video: this.isOpenVideo,
      screen: false
    });

    if (this.isOpenVideo) {
      //设置分辨率
      this.localStream.setVideoProfile(this.videoResolution);
    }
  }

  leaveChannel() {
    loger.log("离开视频通话频道");
    if (!this.client) {
      return;
    }
    this.client.leave(() => {
      loger.log("离开视频通话频道->成功");
    }, (err)=> {
      loger.log("离开视频通话频道->失败");
    });
  }

  closeRemoteVideoView(_data){
    if(!_data){
      return;
    }
    //根据nodeId查找视频
    try{
      loger.log("立即删除停止推流人员的视图");
      $('#' + this.xdyRemote + _data.nodeId).remove();
    }catch (err){

    }

  }
  publish(_params) {
    if (!this.client||!this.localStream) {
      return;
    }
    this.localStream.init(()=> {
      let viewName = this.localViewId.replace("#", "");
      loger.log("webRtc->推流->",viewName);
      this.localStream.play(viewName);
      this.client.publish(this.localStream, (err)=> {
        loger.log("webRtc->推流失败: " + err);
        GlobalConfig.openCamera =0;
        GlobalConfig.openMicrophones =0;
        this.isPublish=false;
      });
      this.isPublish=true;
      GlobalConfig.openCamera = EngineUtils.creatTimestamp();
      GlobalConfig.openMicrophones = GlobalConfig.openCamera;

      this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {
        nodeId: GlobalConfig.nodeId,
        userRole: GlobalConfig.userRole,
        userName: GlobalConfig.userName,
        userId: GlobalConfig.userId,
        openCamera: GlobalConfig.openCamera,
        openMicrophones: GlobalConfig.openMicrophones
      });

    }, (err)=> {
      loger.error("webRtc->推流->本地流开启失败", err);
      this._emit(MessageTypes.WEB_RTC_PUBLISH_FAILED,err);
    });
  }

  unpublish() {
    clearTimeout(this.rePublishDelay);
    loger.log("webRtc->停止推流 ");
    if (!this.client||!this.localStream) {
      return;
    }
    this.client.unpublish(this.localStream, (err)=> {
      loger.log("webRtc->停止推流->失败" + err);
    });
    this.localStream.close();
    $(this.localViewId).html("");
    this.isPublish=false;
    GlobalConfig.openCamera =0;
    GlobalConfig.openMicrophones =0;
    this._emit(MessageTypes.USER_DEVICE_STATUS_CHAANGE, {
      nodeId: GlobalConfig.nodeId,
      userRole: GlobalConfig.userRole,
      userName: GlobalConfig.userName,
      userId: GlobalConfig.userId,
      openCamera: GlobalConfig.openCamera,
      openMicrophones: GlobalConfig.openMicrophones
    });
  }

  /*
   * 设置本地回显视图
   * */
  setLoaclView(_params) {
    loger.log("设置本地回显视图");
    this.localViewId = _params.divId||"";;
    this.localStyle = _params.styleStr||"";;
  }

  /*
   * 设置其他人的video视图容器
   * */
  setRemoteView(_params) {
    loger.log("设置其他人的video视图容器");
    this.remoteViewId = _params.divId||"";
    this.remoteStyle = _params.styleStr||"";
  }

  /*
   * 设置隐藏用户的video视图容器
   * */
  setInvisibleMediaView(_params) {
    loger.log("设置隐藏用户的video视图容器");
    this.invisibleViewId = _params.divId||"";
    this.invisibleStyle = _params.styleStr||"";
  }
  /*
  * 切换当前使用的设备
  * */
  changeDevices(_params){
    loger.log("切换设备->",_params);
    if(!_params){
      return;
    }
    //设置摄像头
    if(_params.curCamera){
      for(let k in this.cameras){
        let item=this.cameras[k];
        if(item&&item.label==_params.curCamera){
          this.curCameraId=item.deviceId;
          GlobalConfig.curCamera=_params.curCamera;
          break;
        }
      }
    }
    //设置麦克风
    if(_params.curMicrophone){
      for(let k in this.microphones){
        let item=this.microphones[k];
        if(item&&item.label==_params.curMicrophone){
          this.curMicrophoneId=item.deviceId;
          GlobalConfig.curMicrophone=_params.curMicrophone;
          break;
        }
      }
    }
    //分辨率
    if(_params.videoResolution){
      this.videoResolution=_params.videoResolution||"240P";//默认是240P 	20	320x240	15	200
    }

    clearTimeout(this.changeDevicesDelay);
    this.changeDevicesDelay=setTimeout(()=>{
      //重新获取本地视图流
      this.reGetLoaclStream();
    },1400);
  }

  /*
  * 获取设备信息
  * */
  getDevices(_params,_callback) {
    AgoraRTC.getDevices((devices)=> {
      //下面的数组存的是对象
      this.microphones=[];
      this.cameras=[];

      //选的数组存的是设备名称
      GlobalConfig.cameras=[];
      GlobalConfig.microphones=[];

      loger.log("devices", devices)
      for (let i = 0; i < devices.length; i++) {
        let device = devices[i];
        //{"deviceId":"default","kind":"audiooutput","label":"默认","groupId":"cf49a03ca26700235629fc13d3e6630bd34407c66438d157056a34dd3ae03ef5"}
        if (device.kind == 'audioinput') {
          this.microphones.push(device);
          GlobalConfig.microphones.push(device.label);
        } else if (device.kind == 'videoinput') {
          this.cameras.push(device);
          GlobalConfig.cameras.push(device.label);
        } else {
          loger.warn('其他设备: ', device);
        }
      }
      let _deviceData={cameras:GlobalConfig.cameras,microphones:GlobalConfig.microphones};
      if(_callback){
        _callback(_deviceData);
      }
      this._emit(MessageTypes.GET_DEVICES_SUCCESS,_deviceData);
    });
  }
}
export default new WebRtcApe;