заключване на камерата неуспешно изключение при повторно създаване на медиен рекордер android

Правя видеозапис с медиен рекордер.

За това използвах кода по-долу.

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

В горния код, когато се извика слушател на грешки в медийно записващо устройство, аз пресъздавам медийно записващо устройство с друг размер на видеото, но докато правя това, получавам изключение при заключване на камерата.

как мога да разреша това?


person koti    schedule 22.01.2013    source източник


Отговори (1)


Това е начинът, по който се справям с проблема с опита да използвам определени размери за видеозапис, които могат или не могат да бъдат налични на различни устройства. Започвам, като се опитвам да записвам с идеална разделителна способност и използвам блокове try-catch за да изключите и опитате отново да отворите видеокамерата при различна резолюция. Това вероятно няма да е сериозен проблем с бъдещите версии на android поради увеличената поддръжка за CamcorderProfiles, но към момента има много устройства, които просто не споделят точно наличните видео разделителни способности.

Извиквам 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();
    }
person Daniel Smith    schedule 24.01.2013
comment
+1 За частен статичен окончателен PreviewSize PRE_ICS_DEFAULT_FRONT_VIDEO_SIZE = нов PreviewSize(480, 640); - person gurkan; 26.07.2013