MediaRecorder problems on starting video capturing

2019-06-24 06:48发布

问题:

I'm trying to develop an App that amongst other things can record videos from its User. So I need to capture the video with the front facing camera if there is one. I build a camera preview and this works fine. I used the Android How-To Sites to build a MediaRecorder and set it up. If I use a CamcorderProfile my Media Server dies when I call start(). If I set up the encoder by myself the media server throws a runtime exception at start() with the message "start failed: -19" I found some questions about this topic here but none solved my problem. I think that this could be related to the fact that I'm not using the back-facing camera. Maybe I didn't found the right documentary to build the proper code. I think this isn't only my problem and I would be happy to get some more knowledge about the camera usage. My Code follows:

the onResume() where the preview is set up

protected void onResume() {
        super.onResume();
        // 1. set up camera preview
        if(checkCameraHardware(this)){
            mCamera = getCameraInstance();
            mCameraPreview = new CameraPreview(this, mCamera);
            FrameLayout preview = (FrameLayout) findViewById(id.cameraPreview);
            preview.addView(mCameraPreview);
        }
        else{
            Log.d("Recorder", "camera check returned false");
        }
}

the used method checkCameraHardware()

private boolean checkCameraHardware(Context context){
    boolean ret = true;
    if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
            ret = true;
    }
    else {
        ret = false;
        }
    return ret;
}

and the method getCameraInstance()

public static Camera getCameraInstance(){
    Camera c = null;
    int cnum = 0;
    mCamSelect = 0;
    Camera.CameraInfo caminfo = new CameraInfo();
    try {
        cnum = Camera.getNumberOfCameras();
        Log.d("getCameraInstance", String.valueOf(cnum));
        for(int i = 0;i<cnum;i++){
            Camera.getCameraInfo(i, caminfo);
            if(caminfo.facing == CameraInfo.CAMERA_FACING_FRONT){
                mCamSelect = i;
                break;
            }
        }
        c = Camera.open(mCamSelect); // attempt to get a Camera instance
    }
    catch (Exception e){
        Log.d("getCameraInstance", "FATAL camera could not be opened");
        // Camera is not available (in use or does not exist)
    }
    if(c==null)Log.d("getCameraInstance", "no camera returned");
    return c; // returns null if camera is unavailable
}

this code snippet shows where the error appears ( inside a onClick Callback )

if(prepareVideoRecorder()){
    mMediaRecorder.start(); //here the errors occure
    recording = true;
    //start recording
}

and the three MediaRecorder related methods: prepareVideoRecorder(), releaseMediaRecorder() and release Camera()

private void releaseMediaRecorder(){
        if (mMediaRecorder != null) {
            mMediaRecorder.reset();   // clear recorder configuration
            mMediaRecorder.release(); // release the recorder object
            mMediaRecorder = null;
            mCamera.lock();           // lock camera for later use
        }
    }

private void releaseCamera(){
    if (mCamera != null){
        mCamera.release();        // release the camera for other applications
        mCamera = null;
    }
}

private boolean prepareVideoRecorder(){

    //ex: mCamera = getCameraInstance();
    mMediaRecorder = new MediaRecorder();

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

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

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)


    CamcorderProfile profile = CamcorderProfile.get(mCamSelect, CamcorderProfile.QUALITY_HIGH);
    if(profile == null){Log.d(tag, "the camcorder profile instance is null");

        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    }else{
        mMediaRecorder.setProfile(profile);
    }



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

    // Step 5: Set the preview output
    mMediaRecorder.setPreviewDisplay(mSlideview.getHolder().getSurface());

    // Step 6: 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;
}

public void onGesturePerformed(GestureOverlayView arg0, Gesture arg1) {
    // TODO Auto-generated method stub

}

}

回答1:

I'm answering my own question to help everybody who has the same problem. The error was so stupid that it's a little embarrassing to admit it.

On preparing the audio and video sources I committed the wrong surface.

I have different SurfaceViews and committed the surface of the wrong SurfaceView to the MediaRecorder. This resulted in the attempt to connect two different sources to the surface what is not possible and leads to a shutdown of the Media Server.

I tested my App on a GalaxyPad 10.1 and the video recording works fine. I tested the App on the Dalvik VM and the Video is black/white but also works.

I hope this helps.



回答2:

Did you add the following permissions to your manifest?

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