jssip(呼叫,接听,重新协商等功能实现)

news/2024/11/14 19:40:26/

jssip(呼叫,接听,重新协商等功能实现)

<template><div class="head"><a-button type="primary" @click="call">call</a-button><a-button type="primary">answer</a-button><a-button type="primary" @click="renegotiate">renegotiate</a-button><a-button type="primary" @click="terminate">terminate</a-button><a-button type="primary" @click="peerBtn">对等连接</a-button></div><div class="main"><div><video src="" id="selfVideo" controls></video><video src="" id="remoteVideo" controls></video><audio src="" id="audioElement" controls></audio></div><div class="message"></div></div>
</template><script setup>
import JsSIP from "jssip";
import { onMounted } from "vue";
let currentSession;
let userAgent;
let peer;
onMounted(() => {sip_init();
});
var msg_log;
function sip_init() {msg_log = {el: document.querySelector(".message"),log(msg) {console.log("msg", msg);this.el.innerHTML += `<span class="success">${new Date().toLocaleTimeString()}:${msg}</span></br>`;},error(msg) {console.log("error", msg);this.el.innerHTML += `<span class="error">${new Date().toLocaleTimeString()}:${msg}</span></br>`;},};const name = location.search.slice(6);if (!name) {return msg_log.error("location.search获取不到信息");}const selfVideo = document.querySelector("#selfVideo");const remoteVideo = document.querySelector("#remoteVideo");// 本地加载完成 对端加载完成const socket = new JsSIP.WebSocketInterface("ws://101.200.183.204:5062");const configuration = {sockets: [socket],uri: `sip:${name === "offer" ? 2001 : 2002}@172.24.66.100;transport=ws`,password: "67975111",register: true,session_timers: false,};var ua = new JsSIP.UA(configuration);ua.on("connected", () => msg_log.log("连线中"));ua.on("connecting", () => msg_log.log("接线中"));ua.on("disconnected", () => msg_log.error("取消连线"));ua.on("registered", () =>msg_log.log(`--${name === "offer" ? 2001 : 2002}注册成功`));ua.on("registrationExpiring", () => msg_log.log("注册即将到期,重新注册"));ua.on("registrationFailed", () => msg_log.error("注册失败"));ua.on("unregistered", () => msg_log.log("取消注册"));ua.on("sipEvent", () => msg_log.log("sipEvent"));ua.on("newRTCSession", function (data) {const { session, request, originator } = data;if (originator === "remote") {msg_log.log("对方打电话过来了~~~");} else {msg_log.log("拨打电话中~~~");}currentSession = session;session.on("accepted", () => msg_log.log("通话接受时候触发"));session.on("connecting", () => msg_log.log("通话连线时候触发"));session.on("sdp", () => msg_log.log("交换sdp信令事件触发"));session.on("failed", () => msg_log.log("通话失败事件触发"));session.on("reinvite", () => {openLocalCamera();msg_log.log("重新协商事件触发");audioElement.srcObject = null;if (session._connection.getLocalStreams().length > 0) {// 接听后,判断localStreamselfVideo.srcObject = session?._connection.getLocalStreams()[0];selfVideo.play();}if (session?._connection.getRemoteStreams().length > 0) {remoteVideo.srcObject = session?._connection.getRemoteStreams()[0];remoteVideo.play();}});session.on("progress", () => {if (originator === "remote") {msg_log.log("电话过来拉~~~~~~~~~··");// var flag = confirm("是否接听?");// if (!flag) {//   ua?.terminateSessions();//   return;// }session.answer({mediaConstraints: { audio: true, video: true },// mediaStream: localStream,});msg_log.log("我接听了");}msg_log.log("接听事件在progress中触发");});session.on("confirmed", () => {msg_log.log("呼叫确认--设置媒体流到音视频中");selfVideo.srcObject = null;remoteVideo.srcObject = null;const stream = new MediaStream();const receivers = currentSession.connection?.getReceivers();if (receivers)receivers.forEach((receiver) => stream.addTrack(receiver.track));audioElement.srcObject = stream;// 最后都要播放audioElement.oncanplay = () => {audioElement.play();};});session.on("peerconnection", (data) => {msg_log.log("对等连接事件触发");});session.on("connecting", (data) => {peer = session._connection;console.log(peer, data, "wewewewewewewew");msg_log.log("对等连接建立,connecting");});session.on("ended", () => msg_log.log("通话结束"));});userAgent = ua;ua.start();
}
const eventHandlers = {progress: function (e) {console.log("call is in progress");},failed: function (e) {console.log("call failed: ", e);},ended: function (e) {console.log("call ended : ", e);},confirmed: function (e) {console.log("call confirmed");},
};
function call() {const opt = {mediaConstraints: {audio: true,video: false,},eventHandlers,};msg_log.log("1001 呼叫");userAgent.call("sip:2002@101.200.183.204", opt);
}
// 重新协商
function renegotiate() {// openLocalCamera();var options = {useUpdate: false,rtcOfferConstraints: {mandatory: {OfferToReceiveAudio: true,OfferToReceiveVideo: true,},},pcConfig: {rtcpMuxPolicy: "negotiate",iceServers: [{ urls: ["stun:stun.l.google.com:19302"] }],},};currentSession.renegotiate(options, () => {audioElement.srcObject = null;if (currentSession._connection.getLocalStreams().length > 0) {// 接听后,判断localStreamselfVideo.srcObject = currentSession?._connection.getLocalStreams()[0];selfVideo.play();}if (currentSession?._connection.getRemoteStreams().length > 0) {remoteVideo.srcObject = currentSession?._connection.getRemoteStreams()[0];remoteVideo.play();}console.log("我重新协商成功了~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");});
}
function terminate() {currentSession.terminate();
}
//开启本地摄像头,并把当前的媒体流添加到peerConnection中
function openLocalCamera() {// 1.获取本地音视频流// 调用 getUserMedia API 获取音视频流let constraints = {video: true,// audio: true,// audio: {//     // 设置回音消除//     noiseSuppression: true,//     // 设置降噪//     echoCancellation: true,// }};navigator.mediaDevices.getUserMedia(constraints).then(gotLocalMediaStream).catch((err) => {console.log("getUserMedia 错误", err);});
}
async function gotLocalMediaStream(mediaStream) {selfVideo.srcObject = mediaStream;selfVideo.play();const mediaStreamTrack = mediaStream.getTracks()[0];const localStream = mediaStream;localStream.getTracks().forEach((track) => {peer.addTrack(track, mediaStream);});// 这里每次开启本地视频流都要重新发送offer到对端// await peer.setLocalDescription(offer);
}
//关闭本地的视频流
function closeLocalMedia() {peerConnection.removeTrack(this.rtpSender);
}
async function peerBtn() {console.log(peer, "peer");// const await navigator.const stream = await navigator.mediaDevices.getUserMedia({ video: true });stream.getTracks().forEach((track) => {peer.addTrack(track, stream);});selfVideo.srcObject = stream;selfVideo.play();// openLocalCamera();
}
// 在关闭视频流之后,video标签会显示最后一帧的画面,如果想使video标签展示初始状态,可以调用video.load()
// video.load(); //视频回到初始状态
</script><style lang="less">
.head {height: 50px;background-color: #ccc;display: flex;align-items: center;margin-bottom: 20px;button {margin: 0 10px;}
}
.main {display: flex;.message {margin-left: 100px;background-color: rgba(0, 0, 0, 0.729);width: 500px;border: 2px solid #000;span.success {color: green;}span.error {color: red;}}
}
</style>

http://localhost:8080/?type=offer 发送方

http://localhost:8080/?type=answer 接听方


http://www.ppmy.cn/news/271063.html

相关文章

接听拨打电话没有声音而其他正常的解决办法

安卓手机接听拨打电话没有声音而其他运行正常&#xff0c;原因如下&#xff1a; 很多第三方软件开机加速会误把com.qualcomm.qti.telephonyservice这个软件自启给禁用了 我们把com.qualcomm.qti.telephonyservice这个软件自启打开&#xff0c;然后重启一下手机就行了&#xff0…

android 拨打电话、 监听来电、监听呼出电话的功能实现

demo1&#xff08;通用&#xff09;&#xff1a; 权限 <!-- 监听呼出电话 --> <uses-permission android:name"android.permission.PROCESS_OUTGOING_CALLS" /> <!-- 监听来电 --> <uses-permission android:name"android.per…

AutoAnswer使用指南(QQ、微信自动接听)

软件下载地址&#xff1a;https://pan.baidu.com/s/19fX1NRup7v0bhtq9WSON8A BUG反馈&#xff1a; QQ群&#xff1a;563152032 --------------------------------------------------------------- 如果安装的是 1.3.6738.R之前的版本&#xff0c;要先卸载旧的版本再安装新版…

android 来电自动接听和自动挂断

转自&#xff1a;http://stephen830.iteye.com/blog/1181786 //-----------------------------------------------------------------------------------------------------------------------------------// android 来电自动接听和自动挂断 注意&#xff1a;android2.3版本不…

android 通话状态监听(自定义接听挂断按钮与通话界面,根据公司的业务逻辑可以实现自己的来电秀功能)...

前言&#xff1a; 因为公司需求&#xff0c;要自定义一款来电秀的app当做周边产品来配合主营的app业务。 之前因为赶项目&#xff0c;没时间整理这块&#xff0c;现在项目告一段落了&#xff0c;现在回头看看感觉这个功能还是挺有意思的&#xff0c;比较有针对性。电话呼入或者…

无人值守安装

自动化安装Linux 一、PXE1.1PXE概念1.2协议分类1.3 优点1.4 批量安装的前置条件1.5 PXE实现的过程详解 二、配置PXE远程安装服务器2.1 思路2.2 配置步骤2.3 配置应答文件总结&#xff1a; 引言&#xff1a; 学会自动安装&#xff0c;安逸的很 一、PXE 1.1PXE概念 PXE 是由 In…

出租车不需要司机了?带你体验无人驾驶出租车!|『智能产品家』第三期

消费者真的了解什么是自动驾驶吗&#xff1f; 不同级别的自动驾驶汽车有什么区别&#xff1f; 自动驾驶系统开发商及汽车制造商真正了解消费者的现实需要吗&#xff1f; 正是这一系列的问题&#xff0c;促使自动驾驶标准制定组织SAE与上海国际汽车城、联合中智行和Velodyne Lid…

电话来电,接听解读

OutgoingCallBroadcaster将在往外拨打电话时被调用&#xff0c;当然执行其onCreate()方法 首先&#xff1a; mPhone PhoneApp.getInstance().phone; Intent intent getIntent(); if (LOGV) Log.v(TAG, "onResume: Got intent " intent "."); S…