224 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			224 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| 
								 | 
							
								class WebRTC {
							 | 
						||
| 
								 | 
							
								  constructor(config) {
							 | 
						||
| 
								 | 
							
								    this.ChangeStatus = "";
							 | 
						||
| 
								 | 
							
								    this.options = {
							 | 
						||
| 
								 | 
							
								      mediaConstraints: { audio: true, video: false },
							 | 
						||
| 
								 | 
							
								      pcConfig: {
							 | 
						||
| 
								 | 
							
								        iceServers: [
							 | 
						||
| 
								 | 
							
								          { urls: ["stun:stun.mixcom.cn:3478"] },
							 | 
						||
| 
								 | 
							
								          {
							 | 
						||
| 
								 | 
							
								            urls: "turn:stun.mixcom.cn:3478",
							 | 
						||
| 
								 | 
							
								            username: "mixcom",
							 | 
						||
| 
								 | 
							
								            credential: "MikangyunST",
							 | 
						||
| 
								 | 
							
								          },
							 | 
						||
| 
								 | 
							
								        ],
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    this.audioConf = {
							 | 
						||
| 
								 | 
							
								      audio: "",
							 | 
						||
| 
								 | 
							
								      ringout: "",
							 | 
						||
| 
								 | 
							
								      ringin: "",
							 | 
						||
| 
								 | 
							
								      hangup: "",
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    if (config == undefined) {
							 | 
						||
| 
								 | 
							
								      console.log("[RTC] : RTC is missing configuration information");
							 | 
						||
| 
								 | 
							
								      return false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (
							 | 
						||
| 
								 | 
							
								      config.audioConfigs == undefined ||
							 | 
						||
| 
								 | 
							
								      typeof config.audioConfigs.audio != "object"
							 | 
						||
| 
								 | 
							
								    ) {
							 | 
						||
| 
								 | 
							
								      console.log("[RTC] : audio is not configured");
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      this.audioConf = { ...this.audioConf, ...config.audioConfigs };
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (config.changeStatus) {
							 | 
						||
| 
								 | 
							
								      this.ChangeStatus = config.changeStatus;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (config.options !== undefined) {
							 | 
						||
| 
								 | 
							
								      this.options = config.options;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (config.debug !== undefined && config.debug === true) {
							 | 
						||
| 
								 | 
							
								      JsSIP.debug.enable("JsSIP:*");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 初始化录音播放
							 | 
						||
| 
								 | 
							
								  audioInit() {
							 | 
						||
| 
								 | 
							
								    // 默认是循环播放
							 | 
						||
| 
								 | 
							
								    const audio = this.audioConf.audio;
							 | 
						||
| 
								 | 
							
								    audio.srcObject = null;
							 | 
						||
| 
								 | 
							
								    audio.currentTime = 0;
							 | 
						||
| 
								 | 
							
								    audio.loop = false;
							 | 
						||
| 
								 | 
							
								    audio.src = "";
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 播放录音
							 | 
						||
| 
								 | 
							
								  audioPlay(src) {
							 | 
						||
| 
								 | 
							
								    const audio = this.audioConf.audio;
							 | 
						||
| 
								 | 
							
								    this.audioInit();
							 | 
						||
| 
								 | 
							
								    if (src == "ringin" || src == "ringout") {
							 | 
						||
| 
								 | 
							
								      audio.loop = true;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    audio.src = this.audioConf[src];
							 | 
						||
| 
								 | 
							
								    audio.load();
							 | 
						||
| 
								 | 
							
								    audio.play();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 连接WebSocket
							 | 
						||
| 
								 | 
							
								  WebSocket(url) {
							 | 
						||
| 
								 | 
							
								    this.socket = new JsSIP.WebSocketInterface(url);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 注册分机
							 | 
						||
| 
								 | 
							
								  register(config) {
							 | 
						||
| 
								 | 
							
								    console.log("注册分机");
							 | 
						||
| 
								 | 
							
								    this.configuration = {
							 | 
						||
| 
								 | 
							
								      sockets: [this.socket],
							 | 
						||
| 
								 | 
							
								      uri: "sip:" + config.extension + "@" + config.sipserver,
							 | 
						||
| 
								 | 
							
								      password: config.password,
							 | 
						||
| 
								 | 
							
								      contact_uri: "sip:" + config.extension + "@" + config.sipserver,
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    this.ua = new JsSIP.UA(this.configuration);
							 | 
						||
| 
								 | 
							
								    // Websocket连接成功
							 | 
						||
| 
								 | 
							
								    this.ua.on("connected", function () {
							 | 
						||
| 
								 | 
							
								      console.log("websocket连接成功");
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Websocket连接断开
							 | 
						||
| 
								 | 
							
								    this.ua.on("disconnected", function () {
							 | 
						||
| 
								 | 
							
								      console.log("websocket连接断开");
							 | 
						||
| 
								 | 
							
								      // 重连
							 | 
						||
| 
								 | 
							
								      if (this.ua) {
							 | 
						||
| 
								 | 
							
								          this.ua.start();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var that = this;
							 | 
						||
| 
								 | 
							
								    // 呼入或者呼出时触发的事件
							 | 
						||
| 
								 | 
							
								    this.ua.on("newRTCSession", function (e) {
							 | 
						||
| 
								 | 
							
								      const { session, originator } = e;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      that.session = session;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      switch (originator) {
							 | 
						||
| 
								 | 
							
								        // out
							 | 
						||
| 
								 | 
							
								        case "local":
							 | 
						||
| 
								 | 
							
								          // 此处为呼出前的操作
							 | 
						||
| 
								 | 
							
								          that.ChangeStatus("CallOut");
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        case "remote":
							 | 
						||
| 
								 | 
							
								          that.audioPlay("ringin");
							 | 
						||
| 
								 | 
							
								          that.ChangeStatus("CallIn", session.remote_identity.display_name);
							 | 
						||
| 
								 | 
							
								          // 此处为呼入接通前的操作
							 | 
						||
| 
								 | 
							
								          break;
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // 连接中
							 | 
						||
| 
								 | 
							
								      session.on("connecting", () => {
							 | 
						||
| 
								 | 
							
								        that.ChangeStatus("Connecting");
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								      // 连接已接受
							 | 
						||
| 
								 | 
							
								      session.on("accepted", () => {
							 | 
						||
| 
								 | 
							
								        that.ChangeStatus("Connected");
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // 通话中
							 | 
						||
| 
								 | 
							
								      session.on("confirmed", () => {
							 | 
						||
| 
								 | 
							
								        that.ChangeStatus("Calling");
							 | 
						||
| 
								 | 
							
								        const stream = new MediaStream();
							 | 
						||
| 
								 | 
							
								        const receivers = session.connection.getReceivers();
							 | 
						||
| 
								 | 
							
								        if (receivers) {
							 | 
						||
| 
								 | 
							
								          receivers.forEach((receiver) => stream.addTrack(receiver.track));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        audio.srcObject = stream;
							 | 
						||
| 
								 | 
							
								        // 最后都要播放
							 | 
						||
| 
								 | 
							
								        audio.play();
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // 播放回铃音
							 | 
						||
| 
								 | 
							
								      session.on("progress", () => {
							 | 
						||
| 
								 | 
							
								        // 判断呼出 播放回铃
							 | 
						||
| 
								 | 
							
								        if (originator === "local") {
							 | 
						||
| 
								 | 
							
								          that.audioInit();
							 | 
						||
| 
								 | 
							
								          const stream = new MediaStream();
							 | 
						||
| 
								 | 
							
								          const receivers = session.connection.getReceivers();
							 | 
						||
| 
								 | 
							
								          if (receivers) {
							 | 
						||
| 
								 | 
							
								            receivers.forEach((receiver) => stream.addTrack(receiver.track));
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          audio.srcObject = stream;
							 | 
						||
| 
								 | 
							
								          audio.play();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // 结束
							 | 
						||
| 
								 | 
							
								      session.on("ended", () => {
							 | 
						||
| 
								 | 
							
								        console.log("挂断了");
							 | 
						||
| 
								 | 
							
								        that.ChangeStatus("Ended", "");
							 | 
						||
| 
								 | 
							
								        that.audioPlay("hangup");
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								      // 失败
							 | 
						||
| 
								 | 
							
								      session.on("failed", (e) => {
							 | 
						||
| 
								 | 
							
								        console.log("失败了");
							 | 
						||
| 
								 | 
							
								        that.ChangeStatus("Failed", "");
							 | 
						||
| 
								 | 
							
								        that.audioPlay("hangup");
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // ICE 交互连通建立事件 加快通讯速度
							 | 
						||
| 
								 | 
							
								      session.on('icecandidate', function (event) {
							 | 
						||
| 
								 | 
							
								        if (
							 | 
						||
| 
								 | 
							
								          event.candidate.type === 'srflx' &&
							 | 
						||
| 
								 | 
							
								          event.candidate.relatedAddress !== null &&
							 | 
						||
| 
								 | 
							
								          event.candidate.relatedPort !== null
							 | 
						||
| 
								 | 
							
								        ) {
							 | 
						||
| 
								 | 
							
								          event.ready();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.ua.on("registered", () => {
							 | 
						||
| 
								 | 
							
								      console.log("[SIP Phone] : Registered (ON LINE)");
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    this.ua.on("unregistered", () => {
							 | 
						||
| 
								 | 
							
								      console.log("[SIP Phone] : Unregistered (OFF LINE)");
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    this.ua.on("registrationFailed", (e) => {
							 | 
						||
| 
								 | 
							
								      console.log("[SIP Phone] : Registration Failed (OFF LINE)");
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    this.ua.start();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 注销
							 | 
						||
| 
								 | 
							
								  unregister() {
							 | 
						||
| 
								 | 
							
								    this.ua.unregister(this.options);
							 | 
						||
| 
								 | 
							
								    this.ua.stop();
							 | 
						||
| 
								 | 
							
								    this.ua = null;
							 | 
						||
| 
								 | 
							
								    console.log("[SIP Phone] : unregistered")
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 呼出
							 | 
						||
| 
								 | 
							
								  call(phone) {
							 | 
						||
| 
								 | 
							
								    this.ua.call(phone, this.options);
							 | 
						||
| 
								 | 
							
								    this.audioPlay("ringout");
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 挂断
							 | 
						||
| 
								 | 
							
								  hangup() {
							 | 
						||
| 
								 | 
							
								    this.ua.terminateSessions();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 接通
							 | 
						||
| 
								 | 
							
								  answer() {
							 | 
						||
| 
								 | 
							
								    console.log(this.session)
							 | 
						||
| 
								 | 
							
								    this.session.answer(this.options);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // 拒接
							 | 
						||
| 
								 | 
							
								  reject() {
							 | 
						||
| 
								 | 
							
								    this.ua.terminateSessions();
							 | 
						||
| 
								 | 
							
								    // this.seesion.terminate(this.options);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 |