类型:开发

描述:
This commit is contained in:
2025-05-15 09:15:33 +08:00
parent 3763508fab
commit 21a3bc6452
8 changed files with 684 additions and 9 deletions

1
src/assets/com/jssip.js Normal file

File diff suppressed because one or more lines are too long

592
src/assets/com/webrtc.js Normal file
View File

@@ -0,0 +1,592 @@
import JsSIP from 'jssip';
export default class MyWebrtc {
constructor() {
var MediaStreamTrack = null;
var peerconnection = null;
var outgoingSession = null;
var incomingSession = null;
var currentSession = null;
var getJsSipgetIp = null; //存取全局IP
var getJsSipPhoneNumber = null; //存取全局号码
var getJsSipgetPassWord = null; //存取全局密码
var getstatus1 = null;
var getstatus2 = null;
var globalRegisteState = '未注册';//注册状态
var globalCallPhoneStates = "未通话";//通话状态
var judgeIsVoice = "";//判断是语音拨打还是视频拨打
var Datas = null;
var useVideo = true;
var selfViewWap = document.getElementById('selfViewWap');
URL = window.URL || window.webkitURL;
var localStream = null;
var userAgent = null;
var autoAnswerFlag = false;//是否自动接听
var holdFlag = false;
var session;
var incomingCallAudio = new window.Audio('./static/incoming-call-ringtone.wav');
var ringbackAudio = new window.Audio('./static/ringbacktone.wav');
incomingCallAudio.loop = true;
ringbackAudio.loop = true;
var remoteAudio = new window.Audio();
remoteAudio.autoplay = true;
var meVideo;
var youVideo;
var constraints = {
audio: true,
video: false
};
if(useVideo){
constraints = {
audio: true,
video: true
};
}
//jssip实例初始化
this.jssipAgent = function(JsSipPhoneNumber, JsSipgetIp, JsSipgetPort, JsSipgetPassWord, remoteVideo, Registerstate, Callstate) {
getJsSipPhoneNumber = JsSipPhoneNumber;
getJsSipgetIp = JsSipgetIp;
getJsSipgetPassWord = JsSipgetPassWord;
getstatus1 = Registerstate;
getstatus2 = Callstate;
var phoneNumber = JsSipPhoneNumber + "@";
var getIp = JsSipgetIp;
getJsSipgetIp = JsSipgetIp;
// var lastPort = ":5060"
//var sip_uri_ = (phoneNumber + getIp + lastPort).toString();
var sip_uri_ = ("sip:"+phoneNumber + getIp).toString();
console.log(sip_uri_);
// var ws_uri_ = "ws://10.0.11.120:5066";
var _Ws = "ws://";
var _WsPort = ":"+JsSipgetPort;
var ws_uri_ = (_Ws + getIp + _WsPort).toString();
console.log(ws_uri_);
//var sip_password_ = document.getElementById('JsSipgetPassWord').value;
var sip_password_ = JsSipgetPassWord;
// var sip_password_ = "1234";
JsSIP.C.SESSION_EXPIRES=120,JsSIP.C.MIN_SESSION_EXPIRES=120;
var socket = new JsSIP.WebSocketInterface(ws_uri_);
var configuration = {
sockets: [socket],
uri: sip_uri_,
register: true,
password: sip_password_,
contact_uri: sip_uri_ + ';transport=wss',
ws_servers: ws_uri_
//session_timers: false
};
userAgent = new JsSIP.UA(configuration);
incomingCallAudio.play();
incomingCallAudio.pause();
ringbackAudio.play();
ringbackAudio.pause();
userAgent.on('registered', function(data) {
//console.log(data);
console.info("registered: ", data.response.status_code, ",", data.response.reason_phrase);
});
//未注册
userAgent.on('unregistered', function(e) {
console.log("未注册", e);
});
userAgent.on('registrationFailed', function(data) {
console.log("registrationFailed, ", data);
});
//1.在注册到期之前发射几秒钟。如果应用程序没有为这个事件设置任何监听器JsSIP将像往常一样重新注册。
userAgent.on('registrationExpiring', function() {
//过期之后将自动重新注册
console.warn("registrationExpiring");
//重新注册
userAgent.register();
//jssipAgent(JsSipPhoneNumber,JsSipgetIp,JsSipgetPassWord,remoteVideo,status1,status2);
});
//为传入或传出的会话/呼叫
userAgent.on('newRTCSession', function(data) {
console.info('onNewRTCSession: ', data);
if(data.originator == 'remote') { //incoming call
if(globalCallPhoneStates == "连接中" || globalCallPhoneStates == "通话中" || globalCallPhoneStates.indexOf("来电")>-1){
var options2 = {
all: false,
'status_code':486
};
data.session.terminate(options2);
return;
}
autoAnswerFlag = document.getElementById('autoAnswerFlag').checked;
console.info("incomingSession, answer the call");
incomingSession = data.session;
Datas = data.session;
var incomingNum = data.request.headers.From[0].raw;
if(incomingNum.indexOf("sip:")>0){
incomingNum = incomingNum.substring(incomingNum.indexOf("sip:")+4);
incomingNum = incomingNum.substring(0,incomingNum.indexOf("@"));
}
globalCallPhoneStates = incomingNum+"来电";
if(useVideo){
initVideo();
}
if(autoAnswerFlag){//自动接听
incomingCallAudio.pause();
if(useVideo){
Datas.answer({
'mediaConstraints': {
'audio': true,
"video": true
},
'mediaStream': null
});
}else{
Datas.answer({
'mediaConstraints': {
'audio': true,
"video": false
},
'mediaStream': null
});
}
getstatus2.innerText = "通话中";
globalCallPhoneStates = "通话中";
Datas.connection.ontrack = getRemoteStream;
}
} else {
peerconnection = data.session.connection;
peerconnection.ontrack = getRemoteStream;
if(useVideo){
initVideo();
}
//peerconnection.addEventListener('addstream', function(ev) {
// ringbackAudio.pause();
// console.info('onaddstream from remote - ', ev);
// remoteAudio.srcObject = ev.stream;
//});
console.info("outgoingSession");
outgoingSession = data.session;
outgoingSession.on('connecting', function(data) {
//通话状态
// Callstate.innerText = "连接中";
// globalCallPhoneStates = "连接中";
console.info('onConnecting - ', data.request);
currentSession = outgoingSession;
outgoingSession = null;
});
}
//远程挂断事件
data.session.on("ended", function(data) {
console.log("call end", data);
//通话状态
var call_id = "";
if(data.message!=null && data.message.call_id!=null){
call_id = data.message.call_id;
}else if(currentSession!=null && currentSession._request.call_id!=null){
call_id = currentSession._request.call_id;
}
doEvent("hangup_event",'',call_id);
//Callstate.innerText = "已挂断";
globalCallPhoneStates = "已挂断";
clearVideo();
currentSession = null;
});
data.session.on('accepted', function(data) {
console.info('onAccepted - ', data);
var call_id = "";
if(data!=null && data.request!=null && data.request.call_id!=null){
call_id = data.request.call_id;
}else if(data!=null && data.response!=null && data.response.call_id!=null){
call_id = data.response.call_id;
}
if(data.originator == 'remote' && currentSession == null) {
currentSession = incomingSession;
incomingSession = null;
// console.info("setCurrentSession - ", currentSession);
// //通话状态
// doEvent("answer_event",'',call_id);
//getstatus2.innerText = "通话中 00:00";
globalCallPhoneStates = "通话中 00:00";
}else if(currentSession != null){
// doEvent("answer_event",'',call_id);
//getstatus2.innerText = "通话中 00:00";
globalCallPhoneStates = "通话中";
}
});
data.session.on('confirmed', function(data) {
console.info('onConfirmed - ', data);
if(data.originator == 'remote' && currentSession == null) {
currentSession = incomingSession;
incomingSession = null;
console.info("setCurrentSession - ", currentSession);
//通话状态
// doEvent("answer_event",'',data.ack.call_id);
//getstatus2.innerText = "通话中";
globalCallPhoneStates = "通话中";
}
});
data.session.on('sdp', function(data) {
console.info('onSDP, type - ', data.type, ' sdp - ', data.sdp);
if(data.type=="answer" && currentSession != null){
var holdOption = currentSession.isOnHold();
if(holdOption.local){
holdFlag = true;
doEvent("hold_event",'',data.request.call_id);
}else if(holdFlag){;
holdFlag = false;
doEvent("unhold_event",'',data.request.call_id);
}
}
/*
var changeSDP="";
var snsArr = data.sdp.split(/[(\r\n)\r\n]+/);
var videoCodec = false;
var rtpmap = false;
snsArr.forEach((item,index)=>{
console.info("index[",index,"]",snsArr[index]);
var str = snsArr[index];
if(str.indexOf("m=video ")>-1){
videoCodec = true;
}
if(videoCodec){
if(str.indexOf("a=rtpmap:")>-1){
rtpmap = true;
}
if(str.indexOf("m=video ")>-1 && str.indexOf("UDP/TLS/RTP/SAVPF")>-1){
str = str.substring(0,str.indexOf("UDP/TLS/RTP/SAVPF"))+" UDP/TLS/RTP/SAVPF 102";
changeSDP=changeSDP+str+'\n';
}else if(rtpmap){
if(str.indexOf("a=rtpmap:102 H264/90000")>-1 || str.indexOf("a=fmtp:102 ")>-1
|| str.indexOf("a=ssrc")>-1 || str.indexOf("a=rtcp-fb:102 ")>-1){
changeSDP=changeSDP+str+'\n';
}
}else{
changeSDP=changeSDP+str+'\n';
}
}else{
changeSDP=changeSDP+str+'\n';
}
})
*/
//data.sdp = changeSDP;
//console.info('onSDP, changed sdp - ', data.sdp);
//data.sdp = data.sdp.replace('UDP/TLS/RTP/SAVPF', 'RTP/SAVPF');
//console.info('onSDP, changed sdp - ', data.sdp);
});
data.session.on('progress', function(data) {
console.info('onProgress - ', data.originator);
if(data.originator == 'remote') {
console.info('onProgress, response - ', data.response);
if(data.response!=null && data.response.status_code!=null && data.response.status_code=='183'){
ringbackAudio.pause();
}
//通话状态
//status2.innerText = "通话中";
}
});
data.session.on('peerconnection', function(data) {
console.info('onPeerconnection - ', data.peerconnection);
console.log(data);
data.peerconnection.ontrack = getRemoteStream;
//data.peerconnection.onaddstream = function(ev) {
// ringbackAudio.pause();
// console.info('onaddstream from remote - ', ev);
// remoteAudio.srcObject = ev.stream;
//};
});
data.session.on('addstream', function(e){
console.info('on addstream - ');
incomingCallAudio.pause();
remoteAudio.src = e.stream;
});
data.session.on('failed', function(e){
console.info('on failed - ');
var call_id = "";
if(incomingSession!=null && incomingSession._requst!=null){
call_id = incomingSession._requst.call_id;
}
// doEvent("hangup_event",'',call_id);
// globalCallPhoneStates = "未通话";
if(incomingSession!=null){
incomingCallAudio.pause();
incomingSession = null;
}
clearVideo();
currentSession = null;
});
if(data.session.direction === 'incoming'){
console.log('incoming - ',data.session);
autoAnswerFlag = document.getElementById('autoAnswerFlag').checked;
if(!autoAnswerFlag){
incomingCallAudio.play();
}
}
});
console.info("call register");
userAgent.start();
}
// Register callbacks to desired call events
var eventHandlers = {
'progress': function(e) {
// ringbackAudio.play();
console.log('call is in progress');
// getstatus2.innerText = "连接中";
// globalCallPhoneStates = "连接中";
},
'failed': function(e) {
console.log('call failed: ', e);
ringbackAudio.pause();
if(e.cause == "Busy") {
console.error("用户正忙");
// getstatus2.innerText = "用户正忙";
// globalCallPhoneStates = "用户正忙";
} else {
console.error("拨打失败");
//通话状态
// getstatus2.innerText = "拨打失败";
// globalCallPhoneStates = "拨打失败";
}
clearVideo();
},
'ended': function(e) {
//隐藏本地视频区域
//selfViewWap.style.display = "none";
console.log('call ended : ', e);
//通话状态
getstatus2.innerText = "已挂断";
globalCallPhoneStates = "已挂断";
clearVideo();
currentSession = null;
},
'confirmed': function(e) {
ringbackAudio.pause();
console.log('call confirmed');
}
};
//语音拨打
this.JsSip_VoiceCall = function(callPhone,isVoice) {
console.log("isVoice",isVoice);
judgeIsVoice = isVoice;//判断是语音拨打还是视频拨打
//var sip_phone_number_ ="sip:1000@10.0.11.120:5060";
var sip = "sip:";
var getIp = getJsSipgetIp;
var sip_phone_number_ = (sip + callPhone + "@" + getIp).toString();
console.log(sip_phone_number_);
var options = {
'eventHandlers': eventHandlers,
'mediaConstraints': constraints,
'mediaStream': null
};
outgoingSession = userAgent.call(sip_phone_number_, options);
}
//接听
this.VoiceAnsWter = function() {
incomingCallAudio.pause();
if(useVideo){
Datas.answer({
'mediaConstraints': {
'audio': true,
"video": true
},
'mediaStream': null
});
}else{
Datas.answer({
'mediaConstraints': {
'audio': true,
"video": false
},
'mediaStream': null
});
}
//getstatus2.innerText = "通话中";
//globalCallPhoneStates = "通话中";
}
//发送DTMF
this.VoiceSendDTMF = function(dtmf) {
if(incomingSession!=null){
incomingSession.sendDTMF(dtmf);
}else{
currentSession.sendDTMF(dtmf);
}
}
//通话保持
this.VoiceHold = function() {
//var hOptions = {
// 'useUpdate': true,
// 'mediaStream': null
//};
if(incomingSession!=null){
incomingSession.hold();
}else{
currentSession.hold();
}
}
//解除保持
this.VoiceUnHold = function() {
if(incomingSession!=null){
incomingSession.unhold();
}else{
currentSession.unhold();
}
}
//挂断
this.JsSip_hangUpPhone = function() {
//关闭本地摄像头
//this.closeLocalCapature();
//userAgent.stop();//保存当前的注册状态并在正常注销并终止活动会话(如果有)后断开与信令服务器的连接。
var options = {
all: false,
'status_code':486
};
if(incomingSession!=null){
incomingCallAudio.pause();
incomingSession.terminate(options);
}else{
userAgent.terminateSessions(options); //终止当前对话
}
//通话状态
//getstatus2.innerText = "已挂断";
//globalCallPhoneStates = "已挂断";
//当挂断电话要重新调用注册接口
//this.jssipAgent(getJsSipPhoneNumber,getJsSipgetIp,getJsSipgetPassWord,getRemoteVideo,getstatus1,getstatus2);
}
//注销
this.JsSip_clearRegested = function() {
var options = {
all: true
};
userAgent.unregister(options);
//userAgent.stop();//保存当前的注册状态并在正常注销并终止活动会话(如果有)后断开与信令服务器的连接。
}
//注册状态
this.getRegisterState = function () {
return globalRegisteState;
}
//通话状态
this.callPoneState = function(){
return globalCallPhoneStates;
}
//获取远程媒体流
function getRemoteStream(e) {
ringbackAudio.pause();
console.log('getRemoteStream - ', e.track, e.streams[0]);
//remoteAudio.srcObject = e.streams[0];
if(useVideo){
console.log(e.streams[0])
// youVideo.srcObject = e.streams[0];
// document.body.addEventListener('click', function () {
// meVideo.play();
// });
// 等到视频流准备好了
// var interval = setInterval(function () {
// if (!meVideo.videoWidth) {
// return;
// }
// //stage.appendChild(videoView);
// clearInterval(interval);
// }, 1000 / 50);
}else{
// remoteAudio.srcObject = e.streams[0];
}
}
//初始化视频
function initVideo(){
// meVideo = document.getElementById('meVideo');
// meVideo.setAttribute('autoplay', '');
// meVideo.setAttribute('playsinline', '');
// meVideo.style.width = '212px';
//
// youVideo = document.getElementById('youVideo');
// youVideo.setAttribute('autoplay', '');
// youVideo.setAttribute('playsinline', '');
// youVideo.style.width = '531px';
navigator.mediaDevices.getUserMedia({
audio: false,
video:{
faceMode: 'user'
}
}).then(function success(stream) {
console.log(stream)
// meVideo.srcObject = stream;
// document.body.addEventListener('click', function () {
// meVideo.play();
// });
// // 等到视频流准备好了
// var interval = setInterval(function () {
// if (!meVideo.videoWidth) {
// return;
// }
// //stage.appendChild(videoView);
// clearInterval(interval);
// }, 1000 / 50);
}).catch(function (error) {
alert(error.message);
});
}
//释放视频资源
function clearVideo(){
if(useVideo && meVideo!=null && meVideo.srcObject!=null){
meVideo.pause();
if(meVideo.srcObject.getTracks()[0]!=null){
meVideo.srcObject.getTracks()[0].stop();
}
if(meVideo.srcObject.getTracks()[1]!=null){
meVideo.srcObject.getTracks()[1].stop();
}
meVideo.srcObject = null;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -57,7 +57,9 @@
<div>{{ item.postName }}</div>
<div>{{ item.phoneNumber }}</div>
<div>
<img class="sp-ico" src="@/assets/images/sp-icom.png" />
<img @click="doCallTel(item)" class="tel-ico" src="@/assets/images/tel-icon.png" />
<img @click="doCallVoice(item)" class="voice-ico" src="@/assets/images/voice-icon.png" />
<img @click="doCallVideo(item)" class="sp-ico" src="@/assets/images/sp-icom.png" />
</div>
</div>
</div>
@@ -72,14 +74,27 @@
</div>
</div>
</el-dialog>
<el-dialog v-model="dialogComVideo">
<div class="videoPrefecture_video" id="videoPrefecture">
<video id="youVideo" class="oneVideo"></video>
<video id="meVideo" class="twoVideo"></video>
<!-- <span class="glyphicon glyphicon-volume-down"></span>-->
<!-- <span class="glyphicon glyphicon-off"></span>-->
</div>
</el-dialog>
</div>
</template>
<script setup>
import { getComDeptsApi, getComDeptUsersApi, getComRecordApi } from '@/api/common'
import {useWebSocket} from "@/hooks/socket.js";
import {mode, proSocketBaseUrl, socketBaseUrl} from "@/utils/config.js";
import MyWebrtc from '@/assets/com/webrtc.js';
let deptsList = ref([])
let dialogTableVisible = ref(false)
let dialogTableVisible2 = ref(false)
let dialogComVideo = ref(false)
const webrtcInstance = new MyWebrtc();
const getComDepts = async () => {
let res = await getComDeptsApi()
deptsList.value = res.data
@@ -95,16 +110,31 @@
dialogTableVisible2.value = true
// location.href="http://192.168.0.2:81/";
}
const doCallTel = (item) => {
webrtcInstance.JsSip_VoiceCall('15123854798',true);
dialogComVideo.value=true;
}
const doCallVoice = (item) => {
webrtcInstance.JsSip_VoiceCall('854798',false);
dialogComVideo.value=true;
}
const doCallVideo = (item) => {
webrtcInstance.JsSip_VoiceCall('854798',true);
dialogComVideo.value=true;
}
const handleDepsUser = async (id, item) => {
gridTitle.value = item.name
dialogTableVisible.value = true
let res = await getComDeptUsersApi({ id })
gridData.value = res.data
}
const comRegister = () => {
webrtcInstance.jssipAgent('101','192.168.77.8','7066','Admin246246246',null,null,null);
}
onMounted(() => {
getComDepts()
getComRecord()
comRegister();
})
</script>
@@ -124,8 +154,19 @@
color: #fff;
font-weight: bold;
}
.tel-ico {
width: vw(30);
cursor: pointer;
margin-right: vw(20);
}
.voice-ico{
width: vw(35);
cursor: pointer;
margin-right: vw(20);
}
.sp-ico {
width: vw(40);
cursor: pointer;
}
.item-name {
width: 90%;

View File

@@ -6,9 +6,9 @@ export const useHomeStore = defineStore('home', () => {
// 景区信息数据
let scenicData = ref({
scenicSpot: [
{ value: 0, name: '全县景区数量' },
{ value: 0, name: '核心景区数' },
{ value: 0, name: '低感景区总数' }
{ value: 24, name: '全县景区数量' },
{ value: 5, name: '4A及以上景区数' },
{ value: 3, name: '核心景区总数' }
],
data: [
{ name: '预定今日票:', value: 0 },