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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章