Android MediaRecorder Crashes

1.4k views Asked by At

UPDATED:

Ok, after a few days of testing and debugging... I GOT IT TO WORK, but not the way I want.

The reason it crashed previously was because of "reorientation" of the camera during lockscreen, apparently, that crashes often.

Once I forced it to use landscape mode, it works. However, I don't want it to use landscape mode; I want it to work in portrait mode.

The code is taken directly from Android Studio's sample (Media -> MediaRecorder). The sample had the code working in landscape mode, and I can't figure how to get it to use portrait mode so I can avoid re-orientation and thus avoid the crashes?

There's nothing in the onPause, onResume code and the stacktrace pointed toward this method being called.

Easy Reproduce:

1) Use Android Studio to get the MediaRecord Sample app 2) In the manifest, change, android:screenOrientation="landscape"> to Portrait. 3) The App won't launch now.

I added mCamera.setDisplayOrientation(90), same issue.

Code:

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private boolean prepareVideoRecorder(){

    // BEGIN_INCLUDE (configure_preview)
    mCamera = CameraHelper.getDefaultCameraInstance();

    // We need to make sure that our preview and recording video size are supported by the
    // camera. Query camera to find all the sizes and choose the optimal size given the
    // dimensions of our preview surface.
    Camera.Parameters parameters = mCamera.getParameters();
    List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
    Camera.Size optimalSize = CameraHelper.getOptimalPreviewSize(mSupportedPreviewSizes,
            mPreview.getWidth(), mPreview.getHeight());

    // Use the same size for recording profile.
    CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
    profile.videoFrameWidth = optimalSize.width;
    profile.videoFrameHeight = optimalSize.height;

    // likewise for the camera object itself.
    parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
    mCamera.setParameters(parameters);
    try {
            // Requires API level 11+, For backward compatibility use {@link setPreviewDisplay}
            // with {@link SurfaceView}
            mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
    } catch (IOException e) {
        Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
        return false;
    }
    // END_INCLUDE (configure_preview)

    // BEGIN_INCLUDE (configure_media_recorder)
    mMediaRecorder = new MediaRecorder();

    // Step 1: Unlock and set camera to MediaRecorder
    mCamera.unlock();
    mMediaRecorder.setCamera(mCamera);

    // Step 2: Set sources
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    mMediaRecorder.setProfile(profile);

    // Step 4: Set output file
    mMediaRecorder.setOutputFile(CameraHelper.getOutputMediaFile(
            CameraHelper.MEDIA_TYPE_VIDEO).toString());

    mMediaRecorder.setOrientationHint(90);
    // END_INCLUDE (configure_media_recorder)

    MediaScannerConnection.scanFile(this, new String[] { CameraHelper.getOutputMediaFile(
            CameraHelper.MEDIA_TYPE_VIDEO).getPath() }, new String[] { "video/mp4" }, null);
    // Step 5: Prepare configured MediaRecorder
    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
        releaseMediaRecorder();
        return false;
    }
    return true;
}

Logs:

06-27 02:18:08.244  25734-25752/com.watchdawg.watchdawg E/MediaRecorder﹕ start failed: -22
06-27 02:18:08.253  25734-25752/com.watchdawg.watchdawg E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: com.watchdawg.watchdawg, PID: 25734
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.RuntimeException: start failed.
at android.media.MediaRecorder.start(Native Method)
at com.watchdawg.watchdawg.RecordActivity$MediaPrepareTask.doInBackground(RecordActivity.java:276)
at com.watchdawg.watchdawg.RecordActivity$MediaPrepareTask.doInBackground(RecordActivity.java:267)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
2

There are 2 answers

4
siva On

Whenever the application is removed from the recent task list, process will not be cleaned up completely, it is just that the UI will be cleaned up. So it is app responsibility to cleanup the resource held by your activity or app. Hence, you need to override onTaskRemoved() method in your service(Android service) component and perform cleanup(releasing mediaplayer instance etc).

0
sien On

try this way:

 mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoFrameRate(24);
    mMediaRecorder.setVideoSize(720,480);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mPreview.setRotation(90);

instead of mMediaRecorder.setProfile(profile); hope it works!