【Camrea2录制视频报错问题修复java.lang.IllegalArgumentException: Surface was abandoned】

问题现象在这里插入图片描述
修改后的代码在机器正常

int recordTime = 10 * 60 * 1000 ;
        try {
            File vedioTempPath = new File(Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/video/temp/");
            if (!vedioTempPath.exists()) {
                vedioTempPath.mkdirs();
            }
            vedioTempPath = new File(storageDirectory + "/video/Camera2_INT_STR8/");
            if (!vedioTempPath.exists()) {
                vedioTempPath.mkdirs();
            }
            openCamera(cameraId);
            SystemClock.sleep(2000);
            //startPreview();
            startPreview_qcom();
            startRecordingVideo();
            SystemClock.sleep(recordTime);
            stopRecordingVideo();
            SystemClock.sleep(2000);
            stopPreview();
            releaseCamera();
            SystemClock.sleep(5000);

        } catch (Exception e) {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw, true));
            String str = sw.toString();
            Display.appendInfo(str);
            e.printStackTrace();
            fail(str);
        }

    /**
     * 开始录像
     */
    private void startRecordingVideo() {
//        mMediaRecorder = new MediaRecorder();
        if (null == mCameraDevice ) {
            return;
        }
        try {
            closePreviewSession();
            setUpMediaRecorder();
            Display.appendInfo("start recording Video\n");
            mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            List<Surface> surfaces = new ArrayList<>();
            Surface previewSurface = msurfaceHolder.getSurface();
            surfaces.add(previewSurface);
            mPreviewBuilder.addTarget(previewSurface);
            // Set up Surface for the MediaRecorder设置MediaRecorder的表面
            Surface recorderSurface = mMediaRecorder.getSurface();
            Log.d(TAG,recorderSurface.toString());
            surfaces.add(recorderSurface);
            Log.d(TAG,surfaces.toString());
            mPreviewBuilder.addTarget(recorderSurface);

            mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    mSession = cameraCaptureSession;
                    updatePreview();
                    activity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mIsRecordingVideo = true;
                            mMediaRecorder.start();
                            Display.appendInfo("start record\n");
                        }
                    });
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
                    Toast.makeText(activity, "配置失败", Toast.LENGTH_SHORT).show();
                    mSession = null;
                }
            }, mBackgroundHandler);
        } catch (CameraAccessException | IOException e) {
            e.printStackTrace();
        }

    }
  /**
     * 设置录像参数
     * @throws IOException
     */
    private void setUpMediaRecorder() throws IOException {
        if (mMediaRecorder == null) {
            mMediaRecorder = new MediaRecorder();
        }
        CamcorderProfile profile = CamcorderProfile
                .get(CamcorderProfile.QUALITY_480P);
        Log.d(TAG,"setUpMediaRecorder--setUpMediaRecorder");
//        mMediaRecorder.reset();
//        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);//设置音频源
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);//设置视频源: DEFAULT,Surface,Camera
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置视频输出格式: amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp
        mMediaRecorder.setOutputFile(storageDirectory+"/VID_"+cameraId+".mp4");
//        mMediaRecorder.setVideoEncodingBitRate(10000000);
        mMediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
        mMediaRecorder.setVideoFrameRate(30);
//        mMediaRecorder.setVideoSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        mMediaRecorder.setVideoSize(profile.videoFrameWidth,
                profile.videoFrameHeight);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mMediaRecorder.setPreviewDisplay(msurfaceHolder.getSurface());
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        switch (cOrientation) {
            case SENSOR_ORIENTATION_DEFAULT_DEGREES:
                mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
                break;
            case SENSOR_ORIENTATION_INVERSE_DEGREES:
                mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
                break;
        }
        mMediaRecorder.prepare();
        Log.d(TAG,"setUpMediaRecorder--prepare");
    }

补充mediaRecoder API
状态流转图
主要根据各个状态和触发的条件进行状态转换,图上是一个状态机的实现的说明已经足够了,不过值得注意的是还有两个状态函数是pause()【暂停】和resume()【恢复】录制功能,图上没有的

1、创建:new MediaRecorder();
2、设置Camera:mRecorder.setCamera();
3、设置音频源(采集方式):mRecorder.setAudioSource();
4、设置视频源(采集方式):mRecorder.setVideoSource();
5、设置文件的输出格式:mRecorder.setOutputFormat();
6、设置Audio的编码格式(生成对应的编码器):mRecorder.setAudioEncoder();
7、设置Video的编码格式(生成对应的编码器):mRecorder.setVideoEncoder();
8、设置录制的视频编码比特率(每秒编码多少位bit):mRecorder.setVideoEncodingBitRate();
9、设置录制的视频帧率:mRecorder.setVideoFrameRate();
10、设置要捕获的视频的宽度和高度:mRecorder.setVideoSize();
11、设置记录会话的最大持续时间(毫秒):mRecorder.setMaxDuration();
12、设置一个Surface进行预览显示:mRecorder.setPreviewDisplay();
13、设置输出文件路径:mRecorder.setOutputFile();
14、准备录制:mRecorder.prepare();
15、开始录制:mRecorder.start();
16、暂停或恢复录制:mRecorder.pause()/resume();
17、停止录制:mRecorder.stop();
18、重置Recorder:mRecorder.reset();
19、释放Recorder资源:mRecorder.release();

另一个camera2 stopRecordingVideo问题java.lang.IllegalStateException
在这里插入图片描述


    private void stopRecordingVideo() {
        mIsRecordingVideo = false;
        /**
         *  添加这两句  可以解决stop时闪退问题
         */
        Display.appendInfo("stop record\n");
        try {
            if(mSession!=null) {
                mSession.stopRepeating();
                mSession.abortCaptures();
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        // Stop recording
        try {
            mMediaRecorder.stop();
        } catch (IllegalStateException e) {
            // TODO 如果当前java状态和jni里面的状态不一致,
            mMediaRecorder = null;
            mMediaRecorder = new MediaRecorder();
        }
        mMediaRecorder.reset();
        mMediaRecorder.release();
        mMediaRecorder = null;
        startPreview();
    }

    public void stopPreview() {
        if (mSession == null || mPreviewBuilder == null) {
            return;
        }
        if (mSession != null){
            try {
                mSession.stopRepeating();
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

    }
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值