Search code examples
androidruntimeexceptionmediarecorderandroid-mediarecorder

MediaRecorder Error: setAudioSource in invalid state(4)


I've been trying to get a custom camera screen to work, but for some reason the following code does not seem to work. I end up with a RuntimeException, caused by an error that says: setAudioSource called in an invalid state(4).

The following is the code in question:

 Preview.getRecorderInstance().setVideoSource(MediaRecorder.VideoSource.CAMERA);
 Preview.getRecorderInstance().setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
 Preview.getRecorderInstance().setAudioSource(MediaRecorder.AudioSource.MIC);
 Preview.getRecorderInstance().setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
 Preview.getRecorderInstance().setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);

 Preview.getRecorderInstance().setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()
                            + "/test" + System.currentTimeMillis() + ".mp4"
                    );


 Preview.getRecorderInstance().prepare();
 Preview.getRecorderInstance().start();

Preview.getRecorderInstance() gets the singleton media recorder tied to the Preview class (which is a subclass of SurfaceView designed to display the camera preview).

My permissions: <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

I'd appreciate any help with this, as I'm not getting anywhere in this endeavor, and I've looked at similar questions on stackoverflow. I wasn't able to fix the problem after reading the responses.


Solution

  • The required ordering of the statements to configure the MediaRecorder is tricky. The documentation states that setAudioSource() must be called before setOutputFormat(). Flip the order of the statements to be like this:

     Preview.getRecorderInstance().setAudioSource(MediaRecorder.AudioSource.MIC);
     Preview.getRecorderInstance().setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);