var outgoingSession = null, timeInterval = null, incomingSession = null, currentSession = null, calState, nativeStream = null, callVideoState = null, callVideoFail = null, dbCallVideoState = null; var bigVideoStyle = { "background-color": "#000000", "width": "100%", "height": "100%", "top": "0", "right": "0", "z-index": "1" } var smallVideoStyle = { "background-color": "#EEEEEE", "width": "20%", "height": "20%", "top": "10px", "right": "10px", "z-index": "2" } var localStream = null, userAgent = null, superviseMan = null, videoInputDevices = [], currentVideoIndex = 0, timer = null, oppoStream = null, peerData = null, timeOut = null; var myVideoView = document.getElementById('myVideo'); //我的本地视频 var yourVideoView = document.getElementById('yourVideo'); //对方视频信息 var getWidthScale = document.documentElement.clientWidth; $(function() { $(".videoMy video").css({ "width": getWidthScale * 1.5 * 0.2 + "px", "margin-left": -getWidthScale * 1.5 * 0.2 / 2 + "px" }) //yourVideoView.load() mediumInfo() //获取摄像头信息 }) function trunPage(){ if($(".superviseBtn").text() == "我是市民") { window.location.href = "index.html" } else if($(".superviseBtn").text() == "我是督办专员") { window.location.href = "acceptingMan.html" } } //视频窗口大小调整 function videoSize() { if(meetingState) { $(".videoYour video").css({ "width": getWidthScale * 1 + "px", "margin-left": -getWidthScale * 1 / 2 + "px" }) meetingState = false } else { $(".videoYour video").css({ "width": getWidthScale * 2.7 + "px", "margin-left": -getWidthScale * 2.7 / 2 + "px" }) } } //切换摄像头 function shotCut() { if(currentVideoIndex == 1) { currentVideoIndex = 0; } else { currentVideoIndex = 1; }; try { var ls = muteSession.connection.getLocalStreams()[0]; //将传输的媒体流直接关闭掉 ls.getTracks().forEach(function(track) { if(track.kind == 'video') { track.stop(); } }); //关闭本地媒体流 if(nativeStream) { nativeStream.getVideoTracks()[0].stop(); } navigator.mediaDevices.getUserMedia({ audio: false, //这里是为了摄像头切换时,回显本地媒体,禁止本地声音 video: { deviceId: videoInputDevices[currentVideoIndex].deviceId }, }).then((stream) => { const tracks = stream.getVideoTracks()[0]; //摄像头切换只替换视频通道 var sender = muteSession.connection.getSenders().find(function(s) { return s.track.kind == tracks.kind; }); sender.replaceTrack(tracks); //本地摄像头切换 nativeStream = stream myVideoView.srcObject = nativeStream; //微信端浏览器适配,需要先stop,然后执行这个函数 myVideoView.onloadedmetadata = function() { //媒体流直接关闭掉后这里会重新执行 if(nativeStream.active) { //在这里需要做判断,判断媒体流处于活动状态 myVideoView.play(); } } }).catch((res) => { alert('getUserMedia() error1: ' + res.name); }) } catch(e) { alert(JSON.stringify(e)); } } //监测当前传输速率 function monitoringData() { //发送的数据 muteSession.connection.getSenders().forEach(getData => { if(getData.track.kind === "audio") { getData.getStats().then(reports => { reports.forEach(report => { if(report.type === "outbound-rtp") { console.log("发送的数据audio===" + report.bytesSent) } }) }) } else if(getData.track.kind === "video") { getData.getStats().then(reports => { reports.forEach(report => { if(report.type === "outbound-rtp") { console.log("发送的数据video===" + report.bytesSent) // $(".senderSpeedVideo").text(report.bytesSent) } }) }) } }) //接收的数据 muteSession.connection.getReceivers().forEach(getData => { if(getData.track.kind === "audio") { getData.getStats().then(reports => { reports.forEach(report => { if(report.type === "inbound-rtp") { console.log("接收的数据audio===" + report.bytesReceived) // $(".receiverSpeedAudio").text(report.bytesReceived) } }) }) } else if(getData.track.kind === "video") { getData.getStats().then(reports => { reports.forEach(report => { if(report.type === "inbound-rtp") { console.log("接收的数据video===" + report.bytesReceived) // $(".receiverSpeedVideo").text(report.bytesReceived) $(".receiverSpeedVideo").show() $(".refreshImg").show() $(".receiverSpeedVideo").text("黑屏重置按钮") setTimeout(function() { $(".receiverSpeedVideo").hide() }, 5000) } }) }) } }) } $(".internetSpeed img").click(function() { yourVideoView.play(); }) //获取摄像头,音频设备信息 function mediumInfo() { navigator.mediaDevices.enumerateDevices() .then(gotDevices).catch(handleError); function gotDevices(deviceInfos) { deviceInfos.forEach(function(n) { if(n.kind === 'videoinput') { videoInputDevices.push(n); } }) } function handleError(error) { //alert(JSON.stringify(error)); } } //注册成功事件 function registered() { $(".registStatus").show() if($(".superviseBtn").text() == "我是市民") { VideoReqBindAgent() } else if($(".superviseBtn").text() == "我是督办专员") { $(".registStatus").text("连接成功") $("#account").val(extenNum) } } //电话呼入事件 function newRTCSession() { $(".mui-content").hide(); $(".callHtml").show(); $(".dropIcon").hide() $(".answerIcon").show(); if(!nativeStream) { captureLocalMediaVideo() } localMediaStream() } //确认呼叫后触发 function confirmed() { $(".dropIcon").show() $(".answerIcon").hide() //延时函数 timeOut = setTimeout(function() { monitoringData() }, 10000) } //peerconnection 媒体传输事件 function peerconnection() { $(".videoYour").show(); $(".customerImg").show(); $(".rightImg").hide(); } //点击对方视频框 $(".videoYour").click(function() { if(!$(this).attr("index")) { $(this).css(bigVideoStyle) $(".videoYour video").css({ "width": getWidthScale * 2.7 + "px", "margin-left": -getWidthScale * 2.7 / 2 + "px" }) $(".videoMy").css(smallVideoStyle) $(".videoMy video").css({ "width": getWidthScale * 1.5 * 0.2 + "px", "margin-left": -getWidthScale * 1.5 * 0.2 / 2 + "px" }) $(this).attr("index", "1") $(".videoMy").removeAttr("index") } }) //点击我方视频框 $(".videoMy").click(function() { if(!$(this).attr("index")) { $(this).css(bigVideoStyle) $(".videoMy video").css({ "width": getWidthScale * 1.5 + "px", "margin-left": -getWidthScale * 1.5 / 2 + "px" }) $(".videoYour").css(smallVideoStyle) $(".videoYour video").css({ "width": getWidthScale * 2.7 * 0.2 + "px", "margin-left": -getWidthScale * 2.7 * 0.2 / 2 + "px" }) $(this).attr("index", "1") $(".videoYour").removeAttr("index") } }) //视频呼叫 $(".videoCall").click(function() { if($(".registStatus").text() == "已注销") { alert("话机已注销,如有需要请重新进入") return } callVideoState = true; callVideoFail = true; calState = $(this).attr("data-attr"); $(".videoMy").show(); $(".answerIcon").hide() $(".leftText").html("连接中"); videoSize(); //视频窗口大小 if(!nativeStream) { captureLocalMediaVideo() } localMediaStream(); //获取本地媒体流 }) //静音 $(".muteBtn").click(function() { muteSession.mute({ 'audio': true, // Local audio is muted }) $(".muteBtn").hide(); $(".unMuteBtn").show(); }) //取消静音 $(".unMuteBtn").click(function() { muteSession.unmute({ 'audio': true, // Local audio is muted }) $(".muteBtn").show(); $(".unMuteBtn").hide(); }) //关闭摄像头 摄像头切换时会遇到问题 $(".cameraBtn").click(function() { muteSession.mute({ 'video': true, // Local audio is muted }) $(".cameraBtn").hide(); $(".unCameraBtn").show(); }) //取消关闭摄像头 $(".unCameraBtn").click(function() { muteSession.unmute({ 'video': true, // Local audio is muted }) $(".cameraBtn").show(); $(".unCameraBtn").hide(); }) //视频呼叫 function videoCall() { $(".mui-content").hide(); $(".callHtml").show(); var sip_phone_number_ = callNum.toString(); var options = { 'eventHandlers': eventHandlers, 'mediaConstraints': { 'audio': true, 'video': true }, 'mediaStream': localStream }; callVideoState = false; dbCallVideoState = false; outgoingSession = userAgent.call(sip_phone_number_, options); } //接听 function answerCall() { clearTimeout(timeInterval) videoSize(); //视频窗口大小 if(incomingSession) { incomingSession.answer({ 'mediaConstraints': { 'audio': true, 'video': true }, 'mediaStream': localStream }); incomingSession = null; } } //挂断 function hangupCall() { $(".receiverSpeedVideo").text("") clearTimeout(timeOut) clearInterval(timer) closeMediaVideo() $(".refreshImg").hide() userAgent.terminateSessions(); console.log('挂断----------->'); if($(".superviseBtn").text() == "我是督办专员") { $(".mui-content").show(); $(".callHtml").hide(); videoDesExten() } else if($(".superviseBtn").text() == "我是市民") { if(acceptExtenNum) { window.location.href = "acceptingMan.html?extenNum=" + $("#account").val() + "&telephone=" + $("#telephone").val() + "&mathRanDom=" + Math.random() + "&acceptExtenNum=" + acceptExtenNum } else { window.location.href = "acceptingMan.html?extenNum=" + $("#account").val() + "&telephone=" + $("#telephone").val() + "&mathRanDom=" + Math.random() } } } //注销 function unReg() { // window.localStorage.setItem('mathRanDom',Math.random()) if(!superviseMan) { userAgent.unregister(true); clearInterval(timer) $(".registStatus").html("已注销") $(".mui-content").show(); $(".refreshImg").hide() $(".receiverSpeedVideo").hide() $(".callHtml").hide(); $(".dropIcon").hide(); $(".answerIcon").hide(); console.log('注销----------->'); } else { if(acceptExtenNum) { window.location.href = "acceptingMan.html?extenNum=" + $("#account").val() + "&telephone=" + $("#telephone").val() + "&mathRanDom=" + Math.random() + "&acceptExtenNum=" + acceptExtenNum } else { window.location.href = "acceptingMan.html?extenNum=" + $("#account").val() + "&telephone=" + $("#telephone").val() + "&mathRanDom=" + Math.random() } } } //开启本地摄像头 function captureLocalMediaVideo() { navigator.mediaDevices.getUserMedia({ video: { deviceId: videoInputDevices[currentVideoIndex].deviceId }, 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.mediaDevices.getUserMedia({ video: { deviceId: videoInputDevices[currentVideoIndex].deviceId }, audio: true }).then((stream) => { localStream = stream; if(callVideoState) { extenBind() } if(dbCallVideoState) { videoReqIdeAgent() } }).catch((res) => { // alert('getUserMedia() error3: ' + res.name); setTimeout(function() { localMediaStream() }, 1000) }) // navigator.getUserMedia({ // video: { // deviceId: videoInputDevices[currentVideoIndex].deviceId // }, // audio: true // }, function(stream) { // localStream = stream; // if (callVideoState) { extenBind() } // if (dbCallVideoState) { videoReqIdeAgent() } // }, function(e) { // alert('getUserMedia() error: ' + e.name); // }); } // 关闭摄像头 function closeMediaVideo() { if(nativeStream) { nativeStream.getTracks().forEach(function(track) { track.stop(); }); } if(localStream) { localStream.getTracks().forEach(function(track) { track.stop(); }); } if(oppoStream) { oppoStream.getTracks().forEach(function(track) { track.stop(); }); } //yourVideoView.remove(); } function sipCallRTCSession(e, state) { console.log(e.session) console.log(state) // 1是呼出,2是呼入 e.session.on("confirmed", function(data){ console.log("confirmed") if(e.session.connection.getReceivers){ peerconnection() callVideoFail = false console.log(e.session.connection.getReceivers()) remoteStream = new MediaStream(); e.session.connection.getReceivers().forEach(element => { // track可能一个音轨或者视频轨迹 remoteStream.addTrack(element.track) }) $(".videoYour").empty(); $(".videoYour").append(''); yourVideoView = document.getElementById('yourVideo'); // console.log(remoteStream) confirmed videoSize() yourVideoView.srcObject = remoteStream yourVideoView.onloadedmetadata = function() { yourVideoView.play(); yourVideoView.muted = false; state===1?console.log("呼叫成功"):console.log("接听成功") } } }) } function testStart() { 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:' + $("#account").val() +contact_uri, register: true, //指示启动时JsSIP用户代理是否应自动注册 session_timers: false, //启用会话计时器(根据RFC 4028) register_expires: 60, }; userAgent = new JsSIP.UA(configuration); // JsSIP.debug.enable('JsSIP:*'); JsSIP.debug.disable('JsSIP:*'); //注册成功 userAgent.on('registered', function(data) { console.info("registered: ", data.response.status_code, ",", data.response.reason_phrase); registered(); captureLocalMediaVideo() }); //注册失败 userAgent.on('registrationFailed', function(data) { console.log('注册失败----------->'); }); //在注册到期前几秒钟触发,可在这里重新注册 userAgent.on('registrationExpiring', function() { // console.log('注册到期----------->'); // userAgent.register(); //重新注册执行的函数 }); //每次传输连接尝试均触发。 userAgent.on('connecting ', function(data) { console.log('建立连接----------->'); }) //建立传输连接时触发。 userAgent.on('connected ', function(data) { console.log('连接成功----------->'); }) //当传输连接尝试(或自动重新尝试)失败时触发。。 userAgent.on('disconnected ', function(data) { console.log('连接失败----------->') }) //为传入或传出会话/呼叫激发。 userAgent.on('newRTCSession', function(data) { console.log('建立会话----------->') console.info('onNewRTCSession: ', data); muteSession = data.session var originator = data.originator; var session = data.session; var request = data.request; if(data.originator == 'remote') { console.log("电话呼入----------->"); //电话呼入 sipCallRTCSession(data, 2) incomingSession = data.session; newRTCSession(); timeInterval = setInterval(function() { if(incomingSession.isEnded()) { unReg() clearTimeout(timeInterval) } }, 2000) } else { sipCallRTCSession(data, 1) outgoingSession = data.session; outgoingSession.on('connecting', function(data) { currentSession = outgoingSession; outgoingSession = null; }); } //接受呼叫时激发 data.session.on('accepted', function(data) { console.info("接受呼叫----------->"); if(data.originator == 'remote' && currentSession == null) { currentSession = incomingSession; incomingSession = null; } }); //确认呼叫后激发 data.session.on('confirmed', function(data) { console.info("确认呼叫----------->"); $(".leftText").html("通话中"); confirmed(); if(data.originator == 'remote' && currentSession == null) { currentSession = incomingSession; incomingSession = null; } }); //SDP传递之前激发。可以修改传入和传出SDP的机制。 data.session.on('sdp', function(data) { console.info("sdp消息----------->"); }); //接收或生成请求的SIP类响应时激发。该事件在SDP处理之前触发,以便在需要时对其进行微调,甚至通过删除数据对象中响应参数的主体来删除它 data.session.on('progress', function(data) { console.info("接收到sip响应----------->"); if(originator != 'remote') { $(".dropIcon").show() } }); }); //连接到信令服务器,并恢复以前的状态,如果以前停止。重新开始时,如果UA配置中的参数设置为register:true,则向SIP域注册。 userAgent.start(); //网页中有些不稳定,所以开启了定时注册 timer = setInterval(function() { userAgent.register(); //注册到期时,重新注册,这个函数不会影响,话机状态 console.log("重新注册了----------->") }, 30 * 1000) } var eventHandlers = { 'progress': function(e) { console.log('接收到响应----------->'); }, 'failed': function(e) { if(callVideoFail) { // setTimeout(function() { // videoCall() // }, 2000) } console.log('呼叫失败'); }, 'ended': function(e) { console.log('通话结束----------->'); unReg(); }, 'confirmed': function(e) { console.log('确认呼叫----------->'); } };