重新创建媒体记录器android时,相机锁失败异常

时间:2013-01-22 06:42:58

标签: android android-camera android-mediarecorder

我正在使用媒体录像机进行视频录制。

对于我使用下面的代码。

private void prepareMediaRecorder(boolean vsize) {
        mrec = new MediaRecorder();
        mrec.setOnErrorListener(new OnErrorListener() {

            @Override
            public void onError(MediaRecorder mr, int what, int extra) {
                // TODO Auto-generated method stub
                if (extra == -1007)
                {
                    prepareMediaRecorder(false);
                }
                else
                {
                unableToRecord();
                }
            }
        });

        camera.lock();
        camera.unlock();
        mrec.setCamera(camera);
        mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
        mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mrec.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        if (vsize)
            mrec.setVideoSize(getMaxSupportedVideoSize().width,
                    getMaxSupportedVideoSize().height);
        else
        mrec.setVideoSize(640, 480);

        mrec.setOutputFile(path + filename);
        mrec.setMaxDuration(30000);
        mrec.setPreviewDisplay(surfaceHolder.getSurface());

        if (!onlyback
                && currentapiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {
            if (open_camera == 1)
                mrec.setOrientationHint(270);
            else
                mrec.setOrientationHint(90);
        } else if (currentapiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {
            mrec.setOrientationHint(90);
        }
        try {
            mrec.prepare();
            mrec.start();


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在上面的代码中,当媒体记录器错误监听器调用我正在重新创建具有其他视频大小的媒体记录器但在执行此操作时我得到了摄像机锁异常。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

这就是我如何解决尝试使用某些视频录制尺寸的问题,这些视频录制尺寸可能会在不同的设备上提供,也可能不会。我首先尝试使用理想的分辨率进行录制,然后使用try -catch块,以便以不同的分辨率关闭并重试打开摄像机。 由于对CamcorderProfile的支持增加,这可能不会成为未来Android版本的一个大问题,但截至目前,有许多设备根本无法准确地共享可用的视频分辨率。

我从一个活动中调用initializeVideoRecorder fn,并使用我创建的一个名为PreviewSize的自定义类,它基本上只是整齐地打包的宽度和高度。我在上面定义了这些常量PreviewSize

我认为重要的是在尝试连接到不同的预览尺寸之前释放所有内容并重试。我使用releaseVideoCamera函数执行此操作。您还在lock之前致电unlock,这似乎可能存在问题(可能不会)。

无论如何,这是我的代码。我删除了一些部分,遗漏了与您的需求无关的某些功能:

/**Standard 720p video size (1280x720) for both front and back.*/
private static final PreviewSize DEFAULT_VIDEO_SIZE = new PreviewSize(720, 1280);
/**Fallback 480p video size (720x480) for back cameras that don't support 720p */
private static final PreviewSize BACKUP_VIDEO_SIZE = new PreviewSize(480, 720);
/** Default pre-ICS front facing camera size (a version of 480p) */
private static final PreviewSize PRE_ICS_DEFAULT_FRONT_VIDEO_SIZE = new PreviewSize(480, 640);

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public boolean initializeVideoRecorder(){

        if (! externalStorageAvailable()) return false;

        mCamera.stopPreview();

        if (ApiHelper.PRE_ICS && mCameraSide == CameraUtils.FRONT_FACING_CAMERA){
            return initializeVideoRecorderWithoutCamcorderProfile(PRE_ICS_DEFAULT_FRONT_VIDEO_SIZE);
        } else return initializeVideoRecorderWithoutCamcorderProfile(DEFAULT_VIDEO_SIZE);

    }

    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    private boolean initializeVideoRecorder(PreviewSize videoSize){
        mCamera.unlock();
        mVideoRecorder = new MediaRecorder();
        mVideoRecorder.setCamera(mCamera);
        mVideoRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mVideoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        CamcorderProfile dummyCamcorderProfile;
        if (Build.VERSION.SDK_INT > 8) dummyCamcorderProfile = CamcorderProfile.get(mCameraSide, CamcorderProfile.QUALITY_HIGH);
        else dummyCamcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);

        customSetProfile(dummyCamcorderProfile);

        mVideoRecorder.setVideoSize(videoSize.height, videoSize.width);

            //Set the orientation hint here if need be... i left that code out

        mVideoFile = someFunctionThatGivesYouAVideoFile();
        mVideoRecorder.setOutputFile(mVideoFile.toString());
        mVideoRecorder.setPreviewDisplay(yourCameraSurface);

        try {
            mVideoRecorder.prepare();
        } catch (IllegalStateException e) {
            releaseVideoCamera();
            return false;
        } catch (IOException e) {
            Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
            releaseVideoCamera();
            return false;
        }

        try {
            mVideoRecorder.start();
        } catch (RuntimeException e) {
            releaseVideoCamera();
            if (videoSize.equals(DEFAULT_VIDEO_SIZE)) {
                if (mCameraSide == CameraUtils.BACK_FACING_CAMERA) return initializeVideoRecorder(BACKUP_VIDEO_SIZE);
                else return initializeVideoRecorder(PRE_ICS_DEFAULT_FRONT_VIDEO_SIZE);
            }
            else return false;
        }

        return true;
    }

  public void customSetProfile(CamcorderProfile profile) {
        mVideoRecorder.setOutputFormat(profile.fileFormat);
        mVideoRecorder.setVideoFrameRate(profile.videoFrameRate);
        mVideoRecorder.setVideoEncoder(profile.videoCodec);
        mVideoRecorder.setVideoEncodingBitRate(1000000);
        mVideoRecorder.setAudioEncodingBitRate(profile.audioBitRate);
        mVideoRecorder.setAudioChannels(profile.audioChannels);
        mVideoRecorder.setAudioSamplingRate(profile.audioSampleRate);
        mVideoRecorder.setAudioEncoder(profile.audioCodec);
    }

  public void releaseVideoCamera(){
        mVideoRecorder.reset();
        mVideoRecorder.release();
        mVideoRecorder = null;
        try {
            mCamera.reconnect();
        } catch (IOException e) {
                // TODO: handle this exception...
        }
        mCamera.lock();
    }