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 ブロックを使用してビデオ カメラをシャットダウンし、別の解像度で再起動します。これは s のサポートが強化されているため、Android の将来のバージョンでは大きな問題にはならない可能性がありますがCamcorderProfile、現在のところ、利用可能なビデオ解像度を正確に共有していないデバイスが多数あります。

initializeVideoRecorderアクティビティから fnを呼び出し、作成した 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 に答える