feifeiyechuan 2022-08-17 11:05 采纳率: 0%
浏览 428
已结题

关于#语音识别#的问题:Freeswitch-mod_unimrcp音频打断问题

在Freeswitch中,播放录音使用的是playback,语音识别使用的是

play_and_detect_speech  detect:unimrcp {start-input-timers=false,no-input-timeout=80000,recognition-timeout=80000} hello

那么如何控制在语音识别结果出来的时候,停止音频播放;未识别出语音识别结果的时候,音频继续播放

  • 写回答

16条回答 默认 最新

  • 来灵 2022-08-17 12:47
    关注

    调用函数play_and_detect_speech后,判断语音识别是否出来了,然后分别进行不同的处理。

    评论
  • kakaccys 2022-08-17 12:51
    关注

    改动最小最简单的方法:
    打开mod_unimrcp.c 找到这个函数,只需要添加一句代码,这是最简单的代码方式就能使这个app play_and_detect_speech 变得好用起来,你甚至不用去改fs的核心代码,也不用去重新编译fs,只需要重新编译mod_unimrcp.c就行

    img

    更简单更安全的方法:
    不让unimrcpserver发送 start of input 事件,同样可以使这个app好用起来
    这个只需要编译unimrcpserver里面的插件就行

    img

    因为这样做都是让fs可以忽略了 mrcp 的 start of input 事件,改为收到结果再打断。

    评论
  • 不会写代码的猴子 Android领域优质创作者 2022-08-17 13:15
    关注
    评论
  • De-Chang Wang 2022-08-19 19:16
    关注

    你调用的这个接口可能是将播放和识别捆绑在一起的,要想单独控制的话,最好就播放和识别分开调用

    评论
  • 渔戈 2022-08-20 10:06
    关注
    评论
  • Silver Star 大数据领域新星创作者 2022-08-22 07:25
    关注

    加控制语句

    评论
  • 半卷书生 2022-08-22 11:19
    关注

    playback_terminators=123456789*0# | any | none

    评论
  • smartisong 2022-08-22 18:56
    关注

    你的你目的是:控制在语音识别结果出来的时候,停止音频播放;未识别出语音识别结果的时候,音频继续播放。
    音频播放应该是一个函数,语音识别也应该是一个函数
    (1)定义一个全局变量flag,在语音识别中,当识别出结果时,flag = true
    (2)在音频播放中,不断检测 flag 是否为true,当检测到 true 时,停止音频播放;否则,继续播放

    不知道具体你代码如何,只能说一下思路

    评论
  • 白驹_过隙 算法领域新星创作者 2022-08-23 08:30
    关注
    评论
  • 脚踏南山 2022-08-17 11:43
    关注
    
    if ret==语音识别结果出来的时候:
        停止音频播放;
    if ret==未识别出语音识别结果的时候:
        音频继续播放。
    
    评论
  • 反派的大佬 2022-08-17 11:53
    关注

    if ret==语音识别结果出来的时候:
    停止音频播放;
    if ret==未识别出语音识别结果的时候:
    音频继续播放。

    评论
  • 起个昵称难得很 2022-08-17 16:04
    关注

    找到这个app的注册函数

    img


    先看这个函数的整个逻辑

    img


    这里其实也没做啥事,就是解析参数,做了错误判断
    其中这个app函数的错误响应有:
    “USAGE ERROR” (使用错误)
    “GRAMMAR ERROR” (语法错误)
    “ASR INIT ERROR” (asr初始化失败)
    “ERROR” (通用错误,通常指普通地调用app失败)
    每一个错误码的提示都很清晰,进入到这个函数的定义后就可以看到:

    img


    首先是这个核心函数最先开启语音识别,调用函数:
    switch_ivr_detect_speech
    这个函数其实就是之前看过的detect_speech一样,其实也是调用了这个函数去开启ASR:

    img


    然后设置回调函数
    play_and_detect_input_callback 这个就是打断函数,但是先不要管它
    之后就是调用了放音函数
    switch_ivr_play_file

    img


    在播放文件的时候,跳出这里有两种方式,
    1:收码跳出 (收码打断)
    2:收到mrcp start_input 事件跳出(语音打断)

    img


    一:首先调用这个app函数时,是先开启语音识别
    开启的时候初始化及创建asr通道
    通过回调函数speech_callback 来创建一条循环检查ASR的结果,并且产生事件
    产生事件,是在不断地调用mod_unimrcp 里面的一个回调函数:
    recog_channel_check_results
    产生事件的因素:必须有到结果或者收到unimrcpserver的start input 事件,才会
    产生事件,Speech-Type:begin-speaking
    之后就会一直产生的事件类型为:
    Speech-Type:detected-speech
    这样也是通过关注asr的事件,最后会一直产生这个类型的事件的原因

    二:当进入switch_ivr_play_file,在一个死循环内就会不断地去调用回调函数play_and_detect_input_callback去检查asr生成的事件,如果事件的类型为:
    SWITCH_EVENT_DETECTED_SPEECH 即收到了asr的事件,这个时候不论是收到事件类型的:begin-speaking 还是 detected-speech 都会导致跳出播放文件(打断)
    但一开始应该收到的事件一般多为mrcp的start input ,除非unimrcpserver不发送start input 事件,最后也就是说,freeswitch 的语音打断是通过mrcp的start input 或者是收到asr的识别结果来做打断的。但其实这个是不好的
    总结:
    语音打断的方案其实有不少,fs的只是其中的一种,虽然不好用,但你也可以收动改源码使这个app好用
    一:
    改动最小最简单的方法:
    打开mod_unimrcp.c 找到这个函数,只需要添加一句代码,这是最简单的代码方式就能使这个app play_and_detect_speech 变得好用起来,你甚至不用去改fs的核心代码,也不用去重新编译fs,只需要重新编译mod_unimrcp.c就行

    img


    二:
    更简单更安全的方法:
    不让unimrcpserver发送 start of input 事件,同样可以使这个app好用起来
    这个只需要编译unimrcpserver里面的插件就行

    img


    这样做都是让fs可以忽略了 mrcp 的 start of input 事件,改为收到结果再打断,准确性可以大大提高 !!!

    评论
  • 东方佑 2022-08-17 19:22
    关注

    这个是什么

    评论
  • 仰望星空的代码 博客专家认证 2022-08-18 10:16
    关注
    评论
  • {∞} 2022-08-23 17:23
    关注
             private void doVoice(ArrayList<RecognizerResult> results) {  
                Intent i = new Intent();  
                for(RecognizerResult result : results){  
                    if(result.text.contains("天气")){  
                        i.setClass(Voice1Activity.this, Weather.class);  
                        startActivity(i);  
                    }else if(result.text.contains("新闻")){  
                        i.setClass(Voice1Activity.this, News.class);  
                        startActivity(i);  
                    }else if(result.text.contains("短信")){  
                        i.setAction(Intent.ACTION_VIEW);  
                        i.setType("vnd.android-dir/mms-sms");  
                        startActivity(i);  
                    }else{  
                        Toast.makeText(Voice1Activity.this, "无法识别", Toast.LENGTH_SHORT).show();  
                    }  
                }  
                  
            } 
    
    评论

报告相同问题?

问题事件

  • 系统已结题 8月25日
  • 专家修改了标签 8月17日
  • 创建了问题 8月17日

悬赏问题

  • ¥15 unity 绘画方面的问题
  • ¥15 FTP 明明给了权限但是还是550 Permission denied问题
  • ¥20 Java的kafka错误unknowHostException
  • ¥20 gbase 8a没有lisense,需要获取一个lisense
  • ¥15 前端的3d饼图不知道用啥框架做的
  • ¥15 算法问题 斐波那契数 解答
  • ¥15 VS2019 SPY++ 获取句柄操作
  • ¥15 Facebook 获取广告
  • ¥15 PID算法的输出结果如何转换成pwm
  • ¥15 java文本解密算法