FreeSWITCH学习笔记 第二场 第二个镜头 JsSIP视频通讯
2017-12-27 14:46
381 查看
上一章JsSIP初识已经介绍了JsSIP的基本使用方法,这一章将使用FreeSWITCH+JsSIP实现视频通讯,截止本文FreeSWITCH使用1.6.18版本,JsSIP使用的3.0.15版本(经过测试使用3.1.x版本不适用本章的例子)
修改FreeSWITCH安装路径下/conf/var.xml文件中,增加
修改FreeSWITCH安装路径下/conf/sip_profiles/internal.xml文件,设置inbound-proxy-media和inbound-late-negotiation为true
修改配置之后重启FreeSWITCH或者打开FS_Cli输入
如果一直报视频编解码问题的错误,可以尝试修改/conf/var.xml的配置项
![](https://oscdn.geek-share.com/Uploads/Images/Content/202009/07/c30c24bafab3d413447eafd32a31cb98)
由于此类文章不是很受欢迎,所以FreeSWITCH类文章截止此文章为止
如果使用默认密码,而且dailplan保留默认配置的话,会被路由走到一个拨号计划中,导致每次接通电话都需要等待10s ↩
FreeSWITCH配置
修改FreeSWITCH安装路径下/conf/var.xml文件中,修改默认密码1<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
修改FreeSWITCH安装路径下/conf/var.xml文件中,增加
<X-PRE-PROCESS cmd=="set" data="proxy_media=true"/>
修改FreeSWITCH安装路径下/conf/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或者打开FS_Cli输入
reloadxml,然后打开两台机器上的
eyeBeam测试视频通话。
如果一直报视频编解码问题的错误,可以尝试修改/conf/var.xml的配置项
global_codec_prefs和
outbound_codec_prefs如下(增加可用编解码器)
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=OPUS,G722,PCMU,PCMA,GSM,H263,H264,VP8,H263-1998"/> <X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=OPUS,G722,PCMU,PCMA,GSM,H263,H264,VP8,H263-1998"/>
前端页面源码
<!DOCTYPE html> <html> <head> <title>JsSIP + freeSWITCH</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="Author" content="Fly" /> <meta name="description" content="JsSIP Test DEMO" /> <script src="js/jssip-3.0.15.js" type="text/javascript"></script> <style type="text/css"> </style> </head> <body> <div style="padding-bottom:10px;font-weight:bold;">控制台</div> <div id="login-page" style="width: 500px; border: 1px solid #f0f0f0;"> <table border="0"> <tr> <td width="160px" align="left"><label for="sip_uri">自己的SIP URI:</label></td> <td width="300px"><input style="width:250px" id="sip_uri" type="text" value="sip:1000@192.168.17.96"/></td> </tr> <tr> <td align="left"><label for="sip_password">SIP Password:</label></td> <td><input style="width:250px" id="sip_password" type="password" value="0000"/></td> </tr> <tr> <td align="left"><label for="ws_uri">WSS URI:</label></td> <td><input style="width:250px" id="ws_uri" class="last unset" type="text" value="wss://192.168.17.96:7443"/></td> </tr> <tr> <td align="left"><label class="input_label" for="sip_phone_number">拨打SIP URI:</label></td> <td><input style="width:250px" id="sip_phone_number" type="text" value="sip:1001@192.168.17.96"></td> </tr> <tr> <td align="left"><input type="button" onclick="testStart()" value="注册"/></td> <td align="left"><input type="button" onclick="testCall()" value="拨打"/></td> </tr> </table> </div> <div style="padding-top:10px;padding-bottom:10px;font-weight:bold;">视频展示区</div> <div style="padding-top:10px;" align="left"> <table border="0"> <tr> <video id="meVideo" style="padding-right:10px"></video> <video id="youVideo"></video> </tr> </table> </div> </body> <script type="text/javascript"> var outgoingSession = null; var incomingSession = null; var currentSession = null; var meVideo = document.getElementById('meVideo'); meVideo.setAttribute('autoplay', ''); //meVideo.setAttribute('muted', ''); meVideo.setAttribute('playsinline', ''); meVideo.style.width = '360px'; var youVideo = document.getElementById('youVideo'); youVideo.setAttribute('autoplay', ''); //meVideo.setAttribute('muted', ''); youVideo.setAttribute('playsinline', ''); youVideo.style.width = '360px'; var constraints = { audio: true, video: { faceMode: 'user' } }; var localStream = null; var userAgent = null; navigator.mediaDevices.getUserMedia(constraints).then(function success(stream) { meVideo.srcObject = stream; document.body.addEventListener('click', function() { meVideo.play(); }); // wait until the video stream is ready var interval = setInterval(function(){ if(!meVideo.videoWidth){ return; } //stage.appendChild(videoView); clearInterval(interval); }, 1000 / 50); }).catch(function(error){ onError({ name: error.name, message: error.message }); }); function testStart(){ var sip_uri = document.getElementById("sip_uri").value.toString(); var sip_password = document.getElementById("sip_password").value.toString(); var ws_uri = document.getElementById("ws_uri").value.toString(); 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, password: sip_password, register: true, session_timers: false }; userAgent = new JsSIP.UA(configuration); userAgent.on('registered', function(data) { console.info("registered: ", data.response.status_code, ",", data.response.reason_phrase); }); userAgent.on('registrationFailed', function(data) { console.log("registrationFailed, ", data); }); userAgent.on('registrationExpiring', function() { console.warn("registrationExpiring"); }); userAgent.on('newRTCSession', function(data) { console.info('onNewRTCSession: ', data); if(data.originator == 'remote') { console.info("incomingSession, answer the call"); incomingSession = data.session; data.session.answer({'mediaConstraints' : constraints, 'mediaStream': null}); } else { console.info("outgoingSession"); outgoingSession = data.session; outgoingSession.on('connecting', function(data){ console.info('onConnecting - ', data.request); currentSession = outgoingSession; outgoingSession = null; }); } data.session.on('accepted', function(data){ console.info('onAccepted - ', data); if(data.originator == 'remote' && currentSession == null){ currentSession = incomingSession; incomingSession = null; console.info("setCurrentSession - ", currentSession); } }); data.session.on('confirmed', function(data){ console.info('onConfirmed - ', data); if(data.originator == 'remote' && currentSession == null){ currentSession = incomingSession; incomingSession = null; console.info("setCurrentSession - ", currentSession); } }); data.session.on('sdp', function(data){ console.info('onSDP, type - ', data.type, ' 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); } }); data.session.on('peerconnection', function(data){ console.info('onPeerconnection - ', data.peerconnection); data.peerconnection.onaddstream = function(ev){ console.info('onaddstream from remote - ', ev); youVideo.srcObject = ev.stream; document.body.addEventListener('click', function() { meVideo.play(); }); // wait until the video stream is ready var interval = setInterval(function(){ if(!meVideo.videoWidth){ return; } //stage.appendChild(videoView); clearInterval(interval); }, 1000 / 50); }; }); }); userAgent.on('newMessage', function(data){ if(data.originator == 'local'){ console.info('onNewMessage , OutgoingRequest - ', data.request); }else{ console.info('onNewMessage , IncomingRequest - ', data.request); } }); console.info("call register"); userAgent.start(); } // Register callbacks to desired call events var eventHandlers = { 'progress': function(e) { console.log('call is in progress'); }, 'failed': function(e) { console.log('call failed: ', e); alert('呼叫失败'); }, 'ended': function(e) { console.log('call ended : ', e); }, 'confirmed': function(e) { console.log('call confirmed'); } }; function testCall(){ var sip_phone_number = document.getElementById("sip_phone_number").value.toString(); var options = { 'eventHandlers' : eventHandlers, 'mediaConstraints' : constraints, 'mediaStream': null }; outgoingSession = userAgent.call(sip_phone_number, options); } </script> </html>
服务配置
由于WebRTC要求HTTPS服务,所以我们的页面不能直接访问,而是要通过放入服务中去运行。并且要使用与FreeSWITCH相同的证书(FreeSWITCH证书在其安装目录下的cert文件夹下的wss.pem)。可以参考KOA2 提供HTTPS安全服务效果图
由于此类文章不是很受欢迎,所以FreeSWITCH类文章截止此文章为止
如果使用默认密码,而且dailplan保留默认配置的话,会被路由走到一个拨号计划中,导致每次接通电话都需要等待10s ↩
相关文章推荐
- FreeSWITCH学习笔记 第二场 第一个镜头 JsSIP初识
- FreeSWITCH学习笔记 第一场 第二个镜头 视频通话配置
- FreeSWITCH学习笔记 第一场 第一个镜头 安装启动
- FreeSWITCH学习笔记 第一场 第五个镜头 添加新SIP用户
- FreeSWITCH学习笔记 第一场 第六个镜头 控制台与客户端(FS_Cli)
- FreeSWITCH学习笔记 第一场 第三个镜头 WSS配置
- FreeSWITCH学习笔记 第一场 第七个镜头 利用客户端(FS_Cli)执行呼叫
- FreeSWITCH学习笔记 第一场 第八个镜头 API和App
- FreeSWITCH学习笔记 第一场 第九个镜头 拨号计划(Dialplan)
- FreeSWITCH学习笔记 第一场 第四个镜头 局域网支持
- 【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头
- OpenCV学习笔记【2】:第二个程序--播放AVI视频
- Python爬虫框架Scrapy 学习笔记 4 ------- 第二个Scrapy项目
- 【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头
- The Definitive Guide To Django 2 学习笔记(二) 第二个View 动态内容
- Android编程权威指南(第二版)学习笔记(五)—— 第5章 第二个 Activity
- Freeswitch学习笔记 01
- 【深度学习】笔记4_caffe第二个比较经典的[小图片]识别例子CIFAR_10的运行,网络模型的详解
- 【NDN VANET】Rapid Traffic Information Dissemination Using Named Data 学习笔记
- Ubuntu学习笔记(一)