Android应用CameraConstrainedHighSpeedCaptureSession预览帧捕获分析问题求助
问题描述
开发Android应用时,需要基于CameraConstrainedHighSpeedCaptureSession录制120FPS视频,同时对预览画面做30FPS的实时逐帧分析。曾尝试CameraX,但无法配置120FPS录制,转而使用ConstrainedHighSpeed API。用ImageReader捕获预览帧时提示**“该Surface不被支持”**,当前使用Google Camera Samples的AutoFitSurfaceView实现预览,但捕获分析帧遇到障碍。
解决方案
1. 匹配高速会话的Surface配置要求
ConstrainedHighSpeedCaptureSession对Surface有严格限制:必须使用设备支持的高速录制参数对应的尺寸、格式,且所有Surface的配置要和高速会话兼容。
- 先从
CameraCharacteristics获取支持的高速视频尺寸:
val characteristics = cameraManager.getCameraCharacteristics(cameraId) val highSpeedSizes = characteristics.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP )?.getHighSpeedVideoSizes() // 选择和120FPS录制匹配的目标尺寸 val targetSize = highSpeedSizes?.firstOrNull { size -> val fpsRanges = characteristics.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP )?.getHighSpeedVideoFpsRangesFor(size) fpsRanges?.any { it.contains(120) } == true }
- 用该尺寸创建
ImageReader,确保格式为ImageFormat.YUV_420_888(多数设备支持):
mImageReader = targetSize?.let { ImageReader.newInstance( it.width, it.height, ImageFormat.YUV_420_888, 2 ) } mImageReader?.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler)
2. 正确构建高速会话与CaptureRequest
创建ConstrainedHighSpeedCaptureSession时,要把AutoFitSurfaceView的Surface和ImageReader的Surface一起传入:
val surfaces = listOf( mAutoFitSurfaceView.holder.surface, mImageReader?.surface ?: return ) cameraDevice.createConstrainedHighSpeedCaptureSession( surfaces, object : CameraCaptureSession.StateCallback() { override fun onConfigured(session: CameraCaptureSession) { mCaptureSession = session // 构建分析用的预览请求,锁定30FPS val previewRequestBuilder = cameraDevice.createCaptureRequest( CameraDevice.TEMPLATE_PREVIEW ).apply { addTarget(mImageReader?.surface!!) set( CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, intArrayOf(30, 30) ) } // 构建120FPS录制请求 val recordRequestBuilder = cameraDevice.createCaptureRequest( CameraDevice.TEMPLATE_RECORD ).apply { addTarget(mAutoFitSurfaceView.holder.surface) val fpsRange = characteristics.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP )?.getHighSpeedVideoFpsRangesFor(targetSize!!)?.firstOrNull { it.contains(120) } ?: intArrayOf(120, 120) set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange) } // 提交重复burst请求,同时处理录制和预览分析 val requests = listOf(previewRequestBuilder.build(), recordRequestBuilder.build()) mCaptureSession.setRepeatingBurst(requests, null, mBackgroundHandler) } override fun onConfigureFailed(session: CameraCaptureSession) { // 处理配置失败逻辑 } }, mBackgroundHandler )
3. 排查常见问题
- 确保
ImageReader的尺寸和高速录制尺寸完全一致,不能使用普通预览尺寸 - 检查设备是否真的支持120FPS高速录制和YUV_420_888格式的ImageReader
- 如果仍提示Surface不支持,可尝试将
ImageReader的maxImages参数调小(比如设为1),避免资源占用过高
内容的提问来源于stack exchange,提问作者PalFS
相关产品推荐
相关产品推荐

