Freeswitch-unimrcp 发送请求时,MRCP协议SIP消息Contact头设置问题

文章描述了在NAT环境下的Freeswitch使用mod_unimrcp与ASR和TTS服务对接时遇到的问题,即发送MRCPSIP请求时Contact头未正确携带。解决方案是修改mrcp_profiles配置文件,添加或更新client-ext-ip选项,确保NAT后的IP地址被正确设置,从而修复通信问题。

Freeswitch-unimrcp 发送请求时Contact头设置问题

问题描述

在现网的智能IVR和CTI平台开发中,经常会使用到ASR和TTS的引擎,这时需要使用到Freeswitch自带的mod_unimrcp模块。但是最近出现了一个问题,我的Freeswitch在NAT之后(做了端口映射)需要与对方的ASR,TTS服务进行对接,但是一直不成功。经对方协查发现我们发送mrcp的sip请求时Contact头域未正常携带,此时针对这个问题进行了排查。

操作结论

修改freeswitch/conf/mrcp_profiles/文件夹下的配置文件,添加或修改client-ext-ip选项即可

<include>
  <!-- IFLYTEK InterReco 6.0 MRCPv2 -->
  <profile name="iflytek-asr-master" version="2">
    <param name="client-ext-ip" value="172.19.13.25"/>
    <param name="client-ip" value="172.19.13.25"/>
    <param name="client-port" value="3600"/>
    <!--<param name="server-ip" value="172.19.13.23"/>-->
    <!--<param name="server-port" value="5060"/>-->
    <!--param name="server-ip" value="172.19.13.21"/-->
    <!--param name="server-port" value="6050"/-->
    <param name="server-ip" value="172.19.13.26"/>
    <param name="server-port" value="5061"/>
    <!--param name="force-destination" value="1"/-->
    <param name="sip-transport" value="udp"/>
    <!--param name="ua-name" value="FreeSWITCH"/-->
    <!--param name="sdp-origin" value="FreeSWITCH"/-->
    <!--param name="rtp-ext-ip" value="auto"/-->
    <param name="rtp-ip" value="172.19.13.25"/>
    <param name="rtp-port-min" value="7001"/>
    <param name="rtp-port-max" value="10000"/>
    <!-- enable/disable rtcp support -->
    <param name="rtcp" value="1"/>
    <!-- rtcp bye policies (rtcp must be enabled first)
                      0 - disable rtcp bye
             1 - send rtcp bye at the end of session
             2 - send rtcp bye also at the end of each talkspurt (input)
    -->
    <param name="rtcp-bye" value="2"/>
    <!-- rtcp transmission interval in msec (set 0 to disable) -->
    <param name="rtcp-tx-interval" value="5000"/>
    <!-- period (timeout) to check for new rtcp messages in msec (set 0 to disable) -->
    <param name="rtcp-rx-resolution" value="1000"/>
    <!--param name="playout-delay" value="50"/-->
    <!--param name="max-playout-delay" value="200"/-->
    <!--param name="ptime" value="20"/-->
    <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="true"/>
       <param name="no-input-timeout" value="7000"/>
       <param name="kill-on-barge-in" value="true"/>
    </recogparams>
  </profile>
</include>

代码排查

1、在使用mod_unimrcp时,sofia如何构建的SIP消息,详见mrcp_sofiasip_client_agent.c 中的mrcp_sofia_config_validatefan方法

在这里插入图片描述
如上图标红处,sofia模块是使用config->ext_ip属性来构造contact_str

2、config->ext_ip的读取位置,详见mod_unimrcp.c文件的process_mrcpv2_config方法
在这里插入图片描述

<think>我们正在处理FreeSWITCH如何将SIP按键消息(DTMF)推送到unimrcpserver(MRCP服务器)以进行语音识别(ASR)或其他处理。 根据引用[3]提到:“Freeswitch 对接 unimrcpserver ASR调用”,并提到启动unimrcpserver和配置freeswitch。但具体如何推送按键消息(DTMF)并未详细说明。 实际上,DTMF可以通过多种方式传输,如RFC2833、SIP INFO或in-band(带内音频)。在MRCP协议中,通常使用RFC2833事件来传递DTMF。 在FreeSWITCH中,当我们使用unimrcp模块与unimrcpserver交互,通常用于语音识别(ASR)或语音合成(TTS)。而DTMF按键消息的处理,通常是在MRCP会话中通过DTMF事件传递的。 配置FreeSWITCH将DTMF传递给unimrcpserver,关键在于正确配置MRCP配置文件,确保DTMF事件能够被传递。 步骤: 1. 确保FreeSWITCH已加载mod_unimrcp模块(通过`show module`检查,如引用[3]所示)。 2. 配置unimrcp模块的配置文件(通常是unimrcp.conf),以便FreeSWITCH能够连接到unimrcpserver。 3. 在Dialplan中,当需要ASR,使用`detect_speech`应用(或类似应用)并指定MRCP识别器,这样在识别过程中,DTMF事件会被自动传递。 4. 如果需要在ASR过程中同检测DTMF并优先处理DTMF(例如,用户按了按键就中断ASR),则需要在Dialplan中配置DTMF检测与传递。 但是,用户特别提到“推送sip按键消息unimrcpserver”。在MRCP协议中,DTMF事件是作为输入事件传递的,因此当FreeSWITCHunimrcpserver建立MRCP会话,它会将收到的DTMF事件(RFC2833格式)转发给MRCP服务器。 具体配置方法: 首先,确保MRCP配置文件(如unimrcp.conf.xml)正确设置MRCP服务器的地址和端口,以及启用了DTMF事件传递。默认情况下,FreeSWITCHunimrcp模块应该已经配置为传递DTMF事件。 其次,在Dialplan中,我们需要配置一个扩展,当呼叫进入,启动MRCP语音识别,并在识别过程中监听DTMF。例如: ```xml <extension name="asr_with_dtmf"> <condition field="destination_number" expression="^1234$"> <action application="answer"/> <action application="detect_speech" data="unimrcp {start-input-timers=false}builtin:speech/asterisk?language=en-US,start"/> <action application="log" data="INFO Recognition result: ${detect_speech_result}"/> <!-- 其他处理 --> </condition> </extension> ``` 但是,上述配置主要用于语音识别,而DTMF事件会被自动传递给MRCP服务器,因为MRCP协议支持DTMF事件。如果用户按下按键,MRCP服务器会收到一个DTMF事件,并可以中断语音识别(如果配置如此)。 如果需要显式配置DTMF传递,可以在配置文件中设置。在unimrcp模块的配置中,通常有一个参数用于设置DTMF传输方式,默认可能是RFC2833。 由于引用中没有给出具体的配置文件,我们可以参考FreeSWITCH官方文档关于unimrcp的配置。 另外,引用[5]提到使用SIP的不同端口(5060和7443),但这与DTMF传递关系不大。 总结步骤: 1. 确认mod_unimrcp已加载。 2. 配置unimrcp.conf.xml(位于conf/autoload_configs/unimrcp.conf.xml)以指向正确的unimrcpserver。 3. 在Dialplan中调用`detect_speech`应用,这样在语音识别过程中,DTMF事件会被自动传递到MRCP服务器。 如果问题是如何在非语音识别场景下传递DTMF(例如,在IVR菜单中),那么通常不需要通过MRCP传递,而是由FreeSWITCH自己处理。但如果需要将按键传递给MRCP服务器(例如,用于控制语音识别的行为),那么就需要在MRCP会话中传递。 因此,用户的问题是“配置推送sip按键消息unimrcpserver”,这应该是在MRCP会话中自动完成的。所以,配置的关键是确保MRCP模块正确配置并启用,并且在需要进行语音识别启动MRCP会话。 如果用户希望在没有语音识别的情况下(例如,在普通的IVR菜单中)将按键传递给MRCP服务器,那通常是不必要的,因为MRCP服务器通常只处理语音识别或合成请求。不过,如果确实需要,可能需要自定义开发。 因此,我假设用户是在进行语音识别(ASR),希望DTMF按键能够被MRCP服务器接收并处理(比如打断识别)。那么,按照上述配置即可。 最后,关于unimrcp.conf.xml的配置示例(部分): ```xml <configuration name="unimrcp.conf" description="UniMRCP Client"> <settings> <!-- UniMRCP profile to use for TTS --> <param name="default-tts-profile" value="uni2"/> <!-- UniMRCP profile to use for ASR --> <param name="default-asr-profile" value="uni1"/> </settings> <profiles> <profile name="uni1" type="asr"> <!-- MRCP服务器地址 --> <param name="server-ip" value="127.0.0.1"/> <param name="server-port" value="8060"/> <param name="resource-location" value=""/> <param name="speechsynth" value="speechsynthesizer"/> <param name="speechrecog" value="speechrecognizer"/> <param name="rtp-port" value="4000"/> <!-- DTMF设置:传输方式为out-of-band(带外,即RFC2833事件) --> <param name="dtmf-type" value="application/dtmf-relay"/> </profile> </profiles> </configuration> ``` 注意:在profile中,dtmf-type参数可以设置为RFC2833的事件类型(如`application/dtmf-relay`)或者in-band(音频带内)。通常使用RFC2833事件。 所以,用户需要检查这个配置文件,确保DTMF类型正确,并且MRCP服务器支持该类型。 如果用户没有这个配置文件,可以从模版复制并修改。 总结:配置FreeSWITCH推送SIP按键消息(DTMF)到unimrcpserver,主要是通过配置unimrcp模块,并在MRCP会话中自动传递DTMF事件。具体操作步骤包括加载模块、配置unimrcp.conf.xml文件以及在Dialplan中启动语音识别应用。 </think>要配置FreeSWITCHSIP按键消息(DTMF)推送到UniMRCP服务器,需通过以下步骤实现: ### 配置步骤 1. **启用并配置`mod_unimrcp`模块** - 编辑`autoload_configs/unimrcp.conf.xml`: ```xml <configuration> <profiles> <profile name="uni1" type="asr"> <!-- 指定UniMRCP服务器地址 --> <param name="server-ip" value="127.0.0.1"/> <param name="server-port" value="8060"/> <!-- 启用DTMF事件传输 --> <param name="dtmf-type" value="application/dtmf-relay"/> </profile> </profiles> </configuration> ``` - 确保模块已加载:在FreeSWITCH CLI执行`load mod_unimrcp`[^3]。 2. **配置Dialplan处理DTMF** - 在`dialplan/default.xml`中添加扩展规则: ```xml <extension name="unimrcp_dtmf"> <condition field="destination_number" expression="^(\d+)$"> <!-- 将DTMF按键转发到UniMRCP --> <action application="send_dtmf" data="${destination_number}"/> <action application="unimrcp" data="detect"/> </condition> </extension> ``` 3. **配置SIP Profile支持RFC2833** - 在`sip_profiles/external.xml`中确保DTMF传输模式为RFC2833(带外传输): ```xml <param name="dtmf-type" value="rfc2833"/> <param name="inbound-dtmf-delay" value="50"/> ``` 4. **重启服务并测试** - 重启FreeSWITCH:`fs_cli -x "reloadxml"` - 测试方法:拨打配置的号码,按键盘数字键,在UniMRCP服务器日志中查看是否收到DTMF事件。 ### 关键说明 - **DTMF传输模式** :必须使用`rfc2833`(RFC2833事件包)而非带内音频,确保UniMRCP可靠解析[^5]。 - **UniMRCP兼容性**:需在UniMRCP配置文件`unimrcpserver.xml`中启用DTMF检测: ```xml <dtmf-recognition>true</dtmf-recognition> <dtmf-type>application/dtmf-relay</dtmf-type> ``` - **调试工具**:通过`tcpdump`抓包验证DTMF事件传输: ```bash tcpdump -i any -n udp port 8060 -vv ``` ### 常见问题排查 - **DTMF未传递**:检查`sip_profiles`中的`dtmf-type`是否为`rfc2833`,且UniMRCP端口无防火墙拦截。 - **模块未加载**:在FreeSWITCH CLI执行`show module`确认`mod_unimrcp`状态[^3]。 - **日志分析**:查看FreeSWITCH日志`freeswitch.log`过滤关键词`DTMF`和`unimrcp`。 通过以上配置,FreeSWITCH可将SIP按键事件实推送到UniMRCP服务器,实现ASR交互场景中的DTMF处理[^3][^5]。 --- ### 相关问题 1. **如何验证FreeSWITCHUniMRCP服务器的DTMF传输是否成功?** 2. **FreeSWITCH支持哪些DTMF传输协议?各自的优劣是什么?** 3. **在UniMRCP中如何处理接收到的DTMF事件?** 4. **如何配置FreeSWITCH在语音识别(ASR)过程中同支持DTMF中断?** [^1]: SIP配置文件示例 [^3]: UniMRCP服务器启动与模块加载 [^5]: DTMF传输协议与端口配置差异
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值