Use microphone in multiple app simultaneously in Android

16,505

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;
}
Share:
16,505

Related videos on Youtube

Louisbob
Author by

Louisbob

Updated on September 15, 2022

Comments

  • Louisbob
    Louisbob over 1 year

    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 ?

    • sigrlami
      sigrlami over 9 years
      You can start service (something like intermediate layer), that will be getting information from mic, and then send data to multiple applications.
    • Michael
      Michael over 9 years
      I don't remember exactly where the limitation comes from, but on one of the platforms I've worked with we had a workaround in the form of a stream splitter. This class was written by the platform provider (so it was proprietary), and was part of libaudioflinger IIRC. It would manage the audio hw input stream, and hand out audio data to all clients (apps) that wanted to record audio. So it can be done if you have the ability to build your own Android ROM, but it's not trivial.