1

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

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

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

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

我该如何解决这个问题?

4

1 回答 1

2

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

我从一个活动中调用initializeVideoRecorderfn 并使用我创建的一个名为 a 的自定义类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();
    }
于 2013-01-24T19:31:58.950 回答