record/save audio from voice recognition intent

Slim picture Slim · Apr 13, 2014 · Viewed 18.5k times · Source

Before asking this question, I checked all stackoverflow other threads related to this issue without any success, so please, don't answer with links to other threads, :)

I want to save/record the audio that google recognition service used for speech to text operation (using RecognizerIntent or SpeechRecognizer).

I experienced many ideas:

  1. onBufferReceived from RecognitionListener: I know, this is not working, just test it to see what happens and onBufferReceived is never called (tested on galaxy nexus with JB 4.3)
  2. used a media recorder: not working. it's breaking speech recognition. only one operation is allowed for mic
  3. tried to find where recognition service is saving the temporary audio file before the execution of the speech to text api to copy it, but without success

I was almost desperate but I just noticed that Google Keep application is doing what I need to do!!!! I debuged a little the keep application using logcat and the app is also calling the "RecognizerIntent.ACTION_RECOGNIZE_SPEECH" (like we, developers, do) to trigger speech to text. but, how keep is saving the audio? can it be a hide api? is google "cheating" :) ?

Thank you for your help

Best regards

Answer

Iftah picture Iftah · Jun 25, 2014

@Kaarel's answer is almost complete - the resulting audio is in intent.getData() and can be read using ContentResolver

Unfortunately, the AMR file that is returned is low quality - I wasn't able to find a way to get high quality recording. Any value I tried other than "audio/AMR" returned null in intent.getData().

If you find a way to get high quality recording - please comment or add an answer!

public void startSpeechRecognition() {
   // Fire an intent to start the speech recognition activity.
   Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
   // secret parameters that when added provide audio url in the result
   intent.putExtra("android.speech.extra.GET_AUDIO_FORMAT", "audio/AMR");
   intent.putExtra("android.speech.extra.GET_AUDIO", true);

   startActivityForResult(intent, "<some code you choose>");
}

// handle result of speech recognition
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // the resulting text is in the getExtras:
    Bundle bundle = data.getExtras();
    ArrayList<String> matches = bundle.getStringArrayList(RecognizerIntent.EXTRA_RESULTS)
    // the recording url is in getData:
    Uri audioUri = data.getData();
    ContentResolver contentResolver = getContentResolver();
    InputStream filestream = contentResolver.openInputStream(audioUri);
    // TODO: read audio file from inputstream
}