【问题标题】:camera lock failed exception while recreating media recorder android重新创建媒体记录器android时相机锁定失败异常
【发布时间】:2013-01-22 06:42:58
【问题描述】:

我正在使用媒体记录器进行视频录制。

为此,我使用了下面的代码。

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

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

我该如何解决这个问题?

【问题讨论】:

    标签: android android-camera android-mediarecorder


    【解决方案1】:

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

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

    我认为重要的是在尝试连接到不同的预览大小之前释放所有内容并重试。我使用releaseVideoCamera 函数来做到这一点。您还在unlock 之前调用lock,这似乎可能有问题(也许不是)。

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

    /**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();
        }
    

    【讨论】:

    • +1 对于私有静态最终 PreviewSize PRE_ICS_DEFAULT_FRONT_VIDEO_SIZE = new PreviewSize(480, 640);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    相关资源
    最近更新 更多