Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use microphone in multiple app simultaneously in Android

We have an Android device on which we would like to use the microphone in 2 app simultaneously.

In fact, we have a vocal command service that is running in the background (we are using the CMU Sphinx library). The problem is when we start a video recorder (camera application), we can't start the recording as 2 applications can't access to the microphone at the same time.

Error

08-20 12:20:14.601: I/MediaRecorderJNI(7261): prepare: surface=0x59590668
08-20 12:20:15.916: E/MediaRecorder(7261): start failed: -38
08-20 12:20:15.916: E/com.example.CamcorderView(7261): Failed to start recorder.
08-20 12:20:15.916: E/com.example.CamcorderView(7261): java.lang.IllegalStateException
08-20 12:20:15.916: E/com.example.CamcorderView(7261):     at android.media.MediaRecorder.start(Native Method)

Note that the camera works well when the vocal service is off.

Moreover, I precise that I've already read this thread :

Android: Accessing the microphone simultaniously (RecognizerIntent + own app)

but the difference here is that we have a hand on the O/S and the kernel. So we can apply patch if needed.

Is it an SDK/OS/Kernel limitation? Is there any workaround ?

like image 423
Louisbob Avatar asked Aug 20 '14 10:08

Louisbob


People also ask

Can two apps use mic at the same time Android?

When two apps are capturing concurrently, only one app receives audio and the other gets silence. Android shares the input audio according to these rules: If neither app is privacy-sensitive, the app with a UI on top receives audio. If neither app has a UI, the one that started capture the most recently receives audio.

Can two apps use mic at the same time iOS?

iOS does not allow simultaneous access to a devices microphone(s) by two apps. It does, however, allow an app to explicitly export audio (such as from the mic) via inter-app audio or audiobus.


1 Answers

This scenario happens

for instance

when you want to record phone call. you can use the open source call recorder. see this and this

Here is a code sample

private MediaRecorder recorder = null;
public void onCreate()
{
    super.onCreate();
    recorder = new MediaRecorder();
    Log.i("CallRecorder", "onCreate created MediaRecorder object");
}

public void onStart(Intent intent, int startId) {

    if (isRecording) return;

    Context c = getApplicationContext();
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);

    Boolean shouldRecord = prefs.getBoolean(Preferences.PREF_RECORD_CALLS, false);
    if (!shouldRecord) {
        Log.i("CallRecord", "RecordService::onStartCommand with PREF_RECORD_CALLS false, not recording");
        return;
    }

    int audiosource = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_SOURCE, "1"));
    int audioformat = Integer.parseInt(prefs.getString(Preferences.PREF_AUDIO_FORMAT, "1"));

    recording = makeOutputFile(prefs);
    if (recording == null) {
        recorder = null;
        return; //return 0;
    }

    Log.i("CallRecorder", "RecordService will config MediaRecorder with audiosource: " + audiosource + " audioformat: " + audioformat);
    try {
        // These calls will throw exceptions unless you set the 
        // android.permission.RECORD_AUDIO permission for your app
        recorder.reset();
        recorder.setAudioSource(audiosource);
        recorder.setOutputFormat(audioformat);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        recorder.setOutputFile(recording.getAbsolutePath());
        //recorder.setMaxDuration(msDuration); //1000); // 1 seconds
        //recorder.setMaxFileSize(bytesMax); //1024*1024); // 1KB

        recorder.setOnInfoListener(this);
        recorder.setOnErrorListener(this);

        try {
            recorder.prepare();
        } catch (java.io.IOException e) {
            Log.e("CallRecorder", "RecordService::onStart() IOException attempting recorder.prepare()\n");
            t.show();
            recorder = null;
            return;
        }
        Log.d("CallRecorder", "recorder.prepare() returned");

        recorder.start();
        isRecording = true;
        Log.i("CallRecorder", "recorder.start() returned");
        updateNotification(true);
    } catch (java.lang.Exception e) {
        Log.e("CallRecorder", "RecordService::onStart caught unexpected exception", e);
        recorder = null;
    }

    return;
}
like image 124
Alireza Rahimi Avatar answered Oct 21 '22 09:10

Alireza Rahimi