没有超时的Android语音识别?

时间:2015-12-13 17:12:22

标签: java android speech-recognition voice-recognition

我正在使用android语音识别并编写一些代码来识别口语单词。请看下面的代码。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

public class MainActivity extends Activity {

    private TextView returnedText;
    private ToggleButton toggleButton;
    private ProgressBar progressBar;
    private SpeechRecognizer speech = null;
    private Intent recognizerIntent;
    private ListView wordList;
    private String LOG_TAG = "VoiceRecognitionActivity";
    private List<String> previousInterim;
    private diff_match_patch diff;
    private String display = "test";

    private List<String>adapterList = new ArrayList<String>();
    ArrayAdapter<String>  adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        returnedText = (TextView) findViewById(R.id.textView1);
        progressBar = (ProgressBar) findViewById(R.id.progressBar1);
        toggleButton = (ToggleButton) findViewById(R.id.toggleButton1);
        wordList = (ListView)findViewById(R.id.word_list);

        adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_checked, adapterList);
        adapter.setNotifyOnChange(true);
        wordList.setAdapter(adapter);
        progressBar.setVisibility(View.INVISIBLE);

       // createRecog();
        speech = SpeechRecognizer.createSpeechRecognizer(getApplicationContext());
        toggleButton.setOnCheckedChangeListener(new ButtonListener());



    }

    private class ButtonListener implements OnCheckedChangeListener, Runnable
    {
        boolean isChecked;

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            this.isChecked = isChecked;
            this.run();
        }

        @Override
        public void run() {

            if (isChecked) {
                speech.stopListening();
                speech.cancel();
                speech.destroy();
                createRecog();
                progressBar.setVisibility(View.VISIBLE);
                progressBar.setIndeterminate(true);
                speech.startListening(recognizerIntent);
                adapter.clear();

                returnedText.setText("");

            } else {
                progressBar.setIndeterminate(false);
                progressBar.setVisibility(View.INVISIBLE);
                speech.stopListening();

            }


        }
    }

    private class RecognitionListenerClass implements RecognitionListener
    {


        @Override
        public void onBeginningOfSpeech() {
            Log.i(LOG_TAG, "onBeginningOfSpeech");
            progressBar.setIndeterminate(false);
            progressBar.setMax(10);
            wordList.computeScroll();
        }

        @Override
        public void onBufferReceived(byte[] buffer) {
            Log.i(LOG_TAG, "onBufferReceived: " + buffer);
        }

        @Override
        public void onEndOfSpeech() {
            Log.i(LOG_TAG, "onEndOfSpeech");
            progressBar.setIndeterminate(true);
            toggleButton.setChecked(false);
        }

        @Override
        public void onError(int errorCode) {
            String errorMessage = getErrorText(errorCode);
            Log.d(LOG_TAG, "FAILED " + errorMessage);
            returnedText.setText(errorMessage);
            toggleButton.setChecked(false);


          //  speech = null;
            toggleButton.performClick();
        }

        @Override
        public void onEvent(int arg0, Bundle arg1) {
            Log.i(LOG_TAG, "onEvent");
        }

        @Override
        public void onPartialResults(Bundle arg0) {
            Log.i(LOG_TAG, "onPartialResults");
            final ArrayList<String> matches = arg0.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
            final float[] scores = arg0.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES);
            receiveWhatWasHeard(matches, scores);

        }

        @Override
        public void onReadyForSpeech(Bundle arg0) {
            Log.i(LOG_TAG, "onReadyForSpeech");
        }

        @Override
        public void onResults(Bundle results) {

        }

        @Override
        public void onRmsChanged(float rmsdB) {
            Log.i(LOG_TAG, "onRmsChanged: " + rmsdB);
            progressBar.setProgress((int) rmsdB);
        }
    }


    private void receiveWhatWasHeard(ArrayList<String> matches, float[] scores) {

        Log.i(LOG_TAG, matches.get(0));
    returnedText.setText(matches.get(0));        
    }

    private void createRecog()
    {
        speech = SpeechRecognizer.createSpeechRecognizer(this);
        speech.setRecognitionListener(new RecognitionListenerClass());
        recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE,
                "en");
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
                this.getPackageName());
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
        recognizerIntent.putExtra("android.speech.extra.DICTATION_MODE", true);
        recognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
    }

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

    @Override
    protected void onPause() {
        super.onPause();
    }



    public  String getErrorText(int errorCode) {
        String message;
        switch (errorCode) {
            case SpeechRecognizer.ERROR_AUDIO:
                message = "Audio recording error";
                break;
            case SpeechRecognizer.ERROR_CLIENT:
                message = "Client side error";
                break;
            case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
                message = "Insufficient permissions";
                break;
            case SpeechRecognizer.ERROR_NETWORK:
                message = "Network error";
                break;
            case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
                message = "Network timeout";
                break;
            case SpeechRecognizer.ERROR_NO_MATCH:
                message = "No match";
                break;
            case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
                message = "RecognitionService busy";
                break;
            case SpeechRecognizer.ERROR_SERVER:
                message = "error from server";
                break;
            case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
                message = "No speech input";
                break;
            default:
                message = "Didn't understand, please try again.";
                break;
        }

        return message;
    }

}

然而,我需要继续这样做,我没有一直这样做。在语音结束时重新启动识别可能是一个好主意,但它会产生很小的噪音,加载需要1-3秒,这意味着一些语音会丢失。

是的我知道谷歌已经提到他们的系统不是为了持续认可;但是之前有几个人做过工作。不幸的是,这些解决方法现在似乎不起作用,因为它们是用相当旧的API编写的。如果可以使用旧版本,那么当然在新版本中更有可能。

那么,关于如何实现这种持续识别任务的任何想法?我使用的是API 15。

1 个答案:

答案 0 :(得分:2)

阅读here了解背景

this demo是连续的,并使用pultz博客评论流中提到的铬源

全双工谷歌api工作正常in android。 AFAIK,它仍然是有限的,使它在生产应用程序中无用。

google全双工stdout sample使用curl cli

IBM watson拥有支持连续模式的全双工和生产就绪API。你需要深入研究文档细节,但一般的cli样本是here

请参阅watson api上的continuous here