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);
 | ||
|  |   } | ||
|  | } |