CameraManager对象是相机调用的发起对象,
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
通过此对象可以拿到可用的设备id,和设备id对应的一系列属性等。
通过CameraCharacteristics对象可以拿到设备属性的配置集合Map
// 初始化摄像头设备id的属性
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
// 获取到摄像头设备属性支持的配置,比如可以获取到所支持的所有窗口大小组合
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
通过此Map可以用来匹配合适的VideoSize即视频的尺寸,还可以用来匹配合适的预览控件的大小即PreviewSize。PreViewSize用来设置TextureView的大小。
通过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;
}
SurfaceTexture texture = mTextureView.getSurfaceTexture();
Surface previewSurface = new Surface(texture);
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewBuilder.addTarget(previewSurface);
此处的CaptureRequest.Builder跟创建CameraCaptureSession对象无关,目的只是和previewSurface对象相关联,用于抓取帧数据。
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) {
}
};
设置3A控制(auto-exposure, auto-white-balance, auto-focus)
mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
开始不断的获取图像数据
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, mBackGroundHandler);
至此预览画面可以正常显示
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();
接下来的步骤和第四步骤相似,都是获取CameraCaptureSession,之前的CameraCaptureSession是用来预览的,而此处的获取CameraCaptureSession使用来预览和录制的。
有以下区别
Surface recorderSurface = mMediaRecorder.getSurface();
mPreviewBuilder.addTarget(recorderSurface);
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession){
runOnUiThread(new Runnable() {
@Override
public void run() {
mMediaRecorder.start();
}
});
}
至此,便可以成功预览和录制。
源码地址