Camera2的简单使用

参考资料 GoogleDemo
整个使用流程梳理
Camera2的简单使用_第1张图片

1 初始化CameraManager对象

CameraManager对象是相机调用的发起对象,

CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

通过此对象可以拿到可用的设备id,和设备id对应的一系列属性等。

2 初始化CameraCharacteristics对象

通过CameraCharacteristics对象可以拿到设备属性的配置集合Map

// 初始化摄像头设备id的属性
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);

// 获取到摄像头设备属性支持的配置,比如可以获取到所支持的所有窗口大小组合
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

通过此Map可以用来匹配合适的VideoSize即视频的尺寸,还可以用来匹配合适的预览控件的大小即PreviewSize。PreViewSize用来设置TextureView的大小。

3 打开摄像头

通过CameraManager的openCamera()方法打开摄像头。

cameraManager.openCamera(cameraId, mStateCallback, null);

在此方法中的参数为 CameraDevice.StateCallback callback

private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) {
           
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
           
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
           
        }
    };                                                                              

CameraDevice.StateCallback callback简单的说明:
根据回调方法名字可知,当摄像头正常开启时,会回调onOpened方法。并会在参数中返回CameraDevice对象。

@Override
        public void onOpened(@NonNull CameraDevice camera) {
            mCameraDevice = camera;
        }

4 获取CameraCaptureSession

  • 首先获取用于显示视频画面的TextureView对象的SurfaceTexture对象。
SurfaceTexture texture = mTextureView.getSurfaceTexture();
  • 用SurfaceTexture来构建Surface对象
Surface previewSurface = new Surface(texture);
  • 构建用于显示的CaptureRequest.Builder对象
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewBuilder.addTarget(previewSurface);

此处的CaptureRequest.Builder跟创建CameraCaptureSession对象无关,目的只是和previewSurface对象相关联,用于抓取帧数据。

  • 通过CameraDevice对象的的createCaptureSession方法创建用于获取视频数据的CameraCaptureSession。
mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface), previewSessionStateCallback, mBackGroundHandler);

在此方法中会传入CameraCaptureSession.StateCallback对象,
在此对象的回调方法onConfigured()中,会返回创建好的CameraCaptureSession对象。

private CameraCaptureSession.StateCallback previewSessionStateCallback = new CameraCaptureSession.StateCallback() {

        @Override
        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
            mPreviewSession = cameraCaptureSession;
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
    
        }
    };

5 开始预览画面

设置3A控制(auto-exposure, auto-white-balance, auto-focus)

mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

开始不断的获取图像数据

mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackGroundHandler);

至此预览画面可以正常显示

6 录制

1 初始化MediaRecorder对象

MediaRecorder使用来录制音视频数据的对象,可以设置一系列的参数,来控制录制音视频的参数。

MediaRecorder  mMediaRecorder = new MediaRecorder();

例如:
设置音频和视频的来源,输出格式,输出文件路径,视频编码率,视频帧率, 视频大小, 视频编码格式,音频编码格式等。

mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
if (mNextVideoAbsolutePath == null || mNextVideoAbsolutePath.isEmpty()) {
mNextVideoAbsolutePath = getVideoFilePath();
}
mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
int rotation = getWindowManager().getDefaultDisplay().getRotation();

2 获取CameraCaptureSession

接下来的步骤和第四步骤相似,都是获取CameraCaptureSession,之前的CameraCaptureSession是用来预览的,而此处的获取CameraCaptureSession使用来预览和录制的。

有以下区别

  • CaptureRequest.Builder的Target添加来自MediaRecorder的Surface
Surface recorderSurface = mMediaRecorder.getSurface();
mPreviewBuilder.addTarget(recorderSurface);
  • 在获取到CameraCaptureSession对象的回调方法中,开始执行录制
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession){
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
        mMediaRecorder.start();
        }
    });
}

至此,便可以成功预览和录制。

源码地址

你可能感兴趣的:(音视频)