1

I am writing an application, which has a WebView, that is handling a voice call via WebRTC. Microphone is working OK as I have granted permission to WebView.

webView.setWebChromeClient(new WebChromeClient() {
       @Override
        public void onPermissionRequest(final PermissionRequest request) {
            request.grant(request.getResources());
        }

Later I decided to add SpeechRecognizer so I can recognize what I am saying during the WebRTC call. I tried to make speech recognition work in the same activity, later I did it in a separate service, but unfortunally, it doesn't allow to work in a simultaneous way. Microphone gets occupied by WebView, and SpeechRecognizer doesn't get any sound (RMS is constantly -2.12). Or, if I try to run service before making call through WebView, the person I am calling to doesn't hear me at all (SpeechRecognizer occupies microphone and WebView doesn't get anything). I hope to find any solution if it exists. I am not an iOS developer, but I've heard, that it's possible on iPhone, so it's a surprise, that is impossible on Android device. My Speech Recognition service code public class RecognitionService extends Service implements RecognitionListener {

private String LOG_TAG = "RecognitionService";
private SpeechRecognizer speech = null;
private Intent recognizerIntent;
public RecognitionService() {
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    startRecognition();
    return null;
}



@Override
public void onCreate() {
    Log.i("Test", "RecognitionService: onCreate");
    startRecognition();
}

private void startRecognition() {
    speech = SpeechRecognizer.createSpeechRecognizer(this);
    speech.setRecognitionListener(this);
    recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE,
            "ru-RU");
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
            getPackageName());
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
    recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);
    speech.startListening(recognizerIntent);
}

@Override
public void onBeginningOfSpeech() {
    Log.i(LOG_TAG, "onBeginningOfSpeech");
}

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

@Override
public void onEndOfSpeech() {
    Log.i(LOG_TAG, "onEndOfSpeech");
}

@Override
public void onError(int errorCode) {
    String errorMessage = getErrorText(errorCode);
    Log.d(LOG_TAG, "FAILED " + errorMessage);
    speech.destroy();
    startRecognition();
}
@Override
public void onEvent(int arg0, Bundle arg1) {
    Log.i(LOG_TAG, "onEvent");
}

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

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

@Override
public void onResults(Bundle results) {
    Log.i(LOG_TAG, "onResults");
    ArrayList<String> matches = results
            .getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
    String text = "";
    for (String result : matches)
        text += result + "\n";

    Toast.makeText(getApplicationContext(),text,Toast.LENGTH_SHORT).show();
    speech.destroy();
    startRecognition();
}


public static 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;
}
@Override
public void onRmsChanged(float rmsdB) {
    Log.i(LOG_TAG, "onRmsChanged: " + rmsdB);
}


}
inthy
  • 362
  • 6
  • 16
  • if you can expose the buffer where the mic's raw audio is then, that buffer can be split .. http://stackoverflow.com/questions/25532200/webrtc-play-audio-input-as-microphone and http://stackoverflow.com/questions/23047433/record-save-audio-from-voice-recognition-intent buffer1 -> recognizer .. buffer2 -> rtc stream – Robert Rowntree Jun 28 '16 at 17:22
  • https://chromium.googlesource.com/external/webrtc/+/master/webrtc/modules/audio_device/android/java/src/org/webrtc/voiceengine/WebRtcAudioRecord.java?#85 is where the split could be done. – Robert Rowntree Jun 28 '16 at 22:38

0 Answers0