2、Android Camera2 API 架构:CameraManager、CameraDevice、CameraCaptureSession、CaptureRequest 详解
Camera2 API 是 Android 5.0(API 21)引入的、用于替代已废弃的 Camera1 API 的现代相机框架。它采用管道(Pipeline)架构,将相机设备抽象为一系列可配置的捕获请求与结果流。理解其核心组件是进行音视频采集的基础。
2.1 CameraManager:系统相机服务的管理者
CameraManager 是应用与系统相机服务交互的入口。它负责枚举、查询和连接相机设备。
- 获取实例:通过
Context.getSystemService(Context.CAMERA_SERVICE)获取。 - 核心职责:
- 枚举相机:
getCameraIdList()返回所有可用相机的 ID 列表(通常包含后置、前置等)。 - 查询特性:
getCameraCharacteristics(String cameraId)返回CameraCharacteristics对象,包含该相机的所有静态属性,如:SCALER_STREAM_CONFIGURATION_MAP:支持的输出尺寸、格式(YUV_420_888、NV21、JPEG 等)。FLASH_INFO_AVAILABLE:是否支持闪光灯。LENS_FACING:相机朝向(前置/后置)。SENSOR_ORIENTATION:传感器方向(用于旋转预览画面)。
- 打开相机:
openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)异步打开指定相机。
- 枚举相机:
// 示例:获取 CameraManager 并查询后置相机
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {
String[] cameraIds = manager.getCameraIdList();
for (String id : cameraIds) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
// 找到后置相机,准备打开
manager.openCamera(id, stateCallback, backgroundHandler);
break;
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
2.2 CameraDevice:相机硬件的抽象代理
CameraDevice 代表一个物理或逻辑相机设备。一旦通过 CameraManager.openCamera() 成功打开,系统会通过 CameraDevice.StateCallback 回调返回该实例。
- 状态回调:
onOpened(CameraDevice camera):相机成功打开,此时可以创建CameraCaptureSession。onDisconnected(CameraDevice camera):相机断开连接(如被其他应用抢占)。onError(CameraDevice camera, int error):发生错误。
- 核心方法:
createCaptureSession(SessionConfiguration config):创建捕获会话(推荐方式,API 23+)。createCaptureRequest(int templateType):创建CaptureRequest.Builder,模板类型包括:TEMPLATE_PREVIEW:预览模式,高帧率。TEMPLATE_RECORD:视频录制模式,稳定帧率。TEMPLATE_STILL_CAPTURE:拍照模式,高质量。TEMPLATE_VIDEO_SNAPSHOT:录制时拍照。TEMPLATE_MANUAL:手动模式,完全控制参数。
// 示例:CameraDevice.StateCallback 实现
private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
cameraDevice = camera;
// 相机已打开,可以创建会话
createCameraPreviewSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
cameraDevice.close();
cameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
cameraDevice.close();
cameraDevice = null;
}
};
2.3 CameraCaptureSession:捕获请求的会话管道
CameraCaptureSession 是相机设备与输出目标(如 Surface)之间的桥梁。它负责接收 CaptureRequest,并将其发送到相机硬件进行处理,最终将数据输出到指定的 Surface。
- 创建会话:通过
CameraDevice.createCaptureSession()创建,需要提供一组输出Surface(例如:用于预览的SurfaceView的 Surface,用于录制的MediaCodec的 Surface,用于拍照的ImageReader的 Surface)。 - 状态回调:
CameraCaptureSession.StateCallback:onConfigured(CameraCaptureSession session):会话配置成功,可以开始发送请求。onConfigureFailed(CameraCaptureSession session):配置失败。
- 核心方法:
setRepeatingRequest(CaptureRequest request, CameraCaptureSession.CaptureCallback callback, Handler handler):发起持续重复的请求(如预览、视频流)。capture(CaptureRequest request, CameraCaptureSession.CaptureCallback callback, Handler handler):发起单次请求(如拍照)。abortCaptures():中止当前所有待处理的请求。
// 示例:创建预览会话
private void createCameraPreviewSession() {
try {
// 假设 previewSurface 是 SurfaceView 的 Surface
List<Surface> outputs = new ArrayList<>();
outputs.add(previewSurface);
cameraDevice.createCaptureSession(outputs, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
captureSession = session;
// 创建预览请求
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(previewSurface);
// 设置自动对焦模式
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 开始重复请求
captureSession.setRepeatingRequest(builder.build(), null, backgroundHandler);
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
// 处理失败
}
}, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
2.4 CaptureRequest:一次捕获的完整配置
CaptureRequest 定义了相机在一次捕获中需要执行的所有参数和目标。它由 CaptureRequest.Builder 构建。
- 核心组成:
- 目标 Surface:通过
addTarget(Surface)添加,指定数据输出到哪里。一个请求可以同时输出到多个 Surface(例如:同时输出预览和录制)。 - 捕获参数:通过
set(CaptureRequest.Key<T> key, T value)设置,常用参数包括:CONTROL_AF_MODE:对焦模式(自动、连续、手动)。CONTROL_AE_MODE:自动曝光模式。CONTROL_AWB_MODE:白平衡模式。FLASH_MODE:闪光灯模式。SENSOR_EXPOSURE_TIME:曝光时间(手动模式)。SENSOR_SENSITIVITY:ISO 感光度(手动模式)。JPEG_QUALITY:JPEG 压缩质量。
- 目标 Surface:通过
- 请求类型:
- 重复请求:通过
setRepeatingRequest()提交,相机将持续按此配置捕获帧,直到被新的重复请求替换或会话关闭。适用于预览和视频流。 - 单次请求:通过
capture()提交,只执行一次捕获。适用于拍照。
- 重复请求:通过
// 示例:构建一个拍照请求
private void captureStillPicture() {
try {
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
builder.addTarget(imageReader.getSurface()); // ImageReader 用于获取 JPEG 数据
// 设置自动对焦锁定
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 设置闪光灯自动
builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_AUTO);
// 设置 JPEG 质量
builder.set(CaptureRequest.JPEG_QUALITY, (byte) 95);
// 发送单次请求
captureSession.capture(builder.build(), new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
// 拍照完成,可以处理 ImageReader 中的图片数据
}
}, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
2.5 组件协作流程总结
整个 Camera2 的工作流程可以概括为以下步骤:
- 获取 CameraManager:通过系统服务获取。
- 查询并打开 CameraDevice:使用
CameraManager.openCamera()异步打开。 - 准备输出 Surface:创建
SurfaceView、TextureView、ImageReader或MediaCodec的 Surface。 - 创建 CameraCaptureSession:将输出 Surface 列表传入
CameraDevice.createCaptureSession()。 - 构建 CaptureRequest:根据需求(预览/录制/拍照)创建
CaptureRequest.Builder,设置参数并添加目标 Surface。 - 提交请求:调用
setRepeatingRequest()或capture()开始数据流。 - 处理结果:通过
CaptureCallback获取捕获元数据,通过ImageReader或Surface获取图像数据。
理解这四个核心组件的职责与协作关系,是掌握 Camera2 API 的关键。后续章节将基于此架构,深入讲解预览、拍照、视频录制以及编码的具体实现。