Camera2 API Video 录像过程

在之前的文章已经详细讲解过关于Camera的Open整个过程,下面我们在来说说Video的过程:
还记得CameraDevice类吗?CameraDevice的reateCaptureRequest(int templateType)方法创建CaptureRequest.Builder。
templateType参数有以下几种:

  • TEMPLATE_PREVIEW :预览
  • TEMPLATE_RECORD:拍摄视频
  • TEMPLATE_STILL_CAPTURE:拍照
  • TEMPLATE_VIDEO_SNAPSHOT:创建视视频录制时截屏的请求
  • TEMPLATE_ZERO_SHUTTER_LAG:创建一个适用于零快门延迟的请求。在不影响预览帧率的情况下最大化图像质量。
  • TEMPLATE_MANUAL:创建一个基本捕获请求,这种请求中所有的自动控制都是禁用的(自动曝光,自动白平衡、自动焦点)。

当然,视频得选择templateType = TEMPLATE_RECORD

录像是长时间的动作,录像过程中需要重复性的刷新录制界面。其余的步骤和拍照动作基本类似。

 /**
   * 开始视频录制。
   */
private void startRecordingVideo() {
    try {
            //创建录制的session会话中的请求
            mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);

            //设置录制参数,这里省略
            .........

            // Start a capture session
            // Once the session starts, we can update the UI and start recording
            mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {

                     mPreviewSession = cameraCaptureSession;
                     Log.i(TAG, " startRecordingVideo  正式开始录制 ");
                     updatePreview();
                }
                //该接口的方法,部分省略
                .............

            }, workThreadManager.getBackgroundHandler());
        } catch (CameraAccessException | IOException e) {
            e.printStackTrace();
        }
}

//录制过程中,不断刷新录制界面
private void updatePreview() {

        try {
            mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, workThreadManager.getBackgroundHandler());
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
}

和拍照类似,将视频数据写入磁盘文件中,也是需要一个操作类 MediaRecorder来实现的。

先是创建该操作类对象,设置一些列参数:

   /**
     * MediaRecorder
     */
private MediaRecorder mMediaRecorder;

 /**
     * 设置媒体录制器的配置参数
     * <p>
     * 音频,视频格式,文件路径,频率,编码格式等等
     *
     * @throws IOException
     */
    private void setUpMediaRecorder() throws IOException {
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mNextVideoAbsolutePath = FileUtils.createVideoDiskFile(appContext, FileUtils.createVideoFileName()).getAbsolutePath();
        mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
        mMediaRecorder.setVideoEncodingBitRate(10000000);
        //每秒30帧
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        switch (mSensorOrientation) {
            case SENSOR_ORIENTATION_DEFAULT_DEGREES:
                mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
                break;
            case SENSOR_ORIENTATION_INVERSE_DEGREES:
                mMediaRecorder.setOrientationHint(ORIENTATIONS.get(rotation));
                break;
            default:
                break;
        }
        mMediaRecorder.prepare();
    }

间隔性的随着视频录制而输出数据到文件中。

// 为 MediaRecorder设置Surface
Surface recorderSurface = mMediaRecorder.getSurface();
surfaces.add(recorderSurface);
mPreviewBuilder.addTarget(recorderSurface);

最后,当录制视频结束后,停止输出:

 // 停止录制
 mMediaRecorder.stop();
 mMediaRecorder.reset();

完成一些列拍照或录像动作后,重新恢复到预览界面。

/**
  * 完成一些列拍照或录像动作后,释放焦点。
  */
private void unlockFocus() {
   try {
         //向session重新发送,预览的间隔性请求,出现预览界面。
         mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, workThreadManager.getBackgroundHandler());
    } catch (CameraAccessException e) {
            e.printStackTrace();
    }
}

你可能感兴趣的:(Camera)