mod_unimrcp 安装
加载非默认模块的方法:
- 编辑freeswitch/modules.conf文件,找到要安装的模块,去掉前面的注释符号#。
- 在命令行执行make mod_xxx-install命令,这样就编译相应模块,并把编译后的动态库安装的/usr/local/freeswitch/mod目录下了。
- 如果想启动freeswitch的时候就自动加载,修改/usr/local/freeswitch/conf/autoload_configs/modules.conf.xml,去掉注释符号就可以了。
按照上面步骤安装 mod_unimrcp 即可。
mrcp_profiles/unimrcpserver-mrcp-v2.xml
在mrcp_profiles
目录新建unimrcpserver-mrcp-v2.xml
配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <include> <!-- UniMRCP Server MRCPv2 --> <!-- 后面我们使用该配置文件,均使用 name 作为唯一标识,而不是文件名 --> <profile name="unimrcpserver-mrcp2" version="2"> <!-- MRCP 服务器地址 --> <param name="server-ip" value="192.168.2.244"/> <!-- MRCP SIP 端口号 --> <param name="server-port" value="7010"/> <param name="resource-location" value=""/> <!-- FreeSWITCH IP、端口以及 SIP 传输方式 --> <param name="client-ip" value="192.168.1.153" /> <param name="client-port" value="5069"/> <param name="sip-transport" value="udp"/> <param name="speechsynth" value="speechsynthesizer"/> <param name="speechrecog" value="speechrecognizer"/> <!--param name="rtp-ext-ip" value="auto"/--> <param name="rtp-ip" value="192.168.1.153"/> <param name="rtp-port-min" value="4000"/> <param name="rtp-port-max" value="5000"/> <param name="codecs" value="PCMU PCMA L16/96/8000"/> <!-- Add any default MRCP params for SPEAK requests here --> <synthparams> </synthparams> <!-- Add any default MRCP params for RECOGNIZE requests here --> <recogparams> <!--param name="start-input-timers" value="false"/--> </recogparams> </profile> </include> |
autoload_configs/unimrcp.conf.xml
看目录名也大概能猜到,这里面的配置是 FreeSWITCH 运行后自动加载的。
修改unimrcp.conf.xml
,将”default-tts-profile”、”default-asr-profile”修改为我们上面配置的”unimrcpserver-mrcp2”(注意是 name 值而不是文件名),这样我们后面使用的时候可以不指定配置名直接使用默认配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <configuration name="unimrcp.conf" description="UniMRCP Client"> <settings> <!-- UniMRCP profile to use for TTS --> <param name="default-tts-profile" value="unimrcpserver-mrcp2"/> <!-- UniMRCP profile to use for ASR --> <param name="default-asr-profile" value="unimrcpserver-mrcp2"/> <!-- UniMRCP logging level to appear in freeswitch.log. Options are: EMERGENCY|ALERT|CRITICAL|ERROR|WARNING|NOTICE|INFO|DEBUG --> <param name="log-level" value="DEBUG"/> <!-- Enable events for profile creation, open, and close --> <param name="enable-profile-events" value="false"/> <param name="max-connection-count" value="100"/> <param name="offer-new-connection" value="1"/> <param name="request-timeout" value="3000"/> </settings> <profiles> <X-PRE-PROCESS cmd="include" data="../mrcp_profiles/*.xml"/> </profiles> </configuration> |
IVR 配置
查看默认配置conf/dialplan/default.xml
我们可以看到如下配置,这就是默认的 5000 配置:
1 2 3 4 5 6 7 8 | <!-- a sample IVR --> <extension name="ivr_demo"> <condition field="destination_number" expression="^5000$"> <action application="answer"/> <action application="sleep" data="2000"/> <action application="ivr" data="demo_ivr"/> </condition> </extension> |
新增 IVR 配置
在conf/dialplan/default.xml
里新增如下配置:
1 2 3 4 5 6 | <extension name="unimrcp"> <condition field="destination_number" expression="^5001$"> <action application="answer"/> <action application="lua" data="names.lua"/> </condition> </extension> |
跟 5000 配置不同的是,我们使用了 lua 脚本,当拨打 5001 时,FreeSWITCH 将会回调 names.lua 脚本。
智能 IVR 脚本
在scripts
目录下新增names.lua
脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | session:answer() --freeswitch.consoleLog("INFO", "Called extension is '".. argv[1]"'\n") welcome = "ivr/ivr-welcome_to_freeswitch.wav" menu = "ivr/ivr-this_ivr_will_let_you_test_features.wav" -- grammar = "hello" no_input_timeout = 80000 recognition_timeout = 80000 confidence_threshold = 0.2 -- session:streamFile(welcome) --freeswitch.consoleLog("INFO", "Prompt file is \n") tryagain = 1 while (tryagain == 1) do -- session:execute("play_and_detect_speech",menu .. "detect:unimrcp {start-input-timers=false,no-input-timeout=" .. no_input_timeout .. ",recognition-timeout=" .. recognition_timeout .. "}" .. grammar) xml = session:getVariable('detect_speech_result') -- if (xml == nil) then freeswitch.consoleLog("CRIT","Result is 'nil'\n") tryagain = 0 else freeswitch.consoleLog("CRIT","Result is '" .. xml .. "'\n") tryagain = 0 end end -- -- put logic to forward call here -- session:sleep(250) session:set_tts_parms("unimrcp", "xiaofang"); session:speak("今天天气不错啊"); session:hangup() |
同时我们需要在grammar
目录新增hello.gram
语法文件,可以为空语法文件须满足语音识别语法规范1.0标准(简称SRGS1.0),该语法文件 ASR 引擎在进行识别时可以使用。如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <?xml version="1.0" encoding="utf-8" ?> <grammar version="1.0" xml:lang="zh-cn" root="Menu" tag-format="semantics/1.0" xmlns=http://www.w3.org/2001/06/grammar xmlns:sapi="http://schemas.microsoft.com/Speech/2002/06/SRGSExtensions"><!- 这些都是必不可少的--> <rule id="city" scope="public"> <one-of> <!-- 匹配其中一个短语--> <item>北京</item> <item>上海</item> </one-of> </rule> <rule id="cross" scope="public"> <one-of> <item>到</item> <item>至</item> <item>飞往</item> </one-of> </rule> <rule id="Menu" scope="public"> <item> <ruleref uri="#date"/> <!--指定关联的其他规则的节点--> <tag>out.date = reles.latest();</tag> </item> <item repeat="0-1">从</item> <!--显示1次或0次--> <item> <ruleref uri="#city"/> <tag>out.city = rulels.latest();</tag> </item> <item> <ruleref uri="#cross"/> <tag>out.cross = rulels.latest();</tag> </item> <item> <ruleref uri="#city"/> <tag>out.city = rulels.latest();</tag> </item> </rule> </grammar> |
脚本中,我们使用 unimrcp 默认配置,”play_and_detect_speech” 调用了 ASR 服务,”speak” 调用了 TTS 服务。你可以在循环中,尝试分析解析到的语句,根据内容进行导航、反馈。
最终测试
SIP 客户端登陆后拨打 5001 分机,就可以听到我们配置的导航内容了。
最后
本文只是对 FreeSWITCH 的最简单的使用,FreeSWITCH 是一个很强大的系统,若要完全掌握需要花费更多的精力去学习它的架构、配置。而我使用 FreeSWITCH 目前只是为了方便调试自己编写的 UniMRCP Plugin,后面我将通过整合科大讯飞提供的ASR、TTS服务,整理一下 UniMRCP Plugin 的实现。