var outgoingSession = null, incomingSession = null, currentSession = null, nativeStream = null, callVideoState = null, callVideoFail = null, inComing = true, sip_uri_, sip_password_, ws_uri_, localStream = null, userAgent = null, currentVideoIndex = 0, timeOut = null; var getWidthScale = document.documentElement.clientWidth; //监测浏览器的宽度 var myVideoView = document.getElementById('myVideo'); //我的本地视频 var videoView_1 = document.getElementById('videoView'); //对方的视频信息 $(function() { $(".videoList").css({ "height": getWidthScale * 0.9 / 1.6 + "px", }) $(".videoMy").css({ "height": getWidthScale * 0.9 / 1.6 + "px", }) }) function switchScreen() { console.log("switchScreen") $(".titText").hide(); $(".callVideo").hide(); $(".videoMy").hide() $(".videoList").css({ "height": document.documentElement.clientWidth * 0.9 / 1.6 + "px", // "width":"100%", // "margin-left": "0%" }) } function resScreen() { console.log("resScreen") $(".titText").show(); $(".callVideo").show(); $(".videoList").css({ "height": document.documentElement.clientWidth * 0.9 / 1.6 + "px", // "width":"80%", // "margin-left": "10%" }) } //开启本地摄像头 function captureLocalMediaVideo() { // navigator.mediaDevices.getUserMedia({ // video: true, // audio: false // }, function(stream) { // nativeStream = stream; // myVideoView.srcObject = stream; // }, function(e) { // if(e.name != "NotReadableError") { // alert('getUserMedia() error: ' + e.name); // } // // }); navigator.mediaDevices.getUserMedia({ video: true, audio: false }).then((stream) => { nativeStream = stream; myVideoView.srcObject = nativeStream; myVideoView.onloadedmetadata = function() { if(nativeStream.active) { //在这里需要做判断 myVideoView.play(); } } }).catch((res) => { alert('getUserMedia() error2: ' + res.name); }) } //获取本地媒体流 function localMediaStream() { // navigator.getUserMedia({ // video: true, // audio: true // }, function(stream) { // localStream = stream; // if(callVideoState) { // sipCallVideo(); // } // }, function(e) { // if(e.name != "NotReadableError") { // alert('getUserMedia() error: ' + e.name); // } // }); navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then((stream) => { localStream = stream; if(callVideoState) { sipCallVideo(); } }).catch((res) => { alert('getUserMedia() error2: ' + res.name); }) } // 关闭摄像头 function closeMediaVideo() { //if(nativeStream){ // nativeStream.getTracks().forEach(function(track) { // track.stop(); // }); //} if(localStream) { localStream.getTracks().forEach(function(track) { track.stop(); }); } } // 监听挂断事件 function monitorDropcall(data){ timeOut = setInterval(function() { console.log("isEnded"+data.isEnded()) if(data.isEnded()) { console.log("isEnded"+data.isEnded()) dropCall() clearTimeout(timeOut) } }, 2000) } function testStart() { sip_uri_ = "sip:" + selectExten + "@"+huayi.config.sip_ip; // 12345sp.zwfw.anyang.gov.cn sip_password_ = huayi.config.sip_password_; //zhumadian12345800100 ws_uri_ = huayi.config.ws_uri_ console.info("get input info: sip_uri = ", sip_uri_, " sip_password = ", sip_password_, " ws_uri = ", ws_uri_); var socket = new JsSIP.WebSocketInterface(ws_uri_); var configuration = { sockets: [socket], outbound_proxy_set: ws_uri_, uri: sip_uri_, //与用户代理关联的SIP URI(字符串)。这是您的提供商提供给您的SIP地址 password: sip_password_, //SIP身份验证密码 contact_uri: 'sip:' + selectExten + huayi.config.contact_uri, register: true, //指示启动时JsSIP用户代理是否应自动注册 session_timers: false, //启用会话计时器(根据RFC 4028) }; userAgent = new JsSIP.UA(configuration); // JsSIP.debug.enable('JsSIP:*'); JsSIP.debug.disable('JsSIP:*'); //成功注册成功,data:Response JsSIP.IncomingResponse收到的SIP 2XX响应的实例 userAgent.on('registered', function(data) { console.info("registered: ", data.response.status_code, ",", data.response.reason_phrase); $(".titText").show(); $(".titText").html(selectExten + "注册成功"); captureLocalMediaVideo() }); //由于注册失败而被解雇,data:Response JsSIP.IncomingResponse接收到的SIP否定响应的实例,如果失败是由这样的响应的接收产生的,否则为空 userAgent.on('registrationFailed', function(data) { console.log("registrationFailed, ", data); //console.warn("registrationFailed, ", data.response.status_code, ",", data.response.reason_phrase, " cause - ", data.cause); }); //1.在注册到期之前发射几秒钟。如果应用程序没有为这个事件设置任何监听器,JsSIP将像往常一样重新注册。 userAgent.on('registrationExpiring', function() { //==console.warn("registrationExpiring"); }); //为传入或传出会话/呼叫激发。data: userAgent.on('newRTCSession', function(data) { //console.info('onNewRTCSession: ', data); console.info('onNewRTCSession: ', data); var originator = data.originator; var session = data.session; var request = data.request; if(data.session._direction == "outgoing") { sipCallRTCSession(data, 1) outgoingSession = data.session; outgoingSession.on('connecting', function(data) { currentSession = outgoingSession; outgoingSession = null; }); } if(data.originator == "remote") { incomingSession = data.session sipCallRTCSession(data, 2) console.info("incomingSession, answer the call"); incomingSession = data.session; $(".videoBtn").show(); $(".videoCall").show(); $(".vidDrop").hide(); $(".videoList").hide(); $(".videoMy").hide(); $('.maxOpen').trigger("click"); if(!nativeStream) { captureLocalMediaVideo() } localMediaStream() // sipIncomingRTCSession(incomingSession) confirmed } //接受呼叫时激发 data.session.on('accepted', function(data) { console.info("3"); if(data.originator == 'remote' && currentSession == null) { currentSession = incomingSession; incomingSession = null; } }); //确认呼叫后激发 data.session.on('confirmed', function(data) { console.info("4"); $(".callStyle").text("连接中"); if(data.originator == 'remote' && currentSession == null) { currentSession = incomingSession; incomingSession = null; } }); //在将远程SDP传递到RTC引擎之前以及在发送本地SDP之前激发。此事件提供了修改传入和传出SDP的机制。 data.session.on('sdp', function(data) { console.info("5"); }); //接收或生成对邀请请求的1XX SIP类响应(>100)时激发。该事件在SDP处理之前触发(如果存在),以便在需要时对其进行微调,甚至通过删除数据对象中响应参数的主体来删除它 data.session.on('progress', function(data) { console.info("6"); if(data.originator == 'remote') {} }); }); //为传入或传出消息请求激发。data: userAgent.on('newMessage', function(data) { console.info("8"); if(data.originator == 'local') {} else {} }); //连接到信令服务器,并恢复以前的状态,如果以前停止。重新开始时,如果UA配置中的参数设置为register:true,则向SIP域注册。 userAgent.start(); setInterval(function() { userAgent.register(); }, 30 * 1000) } var eventHandlers = { 'progress': function(e) { console.log('call is in progress'); }, 'failed': function(e) { console.log('call failed: ', e); if(callVideoFail) { setTimeout(function() { videoCall() }, 2000) } }, 'ended': function(e) { console.log('call ended : ', e); dropCall(); }, 'confirmed': function(e) { console.log('call confirmed'); } }; // 打电话 function sipCallRTCSession(e, state) { console.log(e.session) console.log(state) // 1是呼出,2是呼入 monitorDropcall(e.session) e.session.on("confirmed", function(data) { console.log("confirmed") console.log(data) callVideoFail = false; if(e.session.connection.getReceivers) { console.log(e.session.connection.getReceivers()) remoteStream = new MediaStream(); e.session.connection.getReceivers().forEach(element => { // track可能一个音轨或者视频轨迹 remoteStream.addTrack(element.track) }) console.log(remoteStream) if(inComing) { inComing = false; videoView_1.srcObject = remoteStream videoView_1.onloadedmetadata = function() { videoView_1.play(); videoView_1.muted = false; state === 1 ? console.log("呼叫成功") : console.log("接听成功") $(".callStyle").text("通话中"); $(".videoCall").show(); $(".videoMy").show(); $(".videoBtn").hide(); $(".videoList").show(); $(".vidDrop").show(); } } } }) } //视频呼叫 function audioCall(callPhone) { if($("#numberCall").val() < 1005 || $("#numberCall").val() > 2080) { alert("账号不正确,请重新输入") } else { inComing = true callVideoState = true; localMediaStream(); if(!nativeStream) { captureLocalMediaVideo() } // $(".videoCall").show(); $(".callStyle").text("连接中"); } } function sipCallVideo() { callVideoFail = true; if(localStream) { var sip_phone_number_ = $("#numberCall").val().toString(); var options = { 'eventHandlers': eventHandlers, 'mediaConstraints': { 'audio': true, 'video': true }, 'mediaStream': localStream }; callVideoState = false; outgoingSession = userAgent.call(sip_phone_number_, options); } } //接听 function answerCall() { $(".callStyle").text("连接中") $(".videoCall").hide(); inComing = true; if(incomingSession) { incomingSession.answer({ 'mediaConstraints': { 'audio': true, 'video': true }, 'mediaStream': localStream }); incomingSession = null; } } //注销 function unReg() { console.log('注销----------->'); userAgent.unregister(true); } //挂断 function dropCall() { userAgent.terminateSessions(); clearTimeout(timeOut) $(".callStyle").text("") resScreen() closeMediaVideo(); $(".videoCall").hide(); }