• FreeSWITCH mrcp-v2小记


    最近得知有人受mrcp的困扰,于是写了这篇小文,希望能有所帮助

    • FreeSWITCH版本选择

    目前当然选择1.10.10,不建议老版本,差别在于老版本用到的libmrcp比较旧,是1.2版本,bug比较多,有时会crash,而FreeSWITCH1.10.10用libmcrp1.6,要稳定很多

    • 编译

    编译不在本文的讨论范围,可能有点小麻烦,但可以解决

    • 配置

    可以找到FreeSWITCH1.10.6版本的vanilla配置,复制过来,可以这样做(以ali为例):

    1. modules.conf.xml里面增加
    2. unimrcp.conf.xml里面 
    3. mrcp_profiles目前下的文件只保留nuance-5.0-mrcp-v2.xml,其它的文件可以删除
    4. nuance-5.0-mrcp-v2.xml改名为ali.xml
    5. ali.xml里面, name改为ali,server-ip和server-port指向sdm的sip地址和sip端口
    • 测试路由
    1. <action application="answer" data="">
    2. <action application="set" data="playback_delimiter=!">
    3. <action application="set" data="tts_engine=unimrcp">
    4. <action application="set" data="tts_voice=xiaoyan">
    5. <action application="playback" data="say:'欢迎使用tts测试系统'!welcome.wav">
    1. <action application="answer" data="">
    2. <action application="speak" data="unimrcp|xiaoyan|欢迎使用tts测试系统">

    本文没有提供asr例子,可以去别的地方去找

    我觉得tts参数比较少,比较容易调试。先搞定tts, asr就不难了

    • 调试

    调试的主要方法是看日志和抓包,从sip invite开始看,里面一般是二个media,其中一个当然是rtp(关注c地址),另外一个就是mrcp(关注地址和mrcp端口)

    • 常见问题

    1.ali和tengxun如何并存?

    同时放二个文件:ali.xml和tengxun.xml,当然,profile 名称不能一样,client-port不能一样

    在应用层,tts_engine设置为unimrcp:ali或者设置为unimrcp:tengxun,这样就可以区别开了

    2.tts和asr能不能分开,比如用ali asr,用tengxun的tts?

    当然可以,so easy!

    3.听不到tts,抓包发现tts server没有发rtp流过来,但sip流程正常

    看fs的c地址是不是127.0.0.1,如果是,那么client-ip和rtp-ip不能配成auto(让fs自动找),要修改成$${local_ip_v4},或者写死,比如192.168.1.100(本机ipv4)。此外,如果有nat,那么client-ext-ip和rtp-ext-ip可能需要设置下。抓包能定位到这些问题(有兴趣的可以研究下mod_unimrcp.c)

    3.1001 bridge 1002,需要同时识别,要怎么做

    重点是2条腿都需要execute 'detect_speech'先启动,不能execute 'play_and_detect_speech',后者不能返回

    在收到pause之后,execute 'detect_speech resume' 继续识别

    下面给出启动时的lua代码:

    1. function debug(s)
    2. session:consoleLog("DEBUG", (s or "(NULL)") .. "\n")
    3. end
    4. debug("start-asr entry")
    5. -- session:execute("info")
    6. debug("caller = " .. session:getVariable("caller_id_number") .. " callee = " .. session:getVariable("destination_number"))
    7. session:setVariable("fire_asr_events", "true")
    8. -- 开始识别
    9. session:execute("detect_speech", "unimrcp {start-input-timers=true,Speech-Complete-Timeout=10000,no-input-timeout=3000,recognition-timeout=60000}builtin:grammar/boolean?language=zh-CN;y=1;n=2 builtin")
    10. -- session:execute("detect_speech", "param start-input-timers true")
    11. -- session:execute("detect_speech", "param Recognition-Mode continuous")
    12. debug("start-asr exit")

    uuid_broadcast可以执行application,对esl程序可能有用(本人不会esl,好惭愧)

    • 其它

    sdm支持连续的语音识别,但mrcp不支持,或许以后可以修改源码来支持这个特性

    dtmf mrcp支持,但sdm不支持,lua可以设置回调,可能可以解决识别的过程中收码的问题

    1. function my_cb(s, type, obj, arg)
    2. -- ...
    3. end
    4. blah = "w00t"
    5. session:setInputCallback("my_cb", "blah")
    6. session:execute("play_and_detect_speech",...
    7. -- ...

    本文完全是凭记忆写成的,或许以后可以适当补充日志。

    • 来一个特别的:
    speak(unimrcp:alitts||{voice=aixia,Prosody-Volume=50, prosody-rate=0,pitch_rate=0}请问你需要什么服务)
    • 不想播放语音,只识别
    1. play_and_detect_speech silence_stream://1 unimrcp grammar
    2. # 还是得播放,但是静音1毫秒而已
  • 相关阅读:
    Linux服务器查看CPU相关信息
    半年销售100万辆 关注比亚迪后300万时代
    【数据结构与算法】四、链表相关算法题
    新型智慧公厕建设:引领公厕行业的未来!
    删除GitLab中的仓库
    Linux运维-Web服务器的配置与管理(Apache+tomcat)(没成功,最后有失败经验)
    缓冲流(字节缓冲流、字符缓冲流)----Java
    SpringBoot SpringBoot 基础篇(第一篇) 第2章 SpringBoot 全局配置 2.2 yaml 文件
    蓝牙运动耳机哪个好、六款最热门的运动耳机推荐
    apifox测试java中接收json格式
  • 原文地址:https://blog.csdn.net/qq_56167818/article/details/134159345