Joshua Ohana
Joshua Ohana

Reputation: 6121

Android video recording - IllegalStateException on mediaRecorder.start

I am following the tutorial on https://developer.android.com/guide/topics/media/camera.html#capture-video

As such I follow the below order when trying to start the camera:

  1. Camera.open
  2. camera.unlock
  3. mediaRecorder.setCamera
  4. mediaRecorder.setAudioSource
  5. mediaRecorder.setVideoSource
  6. mediaRecorder.setProfile
  7. mediaRecorder.setOutputFile
  8. mediaRecorder.prepare
  9. mediaRecorder.start <- this is where I get the IllegalStateException

I can figure out what could be going wrong since I'm following the guide, running 5.0.2

private Camera mCamera;
private MediaRecorder mMediaRecorder;

public CameraActivity() {
    mCamera = getCameraInstance();
    mMediaRecorder = new MediaRecorder();
}

public static Camera getCameraInstance(){
    Camera c = null;
    try {
        c = Camera.open();
    }
    catch (Exception e) { ... }
    return c;
}

public void startRecording() {

    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    try {
        mMediaRecorder.prepare();
    }
    catch (IOException e) { ... }
    catch (IllegalStateException e) { ... }

    try {
        mMediaRecorder.start();
    }
    catch (Exception e) {
        Log.d(TAG, "exception on mediaRecorder.start" + e.toString()); // This is the exception that gets thrown on .start
    }
}

My manifest includes all necessary permissions

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

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.microphone" />

I have also tried manually setting format instead of using .setProfile, same results

    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);

Update

The file is indeed created, though it's unplayable of course, so I know it's working up to that point. The call to prepare does not throw an exception, and occurs before start. Same exception thrown on start()

Upvotes: 3

Views: 2441

Answers (2)

Gv Ravi
Gv Ravi

Reputation: 391

If you are accessing mic hardware multiple times, like, using MediaRecorder and AudioRecord classes at a time will also make this exception.

Upvotes: 0

Edson Menegatti
Edson Menegatti

Reputation: 4036

Comparing agains my code, it seems you're missing two calls:

mediaRecorder.setVideoSize(int width, int height)
mediaRecorder.setPreviewDisplay(SurfaceHolder surfaceHolder)

The latter is most likely to be causing the crash as Android requires a valid preview surface to start recording. This is done so to prevent hidden cameras apps.

There are dozens of questions related to recording without a preview surface, but this one seems to sum up what you need to do to bypass this restriction. The basic idea is to resize your surface to be 1x1 and pass it to your mediaRecorder instance. Keep in mind that this may not work in all devices though.

Upvotes: 3

Related Questions