如何实现一个voip录音系统
来源:互联网 发布:知乎如果庄子诸葛亮 编辑:程序博客网 时间:2024/05/17 09:46
这里讨论的voip录音系统,是在网络交换机上设置端口镜像,将所有坐席(如ip话机)的端口数据镜像到指定端口,录音系统接到该端口,抓取端口上所有的数据包。
市场上做voip录音的厂家,有些是硬件如板卡,有些是纯软件,他们的产品存在下列缺点:
1、很贵;
2、会丢失录音,原因一是处理能力不够,二是程序不稳定;
3、界面或接口复杂,有的还需要调用CTI接口。
我花了几天思考了一下,并用一周的时间实现了它,设计目标如下:
1、高性能:
支持1000线以上的并发录音。
2、简单、自成体系:
系统对sip消息也进行了处理,分析创建会话和结束会话的消息,并从消息中抽取主叫号码、被叫号码等信息。
支持UDP或TCP传输的sip协议。
不支持H323等过时的协议,原因一是此类协议很复杂,二是原先使用h323协议的厂商产品如Avaya,很容易配置成SIP 。
系统可将会话记录写到数据库表,包括主、被叫号码,开始时间,通话时长,录音文件名等信息,供外部应用进行查询匹配。
(因为主叫或被叫,总有一方对应坐席分机,匹配和查询统计是很容易的)
通过数据库,可以很容易和第三方应用集成。
3、稳定:
可长时间稳定运行,不会丢失录音,也不会丢包。
4、支持多种音频编解码:
包括:g711a、g711u,g729ab,gsm,g723,iLbc等多种编码。
实现的要点:
1、抓包采用wincaplib,抓取tcp和udp,抓取后做快速判断,比如判断是否为sip的应答、建立会话200 OK消息,或是sip的bye消息,或是rtp包,如是上述三类包,则放入到缓冲区;
2、线程池去处理缓冲区,如sip处理的从缓冲区读取消息来生成会话和创建录音文件,或者关闭会话关闭录音。
高效率的要点是读写必须无锁,每个线程上的缓冲区为环形队列。
3、rtp包的处理:根据源或目标地址和端口,到会话队列中去匹配会话,此时需要对队列进行加锁。
我参考数据库思想设计了两种锁,读锁和写锁,多个线程同时可以读,但读锁和写锁之间互斥。
sip消息处理线程在创建会话或拆除会话时,使用写锁;
rtp包处理线程在定位会话时,使用读锁。
这是巧妙的设计,因为录音系统大部分时间在处理rtp包,采用读锁机制既保证了线程安全,又大大地提高了效率。
4、媒体处理:
每个会话的两个方向的rtp包收到后要进入缓冲区去抖动,并解码成线性pcm数据,录音合成线程(是个线程池)会以20ms的间隔去合成两个方向的pcm数据并延迟写入录音文件。延迟写入可以提高磁盘io的效率。
媒体处理使用了蓝星际自行开发并长期使用的库:LxjMediaApi.dll,这个库经过升级后可以支持外部数据源。
特别地,蓝星际媒体库对g729的处理十分高效,因为我们采用了Intel的IPP库,是业界公认性能最佳的g729编解码器。
欢迎和我讨论,或索取试用程序。
bluesen@sina.com
- 如何实现一个voip录音系统
- 利用FMS实现的在线录音系统。
- EasyDial 录音系统
- VOIP如何保持后台监听
- VOIP IPsec VPN 架构实现
- VOIP实现原理及关键技术
- VOIP
- voip
- VOIP
- VOIP
- voip
- VOIP
- VOIP
- VOIP
- VOIP
- QCR录音系统使用说明
- 如何实现一个BTE
- 如何实现一个文件系统
- JavaStuNote 4
- UITextField、UILabel和 UITextView四个容易混淆的属性
- 小桐学设计模式--模版方法(TEMPLATE METHOD)
- CGContextRef使用详解
- [LeetCode][Java] Subsets
- 如何实现一个voip录音系统
- java.sql.SQLException: Could not retrieve transation read-only status server
- oracle 删除掉重复数据只保留一条 .
- hdu 3152 Obstacle Course
- android 升级sdk后,adt问题
- ubuntu Qt连接MySQL
- VS2013控制台生成.exe运行闪退的解决
- 7月18日Java基础:本人为新手正在学习Java中把每天学的东西晚上都会在博客记录希望大神可以指点 不足在此谢过。
- 【并发编程】JMM:java内存模型抽象