当前位置: 首页 > 知识库问答 >
问题:

SpeechRecognitor在第一个结果后没有听到

匡晟
2023-03-14

我正在使用Android中的Speech认知器和识别器来实现语音识别。我的目标是在我的语音识别器在屏幕上显示结果后重新开始听语音。为此,我使用以下代码。

问题是,第一次运行正常并显示结果,但在第二次开始侦听(从onResults方法调用)后,由于某种原因,它听不到正在说的内容。然后它给出一个ERROR\u SPEECH\u TIMEOUT错误,这意味着没有语音输入。在Logcat上,我可以看到它进入ReadyForSpeech(),但不知何故,它听不到我在说什么。

有人知道为什么会这样吗?它在返回结果后是否继续侦听?再次显式调用startListening是否正确?

public class VR extends Activity implements RecognitionListener {


    private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
    private TextView vrtext;
    private SpeechRecognizer speech = null;
    private Intent intent;
    private String TAG = "VR";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.vr);

        vrtext = (TextView) findViewById(R.id.vrtext);  

    }

    @Override
    public void onResume()
    {
        listen();
        super.onResume();
    }

    private void listen()
    {
        speech = SpeechRecognizer.createSpeechRecognizer(this);
        speech.setRecognitionListener(this);
        intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

        speech.startListening(intent);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // TODO Auto-generated method stub

        if(speech != null)
        {
            speech.destroy();
            Log.i(TAG,"destroy");
        }

    }

    public void onBeginningOfSpeech() {
        // TODO Auto-generated method stub
        Log.i(TAG, "onbeginningofspeech");
    }

    public void onBufferReceived(byte[] arg0) {
        // TODO Auto-generated method stub
        //Log.i(TAG, "onbufferreceived");
    }

    public void onEndOfSpeech() {
        // TODO Auto-generated method stub
        Log.i(TAG, "onendofspeech");
    }

    public void onError(int arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "error code: " + arg0);
    }

    public void onEvent(int arg0, Bundle arg1) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onevent");
    }

    public void onPartialResults(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onpartialresults");
    }

    public void onReadyForSpeech(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onreadyforspeech");
    }

    public void onResults(Bundle arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "onresults");
        ArrayList<String> matches = arg0.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
        String s = "";
        for (String result:matches)
            s += result + "\n";

        vrtext.setText(s);

        speech.startListening(intent);

    }

    public void onRmsChanged(float arg0) {
        // TODO Auto-generated method stub
        //Log.i(TAG, "onrmschanged");
    }

}

共有2个答案

连俊智
2023-03-14

确保在活动中使用单个SpeechRecognitor对象。快速而肮脏的方法是使其静止。

private static SpeechRecognizer speech = null;

更改您的listen()方法以检查speech对象上的null。

private void listen()
{
    if (speech == null) {
        speech = SpeechRecognizer.createSpeechRecognizer(this);
        speech.setRecognitionListener(this);
    }
    intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "en");
    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
    intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

    speech.startListening(intent);
}

调用监听方法在on结果()onError().

public void onResults(Bundle arg0) {
    // TODO Auto-generated method stub
    Log.i(TAG, "onresults");
    ArrayList<String> matches = arg0.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
    String s = "";
    for (String result:matches)
        s += result + "\n";

    vrtext.setText(s);

    //speech.startListening(intent);
    listen();

}

public void onError(int arg0) {
    // TODO Auto-generated method stub
    Log.i(TAG, "error code: " + arg0);
    listen();
}

最后,不要忘记在onDestroy()中进行必要的清洁。

@Override
public void onDestroy() {
    super.onDestroy();
    speech.destroy();
}
慕容明煦
2023-03-14

“它在返回结果后是否继续侦听?”不

“再次明确调用startListening是否正确?”对

此外,如果您想让识别持续发生,如果出现以下错误,您应该再次调用start Listning

@Override
public void onError(int errorCode)
{
    if ((errorCode == SpeechRecognizer.ERROR_NO_MATCH)
            || (errorCode == SpeechRecognizer.ERROR_SPEECH_TIMEOUT))
    {
        Log.d(TAG, "didn't recognize anything");
        // keep going
        recognizeSpeechDirectly();
    }
    else
    {
        Log.d(TAG,
                "FAILED "
                        + SpeechRecognitionUtil
                                .diagnoseErrorCode(errorCode));
    }
}

请查看我的代码,以便在此处使用SpeechRecognitor检测特定的口语单词。

 类似资料:
  • 在阅读了Oracle站点上的这篇文章https://community.Oracle.com/docs/doc-995305之后,我将尝试实现“Some Two-to-One selection patterns”段落中描述的模式。这最后一类模式还包含二对一模式。但是这次不是执行一次下游元素,而是完成两个上游元素,当两个上游元素中的一个完成时执行下游元素。例如,当我们要解析域名时,这可能会证明非常

  • 我正在尝试用反应异步postgres-async-driver替换PostgreSQL数据库轮询器,并将新插入的行流式传输到Spring5WebFlux反应websocket客户机,就像这里演示的Josh Long的出色示例一样,并基于Sébastien Deleuze的Spring-reactive-playground。 我的获取第一个,但不返回后续行。问题是我的、还是我如何使用postgre

  • 问题内容: 我有这种简单的查询,它返回给定id的非空整数字段: 问题是,如果找不到ID,则结果集为空。我需要查询始终返回一个值,即使没有结果也是如此。 我有这个东西工作,但我不喜欢它,因为它运行相同子查询的2倍: 如果该行存在,则返回field1,否则返回0。有什么改进的方法吗? 谢谢! 编辑以下一些评论和答案 :是的,它必须在 单个查询语句中, 并且我不能使用count技巧,因为 我只需要返回1

  • 嗨,我是新来的Java并发,我正在尝试通过分叉连接将列表内容加倍,并将任务分成多个部分。任务完成,但结果从未到达。 如果我调试我的任务,那么我可以发现数字增加了一倍,但结果从未到达第56行

  • 这是我在控制器中的getIndex()函数中的东西 所以我希望从循环中获取所有类别名称。 但是,例如,如果我希望通过在视图中执行此操作来获得结果 结果是 > 对象(类别)169(20){[“可填充”:受保护]= 字符串(3)“foo1” 第一个结果从哪里来,我如何摆脱它?谢谢!