mcpField
C
camerax

camerax

github.com/android开发10.0k1.3k 次安装2 天前更新
代码仓库

关于 camerax

为 Android 开发者提供 CameraX 相机应用的实践指导,涵盖 Camera2Interop 和 Media3 集成。内容还包括旧相机 API 迁移、复杂功能规划、现代 API 选择及跨设备测试建议。

主要功能

  1. 01Camera1 和 Camera2 迁移指导
  2. 02CameraX 不可变 API 使用模式
  3. 03手动控制、RAW 与低光功能规划
  4. 04Media3 效果与分析 API 建议
  5. 05设备适配、生命周期与测试规范

适用场景

  1. 01将旧相机应用迁移到 CameraX
  2. 02实现 RAW 拍摄或手动相机控制
  3. 03处理折叠屏及多摄像头设备
  4. 04测试相机分析与异步生命周期

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/android/skills --skill camerax

安装后在 Claude Code 中输入/camerax确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
camera1-to-camerax.md
camera2-to-camerax.md
expert-blueprints.md
foldables.md
immutability.md
low-light.md
mlkit-spatial.md
modern-apis.md
testing.md
thermals.md
wear-os.md
xr.md

详细介绍

此技能提供了在 Android 上构建相机应用的流程指导和标准模式,重点介绍 CameraX,包括其 Camera2Interop 实用工具,以及 Media3 集成。

核心工作流

处理不可变 API 模式

各种 Android 相机和媒体 API,尤其是 CameraX VideoCapture,都采用流畅、不可变的构建器式模式,其中方法会返回一个新实例。 如果不重新赋值,这些结果就会被忽略,导致音频等设置不生效。

模式:必须重新赋值

// WRONG
run {
  val pending = recorder.prepareRecording(context, opts)
  pending.withAudioEnabled() // This returns a new instance which is ignored
  val active = pending.start(exec, listener)
}

// CORRECT
run {
  val pending = recorder.prepareRecording(context, opts)
      .withAudioEnabled() // Chaining works
  val active = pending.start(exec, listener)
}

// ALSO CORRECT
run {
  var pending = recorder.prepareRecording(context, opts)
  pending = pending.withAudioEnabled() // Reassignment
  val active = pending.start(exec, listener)
}

请参阅不可变性,了解受影响的类列表。

迁移到 CameraX

将旧版相机代码库迁移到 CameraX Jetpack 库时:

  • Camera1 迁移到 CameraX:如需迁移旧版 android.hardware.Camera 实现、表面处理和手动生命周期,请参阅 Camera1 迁移指南。
  • Camera2 迁移到 CameraX:如需迁移较新但冗长的 android.hardware.camera2 实现、会话状态回调和互操作模式,请参阅 Camera2 迁移指南。
全面的功能蓝图设计

对于涉及多个文件和硬件级连接的多步骤功能,请遵循结构化蓝图设计方法,以避免系统超时。此类复杂功能包括:

  • 手动控制:拆分为 ViewModel 状态、控制器层和会话中的 Camera2Interop 连接。
  • RAW 拍摄:将 JPEG 和 RAW 输出配置拆分为独立的构建步骤。
  • 自定义效果:除非绝对需要更高性能,否则优先使用 Media3Effect 或 SurfaceProcessor,而不是手动搭建 OpenGL 管线。
  • 弱光:请参阅弱光,了解夜间模式和 LLB 指南。
  • 折叠设备:请参阅折叠设备,了解如何处理动态姿态和铰链状态。
  • XR、AR 和 VR:请参阅 xr,了解空间跟踪、透视同步和延迟防护措施。
  • 热管理和电源:请参阅热管理,了解如何管理 StreamUseCase 优化和 PowerManager 热状态。
  • 测试与模拟:请参阅测试,了解如何使用 FakeCameraConfig、处理异步生命周期以及验证分析管线。
  • ML Kit 空间分析:请参阅 mlkit-spatial,了解坐标映射、旋转逻辑和镜像镜头处理。
  • Wear OS 相机远程控制:请参阅 wear-os,了解圆形 UI 限制、Data Layer API 同步和远程触发逻辑。

请参阅 expert-blueprints,了解分步指南。

API 探索

始终使用更高层级的抽象,而不是底层手动连接:

  • 分析:使用 MlKitAnalyzer,而不是手动实现 ImageAnalysis.Analyzer。
  • 滤镜和效果:使用 Media3Effect 进行标准后期处理。
  • 多摄像头:使用 ConcurrentCamera API 设置双流。

请参阅 modern-apis,了解当前建议。

代码质量和架构规范

构建相机实现时,请遵循以下 Android 生态系统标准模式:

  • 测试中优先使用 Fake,而非 Mock:避免使用 Mockito 等 Mock 库,尤其是在处理 ImageProxy 这类涉及多步操作的 CameraX 接口时。构建“Fake”以验证状态,而不是验证不可靠的实现细节。
  • 使用 Google Truth 断言:优先使用 assertThat,而不是 assertEquals 等标准 JUnit 断言,以提升可读性。
  • 显式指定测试运行器:始终为测试类定义显式的 @RunWith,确保 CI 环境能够正确执行测试。
  • 语义化 UI 合并:在 Compose 中构建自定义相机控件时,例如包含 Icon 和 Text 的按钮,请使用 semantics { mergeDescendants = true },确保屏幕阅读器将其作为一个连贯的整体进行播报。

硬件和设备多样性

相机应用运行于各种硬件上,从手机和折叠屏设备到平板电脑、笔记本电脑,甚至智能家电。请考虑应用运行所用硬件的具体情况。

  • 设备形态:考虑折叠屏设备和平板电脑的屏幕尺寸及方向变化。
  • 多摄像头阵列:有些设备配有前置摄像头和后置摄像头;另一些设备则配有多个后置摄像头,例如广角镜头和长焦镜头。
  • 功能一致性:闪光灯或自动对焦等功能在不同硬件上的表现有所不同。例如,CameraX 同时支持物理闪光灯、后置摄像头,以及基于屏幕的闪光灯和前置摄像头;实现闪光灯功能时必须将这些情况都考虑在内。

常见问题

  • 异步生命周期:尝试停止或暂停前,请检查 isRecording 状态。处理 VideoRecordEvent.Start 以更新 UI 状态,而不只是处理初始调用。
  • 线程安全:相机回调通常在后台执行器上运行。请在主线程上分发 UI 更新。
  • 权限处理:检查 CAMERA 权限;在 VideoCapture 中启用音频时,务必检查 RECORD_AUDIO 权限。

评论

支持 Markdown