转:https://rtcdeveloper.com/t/topic/16586
1、基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway 方案和思路
2、基于声网的音视频SDK和FreeSWITCH开发WebRTC2SIP Gateway报文设计
今年初接到一个项目任务,客户要求在自己的音视频平台系统中集成webrtc功能(原系统是基于SIP协议开发的,已经稳定运行多年,已有一定数量的存量客户)。在对比多家RTC产品的效果后,客户对声网音视频DEMO效果后非常满意,指定要求用声网的SD-RTN传输网络,全面改造客户端软件,改善音频通话质量。据客户实测,在某些国家和地区,同样网络环境下比微信的音频通话质量要好很多,比如在东非和中国之间语音通话,延迟很小、声音也更清晰。
目前系统已经上线运行了几个月没出过问题,通话质量也非常好,满足了客户的预期目标。公司要求总结开发阶段中碰到的问题,声网的小伙伴也说,我们公司的策略是培养ISV,把你们培养起来,做出解决方案,然后也希望能回馈一下社区,形成一个良性互动及不断加强一下社区浓厚的学习交流氛围。有感于这一段时间的开发工作,于是写下这篇文章,__我们会在这篇帖子中定期更新,分享开发思路、方案、遇到的问题、解决方法,希望能对大家有所帮助。__我会敲代码,不太会表达,如果大家在实现这个模块的过程中也碰到类似的问题,想了解一些细节,欢迎联系回帖提问或者邮箱交流(交流邮箱地址:[email protected]),咱们尽量答复大家。
一路走来,几个同事经常分析代码到半夜。终于在测试4个月后稳定下来。其实现在回头看,就是因为没有吃透声网的API文档,没有好好利用社区的功能。如果你碰到的坑是跟咱们的类似,那么花点时间仔细撸几遍API文档就可以搞掂了。
1、全面改造Android、iOS、Windows、MacOS、Web版5个平台的客户端软件,原来的客户端分别是基于Pjsip、Linphone、Sipjs开发的;
2、要求在网络环境差的地方,也能满足清晰语音通话的要求(声网的音视频实时传输网提供支持);
3、最小侵入性,尽量不改变服务器端的系统功能,实现客户无感升级;
4、解决SIP协议常碰到的丢包、被过滤UDP、无法呼叫和呼叫听不清等问题;
5、解决SIP服务器经常被尝试攻击呼叫、恶意扫描注册攻击等行为,提高系统稳定性;
6、实现WebRTC协议和SIP协议的双向互通,既要兼容SIP呼叫,又支持RTC客户端送呼叫到SIP Server,也要支持SIP Server呼入到客户端软件(在声网的音视频实时传输网传输)。.
其实刚接到需求的时候,大家一起讨论分析过:这种项目看着有不少预算,但是要做全平台客户端,开发任务繁重,要考虑的细节也比较多,没准是个坑,能否达到客户的期望要打一个问号,因此多数同事建议不做。然后在领导和客户一起去happy一晚后,这活儿不知道怎么就接下来了。
老板理由很简单,这也不做那也不做,那我们可以做什么?如果谁都能做,客户还会找我们吗?那就干吧,马上行动,各种查资料,翻阅声网的技术开发文档,并咨询声网的技术同学,2天后拿出初步方案。
系统架构图 fsgui.com webrtc2sip.com
1、自己写信令模块,保持灵活性,简单实现。开发TCP Server承担信令服务器;
2、核心是开发一个SIP2WebRTC/WebRTC2SIP协议转换网关,维护一个状态机;
3、开发音视频编解码处理器,解决声网语音和SIP语音编码互通;
4、开发一个状态管理模块,SessionManger,以维护客户端的状态IP和端口;
5、结合声网的音视频SDK,集成自己的信令模块,实现和WebRTC2SIP 模块通讯;
6、自定义常见的SIP呼叫信令,供各平台客户端保持一致。
常用的SIP 信令有:1注册、2呼叫、3接听、4挂断、5拒接、6取消、7Hold、8DTMF、9用户未反映、10用户离线、11Transfer、12会议(我会简单介绍前面的6个)。
PS:我们暂且把这个系统命名为 WebRTC2SIP Connector 或者SIP2WebRTC Connector吧。至于为什么这么叫,我也不知道,可能叫XX Gateway的太多了,不这么叫显不出声网的SD-RTN有多厉害,我是他爹,想叫什么都可以,哈哈
以哪个平台的SDK为基础开发WebRTC2SIP Connector核心模块?
Agora SDK是否支持多并发呼叫?
声网的语音编码格式和视频编码格式是什么?采样率多少?
SIP客户侧有没有什么具体的编码要求?客户可接受固定一个语音编码,我选择PCMA
这里特别感谢一下声网,对我们这种小众需求做出了快速响应,也感谢声网技术支持同学Nemo,专门来到公司交流了几个小时,并分享了一些技术信息,点一个大大的赞声网建议我们:
用Agora Windows SDK 或者 Linux SDK 开发协议转换模块;
2个SDK都支持多并发呼叫;
语音是pcm格式,视频是yuv格式,采样率是48khz;
1、各客户端SDK启动时,发起TCP连接,登录TCP Server信令服务器, WebRTC2SIP转接模块初始化也发起TCP连接登录TCP Server ,由TCP Server记录UID,IP和端口等信息。
2、呼叫的具体流程大概是这样的:
(1)呼叫的时候,申请一个房间号,并根据自定义信令格式发起calling 报文,TCP Server收到后,转发给转接模块WebRTC2SIP ;
(2)WebRTC2SIP收到后创建1个线程,解析报文,并启动声网的SDK,加入指定房间号;
(3)开始读取音频流程,同时启动线程,封装SIP标准报文,发起sip invite请求给电话服务器SIP Server;
(4)SIP Server收到呼叫请求就去呼叫被叫电话号码,并返回ring振铃信号。
(5)WebRTC2SIP收到振铃信号,封装自定义的振铃信息给客户端SDK;
(6)被叫接听后,WebRTC2SIP,启动Media Coder开始解析媒体流,并resample 后,写入到声网的房间里面。实现语音通话。
3、从SIP呼入到声网的SDK,大同小异,反过来就行。
1、每个终端都要自定义编号;
2、每个呼叫都要加入声网的房间channel 实现音视频互通;
3、因为编码不一样,所以需要resample,这个很重要,不然接通了没有声音,双方不匹配。
4、WebRTC2SIP模块要多线程方式处理,以实现并发呼叫;
5、WebRTC2SIP模块要维护一个完整的状态机,给每个通话加唯一编号,避免出错。
到现在我们讲清楚了大概的解决方案和技术思路,看到这里,各位客官应该明白了,其实这个做起来没啥难度,至少现在看来是这样的。
上一篇我们提到,常用的SIP 信令有:1注册、2振铃、3呼叫、4接听、5挂断、6取消
有了这几个报文,电话的呼入和呼出就可以基本实现,其他拒接、DTMF等类似。
如图所示:
必传参数:msgtag 是消息唯一标志,userid是谁触发的,appid 作为一个应用的标记。sign 签名加密 (看情况)
errcode=1 说明有错误 errmsg就会有值 ,如果errcode=0 说明返回结果正确一般是返回的msgtag 是请求的msgtag+”_res”做为区分
roomID 是房间号,对应声网的渠道号channel ID,每个通话报文必须包括roomID 用途是什么自己想。
callType 是video \ audio前者代表视频呼叫,后者代表语音呼叫
direction 呼叫方向in呼入 (SIP Server 把呼叫送到声网的SDK)out呼出(声网的SDK把呼叫送到SIP Server)
isSIP YES / NO代表这通呼叫是内部呼叫(声网客户端实现) 还是SIP呼叫(走落地)
这篇文章我只是简单列出核心的报文DEMO格式。
不论客户端还是WebRTC2SIP Connector本质上都是声网的音视频SDK客户端,然后集成了自定义的信令报文,所以在初始化时,需要调用一个专门的的接口(暂时叫做initSIP),调用这个接口时传递type类型参数。
(1)如果是手机端或者电脑端、网页端调用,返回TCP Server地址和端口,供他们建立TCP连接。
(2)如果是Connector转接服务器请求,除了返回TCP Server地址和端口外,还要返回SIP Serve地址及端口和呼叫送号前缀。不然SDK发起电话呼叫时,Connector不知道电话要转送到哪里。这个开发一个http接口就可以实现。
APP初始化,调用initSIP接口,建立TCP连接,或者呼叫的时候在建立TCP连接;
TCP Server维持所有终端的状态及网络位置做Session Manager角色;
主叫输入的号码编辑封装calling报文,通过tcp socket发给服务器,同时UI呈现拨号等待页面;
被叫收到calling报文,就封装ringing报文,通过tcp socket 发给服务器,服务器查询Session Manager查询主被叫的IP和端口,实现消息的路由转发,主叫收到就显示振铃页面。同时WebRTC2SIP Connector启动Media coder线程去解析和resample读取到的音频流。就这样一个个的报文交互串起来,就可以实现整个SIP呼叫逻辑。有兴趣的同学,快去试试吧。