Android WebRTC 外置摄像头接入实战:从硬件选型到低延迟传输优化
一、为什么需要外置摄像头?
在医疗内窥镜、工业质检等专业场景中,设备往往需要:
- 特殊光学需求:如微距、红外或高帧率拍摄(比如检测电路板焊接缺陷需要 10cm 内对焦)
- 物理空间限制:手术机器人等设备无法内置摄像头模组
- 多摄像头协同:产线检测可能需要 4-6 个角度同步拍摄
但外设接入存在三大门槛:
- 接口碎片化:
- USB 摄像头需支持 UVC 协议(Linux 内核版本影响兼容性)
- MIPI 接口需要厂商提供 Android HAL 层驱动
- 工业相机常用 GigE 接口需要 NDK 开发
- 性能瓶颈:
- 实测某 USB3.0 摄像头在 RK3399 开发板上有 300ms 延迟
- 多路 1080P 流会导致 CPU 占用率超 70%
- 系统限制:
- Android 11 后对 USB 设备访问增加 PSA 权限限制
- EMUI 等 ROM 会禁用非白名单设备的 VID/PID
二、技术选型:为什么是 WebRTC?
Camera1 vs Camera2 API 对比
| 维度 | Camera1 | Camera2 |
|---|---|---|
| 架构 | 同步阻塞 | 异步回调 |
| 外设支持 | 仅内置摄像头 | 支持 USB/MIPI 扩展 |
| 帧处理 | 需拷贝到 byte[] | 可通过 Image 直接访问 DMA |
| 延迟 | 120-200ms | 80-150ms |
WebRTC 的 MediaStream 方案优势在于:
- 内置 H264 硬件编码器适配层
- 支持跨平台统一的传输协议
- 提供抗弱网优化的 SRTP 传输
三、核心实现:零拷贝流水线
1. Camera2 采集管道搭建
// 创建面向 ImageReader 的 CaptureSession
val imageReader = ImageReader.newInstance(
1920, 1080, ImageFormat.YUV_420_888, 3
).apply {
setOnImageAvailableListener({ reader ->
val image = reader.acquireNextImage()
// 此处触发 WebRTC 回调
image.close()
}, handler)
}
val cameraDevice: CameraDevice = ... // 通过 CameraManager 打开
val session = cameraDevice.createCaptureSession(
listOf(imageReader.surface),
...
)

