- 浏览: 1477841 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (691)
- linux (207)
- shell (33)
- java (42)
- 其他 (22)
- javascript (33)
- cloud (16)
- python (33)
- c (48)
- sql (12)
- 工具 (6)
- 缓存 (16)
- ubuntu (7)
- perl (3)
- lua (2)
- 超级有用 (2)
- 服务器 (2)
- mac (22)
- nginx (34)
- php (2)
- 内核 (2)
- gdb (13)
- ICTCLAS (2)
- mac android (0)
- unix (1)
- android (1)
- vim (1)
- epoll (1)
- ios (21)
- mysql (3)
- systemtap (1)
- 算法 (2)
- 汇编 (2)
- arm (3)
- 我的数据结构 (8)
- websocket (12)
- hadoop (5)
- thrift (2)
- hbase (1)
- graphviz (1)
- redis (1)
- raspberry (2)
- qemu (31)
- opencv (4)
- socket (1)
- opengl (1)
- ibeacons (1)
- emacs (6)
- openstack (24)
- docker (1)
- webrtc (11)
- angularjs (2)
- neutron (23)
- jslinux (18)
- 网络 (13)
- tap (9)
- tensorflow (8)
- nlu (4)
- asm.js (5)
- sip (3)
- xl2tp (5)
- conda (1)
- emscripten (6)
- ffmpeg (10)
- srt (1)
- wasm (5)
- bert (3)
- kaldi (4)
- 知识图谱 (1)
最新评论
-
wahahachuang8:
我喜欢代码简洁易读,服务稳定的推送服务,前段时间研究了一下go ...
websocket的helloworld -
q114687576:
http://www.blue-zero.com/WebSoc ...
websocket的helloworld -
zhaoyanzimm:
感谢您的分享,给我提供了很大的帮助,在使用过程中发现了一个问题 ...
nginx的helloworld模块的helloworld -
haoningabc:
leebyte 写道太NB了,期待早日用上Killinux!么 ...
qemu+emacs+gdb调试内核 -
leebyte:
太NB了,期待早日用上Killinux!
qemu+emacs+gdb调试内核
########
客户端mac用yate
ios用 adore sip client
############### asr
vim modules.con
asr_tts/mod_pocketsphinx
make mod_pocketsphinx-install
freeswitch/etc/freeswitch/autoload_configs/modules.conf.xml
<!-- ASR /TTS --> <load module="mod_flite"/> <load module="mod_pocketsphinx"/> <!-- <load module="mod_cepstral"/> --> <load module="mod_tts_commandline"/> <!-- <load module="mod_rss"/> -->
如果没有这个就要手工
load mod_flite
load mod_pocketsphinx
freeswitch/etc/freeswitch/dialplan/default.xml
<extension name="ASR"> <condition field="destination_number" expression="^1235$"> <action application="answer" /> <action application="set" data="tts_engine=flite" /> <action application="set" data="tts_voice=kal" /> <action application="play_and_detect_speech" data="say:'please say yes or no hahaha' detect:pocketsphinx yes_no"/> <action application="log" data="INFO ${detect_speeck_result}" /> </condition> </extension>
freeswitch/share/freeswitch/grammar/yes_no.gram
#JSGF V1.0; /** * JSGF Grammar for names */ grammar example; <yes> = [ yes ]; <no> = [ no ]; public <result> = [ <yes> | <no> ] ;
启动拨打1235
在log中查看freeswitch/var/log/freeswitch/freeswitch.log
e0266345-e1de-4f19-9352-88d52a92f028 2019-05-23 15:09:20.530197 [INFO] switch_ivr_async.c:4460 (sofia/internal/1006@192.168.0.100) START OF SPEECH 2019-05-23 15:09:21.750191 [DEBUG] mod_pocketsphinx.c:464 Recognized: no, Confidence: 100, Confidence-Threshold: 0 e0266345-e1de-4f19-9352-88d52a92f028 2019-05-23 15:09:21.770121 [INFO] switch_ivr_async.c:4450 (sofia/internal/1006@192.168.0.100) DETECTED SPEECH
识别出yes或no
#########中文asr识别###########
需要的中文 tdt_sc_8k在
git clone https://github.com/skerit/cmusphinx
cd cmusphinx-master/pocketsphinx/model/hmm/zh
把tdt_sc_8k放在
/usr/local/freeswitch/share/freeswitch/grammar/model
freeswitch/etc/freeswitch/autoload_configs/pocketsphinx.conf.xml
<param name="narrowband-model" value="tdt_sc_8k"/> <!--<param name="wideband-model" value="wsj1"/>--> <!--<param name="dictionary" value="default.dic"/>--> <param name="dictionary" value="zh_broadcastnews_utf8.dic"/>
需要字典
zh_broadcastnews_utf8.dic
参考
https://www.jianshu.com/p/f5d0b6bcea68
https://github.com/znstj/mrobot_speech
考到
freeswitch/share/freeswitch/grammar/zh_broadcastnews_utf8.dic
cp zh.gram /usr/local/freeswitch/share/freeswitch/grammar
#JSGF V1.0; /** * JSGF Grammar for names */ grammar names; <du> = 杜; <jin> = 金; <fang> = 房; <孙> = 孙; <中> = 中; <山> = 山; public <jf> = <jin><fang>; public <djf> = <du><jin><fang>; public <szs> = <孙> <中> <山>;
asr.lua 放到freeswitch/share/freeswitch/scripts
#########录音及播放
录音
originate user/1006 &record(/tmp/welcome.wav)
播放
originate user/1006 &playback(/tmp/welcome.wav)
#执行lua
把test.lua放入
/usr/local/freeswitch/share/freeswitch/scripts
originate user/1006 &lua(test.lua)
session:answer() session:sleep(1000) session:streamFile("/tmp/welcome.wav") session:hangup()
如果是在命令行直接执行lua
freeswitch@bogon> lua /tmp/api.lua
api = freeswitch.API() reply = api:execute("version", "") freeswitch.consoleLog("INFO", "Got reply:\n\n" .. reply .. "\n")
##########javascript脚本######
brew install v8
安装目录
vim modules.conf
打开mod_v8
make mod_v8-install
#################
##################
编译tts模块
需要在源码目录的modules.conf
打开注释
#asr_tts/mod_cepstral asr_tts/mod_flite #asr_tts/mod_pocketsphinx asr_tts/mod_tts_commandline asr_tts/mod_unimrcp
freeswitch安装完之后
make install
make mod_flite-install
进行安装
freeswitch的命令行
一定要load
load mod_flite
freeswitch>originate user/1005 &speak('flite|rms|Hello,welcome to freeswitch,haha,I am haoning')
freeswitch/etc/freeswitch/dialplan/default.xml加入
<extension name="TTS"> <condition field="destination_number" expression="1234"> <action application="answer" /> <action application="speak" data="flite|rms|Hello,welcome to freeswitch,haha,I am haoning"/> </condition> </extension>
拨打1234测试
################
编译目录
vim modules.conf
#asr_tts/mod_cepstral asr_tts/mod_flite #asr_tts/mod_pocketsphinx asr_tts/mod_tts_commandline
make mod_tts_commandline-install
autoload_configs/tts_commandline.conf.xml
<settings> <!--<param name="command" value="echo ${text} | text2wave -f ${rate} > ${file}"/>--> <param name="command" value="say -v ${voice} -o ${file}.aiff ${text}; sox ${file}.aiff ${file}; rm -f ${file}.aiff"/> </settings>
freeswitch/etc/freeswitch/dialplan/default.xml 修改
<extension name="TTS"> <condition field="destination_number" expression="^1234$"> <action application="answer" /> <action application="set" data="tts_engine=tts_commandline" /> <action application="set" data="tts_voice=Ting-Ting" /> <action application="speak" data="欢迎使用freeswitch,我是小美"/> </condition> </extension>
load mod_tts_commandline
拨打1234测试
如果想不load
freeswitch/etc/freeswitch/autoload_configs/modules.conf.xml
打开tts注释
###############
vim modules.conf
asr_tts/mod_unimrcp
make mod_unimrcp-install
########################
aws上的
centos7安装
https://freeswitch.org/confluence/display/FREESWITCH/CentOS+7+and+RHEL+7
yum install -y http://files.freeswitch.org/freeswitch-release-1-6.noarch.rpm epel-release yum install -y freeswitch-config-vanilla freeswitch-lang-* freeswitch-sounds-* tts: yum list|grep freeswitch yum install freeswitch-asrtts-flite yum install freeswitch-asrtts-tts-commandline asrtts-unimrcp -y systemctl enable freeswitch systemctl start freeswitch 客户端进入 fs_cli -rRS
可能会有https://files.freeswitch.org/yum-1.6/7server/x86_64/repodata/repomd.xml 找不到的问题
可能是7Server的问题,需要修改repo,把$releasever 改成 7server小写的
由于内ip和公网ip不一样,电话通了但是没声音
公网电话通了但是没声音:
https://blog.csdn.net/hry2015/article/details/78388839
/etc/freeswitch/sip_profiles/internal.xml <!--<param name="ext-rtp-ip" value="auto-nat"/>--> <param name="ext-rtp-ip" value="13.231.152.115"/> <!--<param name="ext-sip-ip" value="auto-nat"/>--> <param name="ext-sip-ip" value="13.231.152.115"/>
启用internal配置文件
vars.xml:
<X-PRE-PROCESS cmd="set" data="default_password=1234"/> <!--<X-PRE-PROCESS cmd="set" data="use_profile=external"/>--> <X-PRE-PROCESS cmd="set" data="use_profile=internal"/>
internal.xml中的accept-blind-reg与accept-blind-auth 均为true!这样可以做到自注册!
<domain name="all" alias="true" parse="true"/>
ios客户端用ador sip client
两个手机登录后,用户用1001和1005
查看用户
sofia status profile internal reg
###########################
jssip:
https://blog.csdn.net/foruok/article/details/74321214
#########################
mac安装
https://freeswitch.org/confluence/display/FREESWITCH/macOS+Manual+Installation
一定要安装libtool
brew install libtool
会有glibtool 和glibtoolize 生成
brew install autoconf automake curl jpeg ldns libsndfile libtiff libtool lua openssl opus pcre pkg-config speex speexdsp sqlite signalwire/homebrew-signalwire/flite signalwire/homebrew-signalwire/libks signalwire/homebrew-signalwire/signalwire-c
git clone https://freeswitch.org/stash/scm/fs/freeswitch.git ./bootstrap.sh ./configure --prefix=/usr/local/freeswitch make make install make sounds-install make moh-install make cd-sounds-install make cd-moh-install
lsof -i:5060
启动
freeswitch
另一个窗口打开客户端
fs_cli
关闭:
Shutdown
jssip:
https://www.bootcdn.cn/jssip/
#######################
首先介绍下什么是DID? 翻译为中文为“直接向内拨号”
https://blog.csdn.net/daitu3201/article/details/80031503
sofia status profile internal
sofia status profile internal reg
jssip
https://www.jianshu.com/p/813becfc6388
sipjs:
http://sipjs.com/download/
#############################
vars.xml:
<X-PRE-PROCESS cmd="set" data="default_password=1234"/>
<!--<X-PRE-PROCESS cmd="set" data="use_profile=external"/>-->
<X-PRE-PROCESS cmd="set" data="use_profile=internal"/>
注册新用户
https://blog.csdn.net/daitu3201/article/details/80031503
http://www.bubuko.com/infodetail-1443623.html
错误 :总提示“freeswitch You must define a domain called
internal.xml中的accept-blind-reg与accept-blind-auth 均为true!这样可以做到自注册!
<domain name="all" alias="true" parse="true"/>
/usr/local/freeswitchnew/etc/freeswitch/sip_profiles/external#
gw-DID.xml
<include> <gateway name="gw-DID"> <param name="realm" value="172.18.201.122"/> // sip provider 提供的服务器IP <param name="username" value="88888888"/>// sip provider 提供的DID账号 <param name="password" value="12345678"/> // sip provider 提供的DID账号密码 <param name="proxy" value="172.18.201.122"/> // sip provider 提供的服务器IP <param name="register" value="true"/> <param name="expire-seconds" value="600"/> <param name="ping" value="30"/> <param name="sip-trace" value="true"/> </gateway> </include>
配置拨码计划
呼入
在 /usr/local/freeswitchnew/etc/freeswitch/dialplan 中修改 public.xml,
或者在public目录下加
添加如下内容:
<extension name="sipprovider"> <condition field="destination_number" expression="^88888888$"> <action application="transfer" data="1008 XML default"/> </condition> </extension>
呼出:
/usr/local/freeswitchnew/etc/freeswitch/dialplan/default
添加call_out.xml
<include> <extension name="call out"> <condition field="destination_number" expression="^0(\d+)$"> <action application="bridge" data="sofia/gateway/gw-DID/$1"/> </condition> </extension> </include>
重启查看用户
sofia status profile internal reg
sofia status profile internal
originate sofia/gateway/gw-DID/88888888 &echo
originate sofia/gateway/gw-DID/88888888 &park
version
status
sofia status
sofia help
sofia status gateway gw-DID
show channes
show calls
#######
h5的客户端
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>sipjs-webphone</title> <script src="./js/sip-0.13.8.min.js"></script> <script> var config = { uri: '1000@172.18.201.122', displayName: 'tianyu', registrarServer: 'sip:172.18.201.122:5066', authorizationUser: '1000', password: '1234', transportOptions: { wsServers: ['ws://172.18.201.122:5066'], traceSip: true }, log: { level: "debug" }, register: true }; var ua = new SIP.UA(config); </script> </head> <body> </body> </html> sofia status profile internal reg 能看到的
<!DOCTYPE html> <html> <head> <title>JsSIP + WebRTC + freeSWITCH</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="Author" content="foruok" /> <meta name="description" content="JsSIP based example web application." /> <script src="js/jssip.min.js" type="text/javascript"></script> <style type="text/css"> </style> </head> <body> <div id="login-page" style="width: 424px; height: 260px; background-color: #f2f4f4; border: 1px solid grey; padding-top: 4px"> <table border="0" frame="void" width="418px"> <tr> <td class="td_label" width="160px" align="right"><label for="sip_uri">SIP URI:</label></td> <td width="258px"><input value="sip:1000@haoning.com:5066" style="width:250px" id="sip_uri" type="text" placeholder="SIP URI (i.e: sip:alice@example.com)"/></td> </tr> <tr> <td class="td_label" align="right"><label for="sip_password">SIP Password:</label></td> <td><input value="1234" style="width:250px" id="sip_password" type="password" placeholder="SIP password"/></td> </tr> <tr> <td class="td_label" align="right"><label for="ws_uri">WSS URI:</label></td> <td><input value="ws://172.18.201.122:5066" style="width:250px" id="ws_uri" class="last unset" type="text" placeholder="WSS URI (i.e: wss://example.com)"/></td> </tr> <tr> <td class="td_label" align="right"><label class="input_label" for="sip_phone_number">SIP Phone Info:</label></td> <td><input value="sip:1002@haoning.com:5066" style="width:250px" id="sip_phone_number" type="text" placeholder="sip:3000@192.168.40.96:5060"></td> </tr> <tr> <td colspan="2" align="center"><button onclick="testStart()"> Initialize </button></td> </tr> <tr> <td colspan="2" align="center"><button onclick="testCall()"> Call </button></td> </tr> <tr> <td colspan="2" align="center"><button onclick="captureLocalMedia()"> Capture Local Media</button></td> </tr> </table> </div> <div style="width: 424px; height: 324px;background-color: #333333; border: 2px solid blue; padding:0px; margin-top: 4px;"> <video id="videoView" width="420px" height="320px" autoplay ></video> </div> </body> <script type="text/javascript"> var outgoingSession = null; var incomingSession = null; var currentSession = null; var videoView = document.getElementById('videoView'); var constraints = { audio: true, video: true, mandatory: { maxWidth: 640, maxHeight: 360 } }; URL = window.URL || window.webkitURL; var localStream = null; var userAgent = null; function gotLocalMedia(stream) { console.info('Received local media stream'); localStream = stream; videoView.src = URL.createObjectURL(stream); } function captureLocalMedia() { console.info('Requesting local video & audio'); navigator.webkitGetUserMedia(constraints, gotLocalMedia, function(e){ alert('getUserMedia() error: ' + e.name); }); } 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); //console.warn("registrationFailed, ", data.response.status_code, ",", data.response.reason_phrase, " cause - ", data.cause); }); userAgent.on('registrationExpiring', function(){ console.warn("registrationExpiring"); }); userAgent.on('newRTCSession', function(data){ console.info('onNewRTCSession: ', data); if(data.originator == 'remote'){ //incoming call console.info("incomingSession, answer the call"); incomingSession = data.session; data.session.answer({'mediaConstraints' : { 'audio': true, 'video': true, mandatory: { maxWidth: 640, maxHeight: 360 } }, 'mediaStream': localStream}); }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); videoView.src = URL.createObjectURL(ev.stream); }; }); }); 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); }, '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' : { 'audio': true, 'video': true , mandatory: { maxWidth: 640, maxHeight: 360 } }, 'mediaStream': localStream }; //outgoingSession = userAgent.call('sip:3000@192.168.40.96:5060', options); outgoingSession = userAgent.call(sip_phone_number_, options); } </script> </html>
相关推荐
《FreeSWITCH 1.8》这本书是关于VoIP(Voice over Internet Protocol,互联网协议语音)和WebRTC技术的权威指南,专注于使用FreeSWITCH这一开源软件交换机实现这些技术。FreeSWITCH是一个模块化通信平台,支持多种...
《FreeSWITCH权威指南》是一本深度探讨FreeSWITCH开源电话软交换平台的专著,主要面向希望深入了解和使用FreeSWITCH技术的开发者和通信行业从业者。FreeSWITCH以其强大的功能、灵活的架构以及开放源代码的优势,在...
FreeSWITCH是一个开源的通信平台,它支持多种协议和接口,可以用于构建VoIP、视频会议、即时消息等多种通信系统。本简要使用教程V1.1是为那些想要了解和掌握FreeSWITCH操作的初学者或开发者准备的。通过这份文档,...
【Freeswitch集成科大讯飞及百度语音服务】是一个关于如何在Freeswitch系统中整合科大讯飞和百度的语音服务的技术文档。Freeswitch是一个开源的通信平台,常用于建立VoIP(Voice over Internet Protocol)系统,提供...
### CentOS安装FreeSWITCH过程实录 #### 一、安装依赖的第三方库 在开始部署FreeSWITCH之前,首先需要确保CentOS系统已安装了一系列必要的依赖库。这些库包括但不限于编译工具(如`gcc-c++`)、网络库(如`curl-...
**FreeSWITCH简介** FreeSWITCH是一个开源的、多平台的通信系统,它支持多种协议,包括SIP、H.323、Skype、XMPP等,旨在提供灵活的实时通信解决方案。作为一款强大的软交换平台,FreeSWITCH被广泛应用于VoIP、视频...
Freeswitch是一个开源的通信平台,它支持实时通信如VoIP、视频通话、会议和许多其他企业级通信功能。此“freeswitch中文语音包”是专为Freeswitch设计的,目的是为了使该系统能够支持中文语言环境,提供中文语音提示...
FreeSwitch 搭建软交换中心指导 本文档旨在指导读者如何搭建 FreeSwitch 软交换中心,并了解软交换的基本特点。实验环境为 CentOS 7,FreeSwitch 1.6。 一、实验目标 通过安装 FreeSwitch,实际体验交换机在通信...
《Freeswitch权威指南》是一本深度探讨Freeswitch开源通信平台的专业书籍,结合C和C++源码,为读者提供了全面且深入的学习资源。Freeswitch是一个强大的、开源的、多线程的VoIP(Voice over Internet Protocol)...
FreeSwitch 是一个开源的通信平台,它支持多种通信协议,如SIP、Skype for Business (formerly Lync)、WebRTC等,广泛应用于VoIP(Voice over IP)系统。中文语音包是为FreeSwitch设计的,目的是为了提供中文语言...
OpenSips与FreeSWITCH集群搭建是一个复杂的任务,涉及到多个组件的集成和配置。OpenSips是一个开源的SIP服务器,它用作VoIP网络中的会话初始化协议(SIP)路由器,提供负载均衡、会话管理等功能。而FreeSWITCH是一个...
《freeswitch的GB28181模块详解与应用》 在信息技术高速发展的今天,视频监控系统已经广泛应用于各种场所,确保公共安全和个人隐私。其中,GB28181作为中国国家标准,规范了基于IP网络的视频监控系统的互通性,而...
在本文中,我们将深入探讨Freeswitch的呼入呼出路由配置,这是一个关键的环节,对于任何使用Freeswitch作为其VoIP通信基础架构的组织来说都至关重要。Freeswitch是一个开源的通信平台,它支持多种协议,如SIP、TLS、...
Freeswitch是一款强大的开源通信平台,它支持多种协议,包括SIP、TLS、WebSocket等,可用于构建VoIP、视频会议、即时消息等多种通信系统。在Windows环境下,Freeswitch提供了客户端和服务器端的打包版本,使得用户...
**Freeswitch ESL控制方式详解** Freeswitch是一款开源、多平台的VoIP通信系统,它支持多种协议和控制方式,其中包括XML配置和Event Socket Library(ESL)API。本资源主要关注的是通过ESL进行控制的方式,这是一种...
FreeSwitch配置和使用手册 1. FreeSwitch 简介 FreeSwitch是一个强大的开源通信平台,设计用于处理各种媒体通信,包括语音、视频和文本。它不仅能够作为个人软电话客户端,还可以作为企业级PBX(Private Branch ...
FreeSWITCH 1.8 manual, a very comprehensive introduction, English text version , PDF file . 最新版 高清晰 文本电子版: FreeSWITCH-1.8使用手册, 介绍的很全面,英文版本
《freeswitch 1.6 Cookbook》是一本专注于FreeSWITCH 1.6版本的实践指南,旨在帮助读者深入理解和掌握这一开源通信平台的各个方面。FreeSWITCH是一个强大的、多线程、多平台的软交换系统,广泛应用于VoIP、视频会议...