8

我正在开发一个功能,当按下按钮时,它将启动语音识别,同时记录用户所说的话。代码如下:

    button_start.setOnTouchListener( new View.OnTouchListener() 
    {
        @Override
        public boolean onTouch(View arg0, MotionEvent event) 
        {   
                if (pressed == false)
                {
                    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);        
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
                    intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,"voice.recognition.test");
                    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "zh-HK");
                    intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,1); 
                    sr.startListening(intent);
                    Log.i("111111","11111111");
                    pressed = true;
                }

                recordAudio();

            }

            if((event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL))
            {                   
                stopRecording();
            }
            return false;
        }
    });             
}

   public void recordAudio()
   {
      isRecording = true;   
      try 
      {
          mediaRecorder = new MediaRecorder();
          mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
          mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
          mediaRecorder.setOutputFile(audioFilePath);
          mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
          mediaRecorder.prepare();
      } 
      catch (Exception e) 
      {
          e.printStackTrace();
      }
      mediaRecorder.start();            
   }    

   public void stopRecording()
   {            
       if (isRecording)
       {    
           mediaRecorder.stop();
           mediaRecorder.reset();    // set state to idle
           mediaRecorder.release();
           mediaRecorder = null;
           isRecording = false;
       }
       else 
       {
           mediaPlayer.release();
           mediaPlayer.reset();
           mediaPlayer = null;
       }
   }




class listener implements RecognitionListener          
{
    // standard codes onReadyForSpeech, onBeginningOfSpeech, etc
}

问题:

我一步步做的app,一开始app没有录音功能,语音识别完美。

在我测试了很多次,认为语音识别没问题后,我开始使用MediaRecorder.

然后我进行了测试,一旦按下 button_start,ERROR3 AUDIO消息就会在我试图说话之前立即出现。

我播放录音。声音也被正确记录和保存。

怎么了?为什么使用语音识别不能同时录音?

谢谢!

4

1 回答 1

5

--EDIT-- Opus-Record模块同时语音识别也运行

--EDIT-- 'V1BETA1' 流式传输,连续识别,对示例项目稍作更改。更改“ readData() ”,因此“sData”中的原始 PCM 由 2 个线程(fileSink 线程、示例项目中的识别器 API 线程)共享。对于接收器,只需使用在每个“sData”IO 处刷新的 PCM 流连接一个编码器。记得对流进行 CLO,它会起作用。有关 fileSink 的更多信息,请查看“ writeAudiaDataToFile() ”。

--编辑--看到这个线程

当您尝试执行以下操作时,HAL 和麦克风缓冲区将会发生基本冲突:

speechRecognizer.startListening(recognizerIntent); // <-- needs mutex use of mic

mediaRecorder.start(); // <-- needs mutex use of mic

您只能选择上述操作中的一个或另一个来拥有麦克风底层的音频 API!

如果你想模仿 Google Keep 的功能,你只说一次,并且作为一个输入过程的输出(你的语音到麦克风),你会得到 2 种不同类型的输出(STT 和一个 fileSink,比如 MP3),那么你必须拆分当它从麦克风退出 HAL 层时。

例如:

  1. 拾取从麦克风缓冲区中出来的 PCM 16 的 RAW 音频

  2. 拆分上述缓冲区的字节(您可以从缓冲区获取流并将流传输到 2 个位置)

  3. 编码之前或之后的 STRM 1 到 STT 的 API(有 STT API 接受原始 PCM 16 或编码)

  4. STRM 2 到编码器,然后到 fileSink 用于捕获录音

Split 可以在麦克风产生的实际缓冲区上操作,也可以在这些相同字节的派生流上操作。

对于您要进入的内容,我建议您查看getCurrentRecording()consumeRecording() 此处

STT API 参考:谷歌“pultz speech-api”。请注意,那里提到的 API 有一些用例。

于 2014-07-23T13:12:19.740 回答