3

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()

Joshua Ohana
  • 5,613
  • 12
  • 56
  • 112
  • I just took a look at my code and I configure a couple more things than you. But I think the main differences are `mediaRecorder.setVideoSize(int width, int height)` and `mediaRecorder.setPreviewDisplay(SurfaceHolder surfaceHolder)`. Maybe setting one of them may help to get it working. BTW, could you paste your stack trace? – Edson Menegatti Sep 22 '15 at 12:18
  • @EdsonMenegatti Thanks for the reply... I am not using a preview window so I don't think I need those calls, but I will try adding setVideoSize to see if that might clear things up. I will post up the full stack trace later on today – Joshua Ohana Sep 22 '15 at 12:52
  • Does this mean you're not showing any preview of the camera at all? – Edson Menegatti Sep 23 '15 at 12:10
  • @EdsonMenegatti That is correct. For my purposes I want to record video but not show a preview window. The basic piece I'm working through now is just a start/stop record button and save the video file somewhere... still surprised it's proving this troublesome! – Joshua Ohana Sep 23 '15 at 13:17
  • Unfortunately you can't do that. In Android it is mandatory to present the camera preview if you want to record. It is implemented that way to prevent hidden camera apps. There's plenty of related questions in SO, but take a look at this link http://stackoverflow.com/questions/2386025/taking-picture-from-camera-without-preview – Edson Menegatti Sep 23 '15 at 13:22
  • @EdsonMenegatti According to the Android Camera tutorial at https://developer.android.com/guide/topics/media/camera.html#capture-video that's not true. At the bottom of the Capture Video section it says "Note: It is possible to use MediaRecorder without creating a camera preview first and skip the first few steps of this process. However, since users typically prefer to see a preview before starting a recording, that process is not discussed here." – Joshua Ohana Sep 23 '15 at 13:51
  • That being said, I will try it with a 1x1 preview per the link you provided. Thank you much – Joshua Ohana Sep 23 '15 at 13:52
  • @EdsonMenegatti After some finagling it worked! Thanks so much... though it really bothers me the official Guide says we don't need one even though we do :-\ Please post your comment as an answer and I'll be happy to accept it. – Joshua Ohana Sep 25 '15 at 14:49
  • Just created the answer. Glad that I was able to help. – Edson Menegatti Sep 25 '15 at 17:26

2 Answers2

3

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.

Community
  • 1
  • 1
Edson Menegatti
  • 4,006
  • 2
  • 25
  • 40
  • Thanks @Edson turns out I wasn't including a preview, which caused the failure. Following the guide linked in my question I added the preview class and attached the surfaceview, solved my issue. – Joshua Ohana Sep 25 '15 at 19:45
0

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

Gv Ravi
  • 333
  • 2
  • 5