我需要一些帮助来解决语音识别器的问题。
背景
我的任务是实现一个语音备忘录功能:用户可以记录短音频、保存它、然后收听它。如果用户没有机会收听该音频,他可以轻敲特殊的"Aa"按钮,并获得作为文本的他的语音笔记的抄本。
由于我没有找到合适的方法来识别预先录制的音频,所以我决定在录制音频的同时使用SpeechRecognizer实现语音识别。识别结果存储在字符串中,当用户点击"Aa"按钮时,这个字符串就会显示在屏幕上。
来源
在Activity中,我声明了一个SpeechRecognizer及其Intent,以及一个用于存储识别文本的字符串和一个特殊变量isStoppedByUser。需要使用该变量,以便只有当用户自己停止录制时,识别才会停止(如果用户在说话过程中暂停,识别可能会自动停止,但我不需要这样做)。
private SpeechRecognizer speechRecognizer;
private Intent speechRecognizerIntent;
private String recognizedMessage = "";
private boolean isStoppedByUser = false;
我在一个单独的方法中初始化SpeechRecognizer,该方法从onCreate()调用。
private void initSpeechRecognizer() {
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
boolean isRecognitionAvailable = SpeechRecognizer.isRecognitionAvailable(this);
Toast.makeText(this, "isRecognitionAvailable = " + isRecognitionAvailable, Toast.LENGTH_SHORT).show();
Log.i(TAG, "isRecognitionAvailable: " + isRecognitionAvailable);
speechRecognizer.setRecognitionListener(new RecognitionListener() {
@Override
public void onRmsChanged(float rmsdB) {
Log.d(TAG, "onRmsChanged() called with: rmsdB = [" + rmsdB + "]");
}
@Override
public void onResults(Bundle results) {
Log.d(TAG, "onResults() called with: results = [" + results + "]");
ArrayList<String> data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
recognizedMessage += " " + data.get(0);
Log.d(TAG, "onResults(): recognizedMessage = " + recognizedMessage);
// If recognition stops by itself (as a result of a pause in speaking), we start recognition again
if (!isStoppedByUser) {
speechRecognizer.startListening(speechRecognizerIntent);
}
}
@Override
public void onError(int error) {
Log.d(TAG, "onError() called with: error = [" + error + "]");
if (!isStoppedByUser) {
speechRecognizer.startListening(speechRecognizerIntent);
}
}
// Other callback methods. They have nothing but logging
// ...
});
}
用户开始记录:
startRecording();
isStoppedByUser = false;
recognizedMessage = "";
speechRecognizer.startListening(speechRecognizerIntent);
用户停止记录:
isStoppedByUser = true;
speechRecognizer.stopListening();
// Further processing of recorded audio
// ...
问题
我在两台设备上测试了此功能:小米9T和Realme 8i.
小米上一切正常:就在我说话的时候,onRmsChanged()
方法每秒被调用几次,rmsdB
的值不同,我在日志中可以清楚地看到这一点,也就是说,音量发生了变化,然后调用了其他回调方法,成功地形成了字符串。
但是在Realme上,onRmsChanged()
方法只被调用一次,在最开始的时候,值为-2.0
,在我说话的时候没有其他事情发生,当我停止录制时,onError()
方法被调用,代码为7(ERROR_NO_MATCH
)。
就好像SpeechRecognizer听不到我说话一样,但麦克风没有问题,并且还授予了RECORD_AUDIO
权限:音频本身被成功地记录并且可以被收听。
如果我打开谷歌应用程序并输入语音请求,一切也都正常工作。
如果你推荐还有什么其他参数可以设置来解决这个问题,我将非常感激,谢谢!
1条答案
按热度按时间kmb7vmvb1#
问题原来是不可能同时使用麦克风API进行录音和语音识别,因此,在小米上一切正常的事实原来只是一个令人高兴的意外。