JsSIP Demo
1安装FreeSWITCH
可直接下载FreeSWITCH-1.10.12-Release-x64.msi在Windows系统安装。
2配置FreeSWITCH
设置它采用 media proxy 模式来代理转发 WebRTC 的音视频。
修改vars.xml,加入:
<X-PRE-PROCESS cmd=="set" data="proxy_media=true"/>
修改sip_profiles/internal.xml,设置inbound-proxy-media和inbound-late-negotiation为true,类似下面:
<!--Uncomment to set all inbound calls to proxy media mode-->
<param name="inbound-proxy-media" value="true"/>
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
这样配置之后,FreeSWITCH 会进入代理模式,不对media 做任何处理,直接在两个 end peer 之间转发(RTP包)。
3JsSIP开发
JsSIP是一个用JavaScript编写的轻量级且功能丰富的SIP库,它利用了SIP和WebRTC技术的最新进展,使得任何网站都能够通过简单的代码集成,实现音视频通话、即时消息和状态展示等实时通信功能。以下是JsSIP的一些主要特性和使用方法:
-
WebSocket 传输:JsSIP通过WebSocket与SIP服务器进行通信,支持ws和wss协议 。
-
音视频通话和即时消息:JsSIP支持音频和视频通话,以及发送和接收即时消息 。
-
轻量级和纯JavaScript构建:JsSIP是一个轻量级的库,完全使用JavaScript从头构建,易于集成和使用 。
-
易于使用的API:JsSIP提供了功能强大且易于使用的用户API,可以快速实现复杂的通信功能 。
-
与多种SIP服务器兼容:JsSIP适用于OverSIP、Kamailio和Asterisk等多种SIP服务器 。
-
创建和管理用户代理(User Agent):JsSIP允许创建多个用户代理,每个代理代表一个SIP账户,可以进行注册、呼叫、发送消息等操作 。
-
事件处理:JsSIP定义了一系列事件,允许用户通过注册回调函数来响应特定的事件,例如呼叫进展、注册状态变化等 。
-
调试支持:JsSIP提供了调试功能,可以在浏览器控制台中启用或禁用,以帮助开发者调试应用程序 。
-
信令和媒体控制:JsSIP支持通过API发送和接收SIP信令,并控制WebRTC媒体,例如静音、取消静音、保持和取消保持等 。
-
DTMF和INFO消息:JsSIP支持发送DTMF(双音多频)信号和INFO消息,以增强通话功能 。
-
引入JsSIP依赖
<script src="js/jquery-1.12.4.min.js"></script> -
注册FreeSWITCH
var socket = new JsSIP.WebSocketInterface(ws_uri_);var configuration = {sockets: [ socket ],outbound_proxy_set: ws_uri_,uri: sip_uri_,password: sip_password_,register: true,session_timers: false,register_expires:900//注册时间秒为单位 900s==15m};userAgent = new JsSIP.UA(configuration);userAgent.on('registered', function(data){//初始化成功console.info("registered: ", data.response.status_code, ",", data.response.reason_phrase);...}); -
事件监听
userAgent.on('registered', function(data){// 注册成功...});userAgent.on('registrationFailed', function(data){// 注册失败...});userAgent.on('registrationExpiring', function(){// 注册到期 ...});userAgent.on('newRTCSession', function(data){console.info('onNewRTCSession: ', data);// 来电if(data.originator == 'remote'){...}else{// 去电...}// 被叫方接受data.session.on('accepted', function(data){...});data.session.on('confirmed', function(data){...});data.session.on('sdp', function(data){...});data.session.on('progress', function(data){...});data.session.on('ended', function (data) {//已建立的通话结束时...});data.session.on('peerconnection', function(data){...});});userAgent.on('newMessage', function(data){...});userAgent.start(); -
呼叫
// 获取本地媒体 function gotLocalMedia(stream) { console.info('Received local media stream'); localStream = stream; // 注意:这里仍然使用了全局变量 $('#localView').prop('src', URL.createObjectURL(stream)); } // 获取本地媒体 function captureLocalMedia() {console.info('Requesting local video & audio');if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia(constraints) .then(gotLocalMedia) .catch(function(e) { alert('getUserMedia() error: ' + e.name); }); } else { alert('Your browser does not support getUserMedia API.'); } } // 呼叫 userAgent.call(sip_phone_number, options); -
接听
// 来电if(data.originator == 'remote'){//响铃var callAudio = new Audio();callAudio.src = "./sounds/ringing.ogg";callAudio.play();$("#repetition").css("display", "block");$("#going").on('click', function(){$("#repetition").css("display", "none");captureLocalMedia();console.info("incomingSession, answer the call");incomingSession = data.session;data.session.answer({'mediaConstraints': {'audio': true,'video': true},'mediaStream': localStream});});$("#outing").on('click', function(){$("#repetition").css("display", "none");data.session.terminate();var serAudio = new Audio();serAudio.src = "./sounds/rejected.mp3";serAudio.play();});} -
挂断
data.session.on('ended', function (data) {//已建立的通话结束时console.info('ended - ', data);if (data.originator == "remote") {alert("对方挂断"); window.location.reload(true); } else if (data.originator == "local") { alert("您已挂断");window.location.reload(true);} else { alert("系统挂断"); window.location.reload(true); } });



学习交流可私信
