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

在进行语音识别时,不会调用RecognitionListener中接收的onBufferReceived

夏侯华彩
2023-03-14

现在,我正在开发一种功能,它配备了语音识别和无效记录功能。我将在识别过程发生时收集语音缓冲区数据。与RecognitionListener一样,应该在识别过程中触发onBufferReceived,但显然在识别过程中没有打印日志。在我的调试器模式中,它还显示了应该步进方法onBufferReceived的注意事项。我的目的是在识别过程中收集缓冲区数据,并将缓冲区保存到记录文件中。

主要活动

package com.example.syoui.voicerecordtest;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.io.IOException;
import java.util.ArrayList;

import static android.R.attr.prompt;

public class MainActivity extends AppCompatActivity {
    private static final String LOG_TAG = "AudioRecordTest";
    private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
    private static String mFileName = null;

    private RecordButton mRecordButton = null;
    public MediaRecorder mRecorder = null;

    private PlayButton   mPlayButton = null;
    private MediaPlayer mPlayer = null;

    // Requesting permission to RECORD_AUDIO
    private boolean permissionToRecordAccepted = false;
    private String [] permissions = {Manifest.permission.RECORD_AUDIO};


    private static final String TAG = "SpeechRecognizerSampleActivity";
    private SpeechRecognizer recog;
    private Runnable readyRecognizeSpeech;
    public Handler handler = new Handler();

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case REQUEST_RECORD_AUDIO_PERMISSION:
                permissionToRecordAccepted  = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                break;
        }
        if (!permissionToRecordAccepted ) finish();

    }

    private void onRecord(boolean start) {
        if (start) {
            startRecording();
        } else {
            stopRecording();
        }
    }

    private void onPlay(boolean start) {
        if (start) {
            startPlaying();
        } else {
            stopPlaying();
        }
    }

    private void startPlaying() {
        mPlayer = new MediaPlayer();
        try {
            mPlayer.setDataSource(mFileName);
            mPlayer.prepare();
            mPlayer.start();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }
    }

    private void stopPlaying() {
        mPlayer.release();
        mPlayer = null;
    }

    private void startRecording() {

        if( mRecorder != null){
            stopRecording();
        }

        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mRecorder.setOutputFile(mFileName);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        try {
            mRecorder.prepare();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }

        mRecorder.start();
        startRecognizeSpeech();
    }

    private void stopRecording() {
        mRecorder.stop();
        mRecorder.release();
        mRecorder = null;
    }

    class RecordButton extends Button {
        boolean mStartRecording = true;

        OnClickListener clicker = new OnClickListener() {
            public void onClick(View v) {
                onRecord(mStartRecording);
                if (mStartRecording) {
                    setText("Stop recording");
                } else {
                    setText("Start recording");
                }
                mStartRecording = !mStartRecording;
            }
        };

        public RecordButton(Context ctx) {
            super(ctx);
            setText("Start recording");
            setOnClickListener(clicker);
        }
    }

    class PlayButton extends Button {
        boolean mStartPlaying = true;

        OnClickListener clicker = new OnClickListener() {
            public void onClick(View v) {
                onPlay(mStartPlaying);
                if (mStartPlaying) {
                    setText("Stop playing");
                } else {
                    setText("Start playing");
                }
                mStartPlaying = !mStartPlaying;
            }
        };

        public PlayButton(Context ctx) {
            super(ctx);
            setText("Start playing");
            setOnClickListener(clicker);
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (mRecorder != null) {
            mRecorder.release();
            mRecorder = null;
        }

        if (mPlayer != null) {
            mPlayer.release();
            mPlayer = null;
        }
    }


    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.activity_main);
        // Record to the external cache directory for visibility

        mFileName = getExternalCacheDir().getAbsolutePath();
        //mFileName = "/sdcard";
        mFileName += "/audiorecordtest.3gp";

        Log.i("mFileName",mFileName);

        ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);

        LinearLayout ll = (LinearLayout) findViewById(R.id.recordButton);
        mRecordButton = new RecordButton(this);
        ll.addView(mRecordButton,
                new LinearLayout.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        0));
        mPlayButton = new PlayButton(this);
        ll.addView(mPlayButton,
                new LinearLayout.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        0));

        /*******/

        recog = SpeechRecognizer.createSpeechRecognizer(this);
        recog.setRecognitionListener(new RecogListener(this));



        // listener登録
        Button b = (Button)findViewById(R.id.start_recognize);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startRecognizeSpeech();
            }
        });
       // startRecognizeSpeech();

    }


    private void startRecognizeSpeech() {
        //Intent intent = RecognizerIntent.getVoiceDetailsIntent(getApplicationContext());
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);

        recog.startListening(intent);


        ((TextView)findViewById(R.id.status)).setText("");
        ((TextView)findViewById(R.id.sub_status)).setText("");
        findViewById(R.id.start_recognize).setEnabled(false);
    }

    /***********/


    private static class RecogListener implements RecognitionListener {
        private MainActivity caller;
        private TextView status;
        private TextView subStatus;

        RecogListener(MainActivity a) {
            caller = a;
            status = (TextView)a.findViewById(R.id.status);
            subStatus = (TextView)a.findViewById(R.id.sub_status);
        }

        // 音声認識準備完了
        @Override
        public void onReadyForSpeech(Bundle params) {
            status.setText("ready for speech");
            Log.v(TAG,"ready for speech");
        }

        // 音声入力開始
        @Override
        public void onBeginningOfSpeech() {
            status.setText("beginning of speech");
            Log.v(TAG,"beginning of speech");
        }

        // 録音データのフィードバック用
        @Override
        public void onBufferReceived(byte[] buffer) {
            status.setText("onBufferReceived");
            Log.v(TAG,"onBufferReceived");

            //status.setText(buffer.toString());
        }

        public void BufferReceived(byte[] buffer) {
            status.setText("onBufferReceived");
            Log.v(TAG,"onBufferReceived");

            //status.setText(buffer.toString());
        }


        // 入力音声のdBが変化した
        @Override
        public void onRmsChanged(float rmsdB) {
            String s = String.format("recieve : % 2.2f[dB]", rmsdB);
            subStatus.setText(s);
            //Log.v(TAG,"recieve : " + rmsdB + "dB");
        }

        // 音声入力終了
        @Override
        public void onEndOfSpeech() {
            status.setText("end of speech");
            Log.v(TAG,"end of speech");
            caller.handler.postDelayed(caller.readyRecognizeSpeech, 500);
        }

        // ネットワークエラー又は、音声認識エラー
        @Override
        public void onError(int error) {
            status.setText("on error");
            caller.findViewById(R.id.start_recognize).setEnabled(true);
            Log.v(TAG,"on error");
            switch (error) {
                case SpeechRecognizer.ERROR_AUDIO:
                    // 音声データ保存失敗
                    subStatus.setText("ERROR_AUDIO");
                    break;
                case SpeechRecognizer.ERROR_CLIENT:
                    // Android端末内のエラー(その他)
                    subStatus.setText("ERROR_CLIENT");
                    break;
                case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
                    // 権限無し
                    subStatus.setText("ERROR_INSUFFICIENT_PERMISSIONS");
                    break;
                case SpeechRecognizer.ERROR_NETWORK:
                    // ネットワークエラー(その他)
                    subStatus.setText("ERROR_NETWORK");
                    break;
                case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
                    // ネットワークタイムアウトエラー
                    subStatus.setText("ERROR_NETWORK_TIMEOUT");
                    break;
                case SpeechRecognizer.ERROR_NO_MATCH:
                    // 音声認識結果無し
                    subStatus.setText("ERROR_NO_MATCH");
                    caller.handler.postDelayed(caller.readyRecognizeSpeech,1000);
                    break;
                case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
                    // RecognitionServiceへ要求出せず
                    subStatus.setText("ERROR_RECOGNIZER_BUSY");
                    caller.handler.postDelayed(caller.readyRecognizeSpeech,1000);
                    break;
                case SpeechRecognizer.ERROR_SERVER:
                    // Server側からエラー通知
                    subStatus.setText("ERROR_SERVER");
                    break;
                case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
                    // 音声入力無し
                    subStatus.setText("ERROR_SPEECH_TIMEOUT");
                    caller.handler.postDelayed(caller.readyRecognizeSpeech,1000);
                    break;
                default:
            }
        }

        // イベント発生時に呼び出される
        @Override
        public void onEvent(int eventType, Bundle params) {
            status.setText("on event");
            Log.v(TAG,"on event");
        }

        // 部分的な認識結果が得られる場合に呼び出される
        @Override
        public void onPartialResults(Bundle partialResults) {
            status.setText("on partial results");
            Log.v(TAG,"on results");
        }

        // 認識結果
        @Override
        public void onResults(Bundle data) {
            status.setText("on results");
            Log.v(TAG,"on results");
            ArrayList<String> results = data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

            TextView t = (TextView)caller.findViewById(R.id.result);
            t.setText("");
            for (String s : results) {
                t.append(s + "\n");
            }

//            boolean end=false;
//            for (String s : results) {
//                if (s.equals("終わり"))
//                    end=true;
//                if (s.equals("おわり"))
//                    end=true;
//                if (s.equals("キャンセル"))
//                    end=true;
//            }
//            if (end)
//                caller.findViewById(R.id.start_recognize).setEnabled(true);
//            else
//                caller.startRecognizeSpeech();


            caller.findViewById(R.id.start_recognize).setEnabled(true);

            //caller.startRecognizeSpeech();

        }
    }


}

activity\u main。xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.syoui.voicerecordtest.MainActivity">





                <LinearLayout
                              android:layout_width="fill_parent"
                              android:layout_height="wrap_content"
                              android:orientation="vertical" >
                            <Button
                                android:id="@+id/start_recognize"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="@string/start_recognize" />
                            <TextView
                                android:id="@+id/status"
                                android:layout_width="fill_parent"
                                android:layout_height="wrap_content" />
                            <TextView
                                android:id="@+id/sub_status"
                                android:layout_width="fill_parent"
                                android:layout_height="wrap_content" />
                            <ScrollView
                                android:layout_height="fill_parent"
                                android:layout_width="wrap_content">
                                <TextView
                                    android:id="@+id/result"
                                    android:inputType="textMultiLine"
                                    android:layout_height="fill_parent"
                                    android:layout_width="fill_parent"/>
                            </ScrollView>



                    <LinearLayout
                        android:layout_width="fill_parent"
                        android:layout_height="130dp"
                        android:orientation="vertical"
                        android:id="@+id/recordButton">
                    </LinearLayout>
                </LinearLayout>







</android.support.constraint.ConstraintLayout>

string.xml

<resources>
    <string name="app_name">voiceRecordTest</string>
    <string name="start_recognize">開始</string>
</resources>

共有1个答案

宋飞舟
2023-03-14

对于ICS,不再调用onBufferReceived。阅读本讨论如何构建BufferReceived()以使用RecognitiverIntent捕获语音?

 类似资料:
  • [信息]:#安装纯Python模块 [信息]:需求(SpeechRecognition,pyaudio)没有菜谱,试图用pip安装它们 [信息]:如果失败,这可能意味着模块已经编译了组件,需要一个配方。 工作:pid 3095的线程后台线程异常:n/python2.7-u-c“导入设置...(和509更多) 回溯(最近调用的最后一次): 文件“/usr/lib/python2.7/threadin

  • 我想在一个用dart编写的颤振项目中使用Google的实时语音识别api。我已经激活了一个gcloud帐户,创建了api密钥(这应该是谷歌语音唯一必要的身份验证方法),并编写了一个基本的apk,它应该向谷歌云发送音频流并显示响应。我导入了googleapis/speech和googleapis\u auth插件。 但是我不知道如何设置它。他们说你必须使用gRPC,这是有道理的,因为它应该使它易于使

  • 我正在努力寻找使用谷歌云语音API进行实时连续语音识别的例子。我的要求是使用麦克风,检测语音,并在用户说话时进行转录。 我知道他们的RESTAPI没有这种支持,所以我研究了grpc示例,包括他们提供的示例。但它们似乎都是用户可以上传音频并检测语音的例子。 我在Java,谷歌grpc也支持java。有人遇到一个很好的例子,展示了如何通过麦克风持续进行这种识别吗?

  • A.我正在努力实现的目标。 允许在网络浏览器内进行实时语音识别的网络应用程序(像这样)。 B.我目前正在考虑使用的技术来实现A。 JavaScript 节点。js WebRTC 微软语音API或Pocketsphinx。js或其他东西(不能使用Web语音API) C.非常基本的工作流程 Web浏览器建立到节点服务器的连接(服务器充当信令服务器,还提供静态文件) D.问题 将节点。js是否适合实现C

  • 我确实试过给下面这些额外的东西以毫秒为单位的时间 但不影响语音收听时间!我现在得到的语音收听时间只有3秒!如何实现10秒的收听时间

  • 我正在尝试从扬声器转录音频 我正在将声音从扬声器传送到节点。js文件(https://askubuntu.com/a/850174) 这是我的抄本。js公司 但谷歌云语音到文本在1分钟内对流媒体识别有一个限制。所以我有一个错误“超过了允许的最大流持续时间65秒” 如何将流拆分为以静默为拆分器的块,或拆分为持续30秒的块?