关于 react-native-vision-camera-realtime
react-native-vision-camera-realtime 是面向 react-native-vision-camera 的实时图像处理技能,供开发者设计从相机帧到结果的完整流水线。它强调减少跨执行与内存域传输、复用热路径资源,并按最终结果选择 GPU、原生或 CPU 处理方式。
主要功能
- 01按最终消费者选择处理路径
- 02保持方向和镜像为元数据
- 03复用已预热的流水线与缓冲区
- 04为逐帧视觉效果保持同帧处理
- 05限制异步任务和帧队列
- 06检查延迟、丢帧与资源使用
适用场景
- 01构建相机帧驱动的 GPU 效果或叠加层
- 02连接 VisionCamera 与原生插件或 WebGPU
- 03为扫描或机器学习任务评测计算单元
- 04排查相机流水线延迟、丢帧和内存问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ margelo/ react-native-skills --skill react-native-vision-camera-realtime安装后在 Claude Code 中输入/react-native-vision-camera-realtime确认已加载。
附带文件references/interop.md
详细介绍
实时 VisionCamera 流水线
这是 react-native-vision-camera 的专用配套指南。应优化从 Camera 缓冲区到最终结果的完整路径,而不是孤立地优化某个阶段。在依赖确切 API 之前,请对照当前的 VisionCamera 文档以及使用方的官方文档或源代码,检查已安装的版本。
根据最终使用方选择
| 最终使用方 | 首选路径 |
|---|---|
| 与帧同步的渲染、特效或叠加层 | 使用 <SkiaCamera /> 或 WebGPU,让处理和绘制处于同一 GPU 时间线上 |
| WGSL 计算或 GPU 推理 | Frame.getNativeBuffer() 到 WebGPU 视频帧,再到 device.importExternalTexture(...) |
| 依赖 VisionCamera 的原生插件 | 使用长生命周期的 Nitro HybridObject,其热路径方法接受类型化的 Frame |
| 不依赖 VisionCamera 的原生库 | 使用无类型的 NativeBuffer 指针和明确的释放约定 |
| 仅需状态的 ML 或扫描 | 对比平台运行时在 ANE 或 NPU、GPU 和 CPU 后端上的表现;返回精简的状态 |
| 仅支持 CPU 的使用方 | 使用满足需求的最小分辨率和格式,并采用有界、可复用的 CPU 缓冲区路径 |
仅在实现或审查 Nitro、NativeBuffer、WebGPU、Skia、Resizer 或 ArrayBuffer 互操作时,才加载 references/interop.md。
热路径不变量
- 将方向和镜像作为元数据处理。设置
enablePhysicalBufferRotation: false,然后将frame.orientation和frame.isMirrored传给使用方,或在同一 GPU 变换中应用它们,同时进行缩放、裁剪或渲染。切勿对 Camera 缓冲区进行物理旋转。 - 始终处于同一执行和内存域中。在 GPU 流水线中,仅导入一次;预处理、推理、后处理和渲染都保留在 GPU 上,并且只在必要时读回精简结果。
- 对经过验证的纯 GPU 路径,优先使用
pixelFormat: 'native'。检查frame.pixelFormat和frame.hasNativeBuffer,因为解析出的原生格式可能是 YUV、RGB、RAW 或 private。 - 在常规 GPU 路径中,不要使用
getPixelBuffer()、getPlanes()、平面像素缓冲区、映射的 GPU 缓冲区或类型化像素视图。CPU 可见性可能导致同步或下载。 - 仅创建并预热一次流水线、着色器、采样器、模型会话、调整器、大型缓冲区和原生处理器。在组件或会话的整个生命周期内复用它们;切勿逐帧分配。
- 使用 Skia 或 WebGPU,从同一个
Frame绘制与帧同步的叠加层。不要通过 React 状态、普通视图或 Reanimated 共享值传递逐帧几何数据。 - 在所有路径中,确保每个
Frame、NativeBuffer、包装器、纹理和池化槽位都只释放一次。按所有权的相反顺序释放包装器,并最后释放Frame。
优先采用同帧处理
需要在视觉上对齐时,让检测、跟踪、决策和绘制与对应帧保持同步。60 FPS 的硬性间隔为 16.67 ms;30 FPS 为 33.33 ms。目标是分别控制在约 16 ms 和 33 ms 以内,以留出调度余量。
“同步”指同帧数据流,而不是阻塞 CPU,直到 GPU 完成。尽可能将相互依赖的 GPU 阶段编码到同一个命令图中。不要逐帧调用 queue.onSubmittedWorkDone()、映射缓冲区、回读数据,或添加其他 CPU 或 GPU 栅栏。
在让工作异步化之前,先移除拷贝和回读、降低输入分辨率或 FPS、融合处理阶段、优化模型张量,并复用预热后的状态。只有在优化后仍无法满足帧间隔(通常约为 50 ms 或更长),且产品能够接受结果滞后时,才使用异步处理。对于与帧关联的视觉效果,优先简化工作,而不是容忍可见延迟。
以下异步交付模式彼此并列:
- 原生 Nitro 工作,使用持久化的完成回调
- 原生 Nitro 工作,将已完成状态存储起来,通过同步的最新状态 getter 获取
- 使用 VisionCamera 的
useAsyncRunner()调度的同步原生方法
每种异步设计都必须限制在途工作量。使用一个活动任务或一个容量较小的固定池,拒绝或替换过时的待处理输入,绝不要构建无界 FIFO 队列。dropFramesWhileBusy 是过载保护措施,不是架构方案。使用 useAsyncRunner() 时,在任务内部释放已接收的 Frame,并立即释放被拒绝的 Frame。
端到端选择 ML 计算方式
如果推理结果要用于同帧 Skia 或 WebGPU 渲染,优先让整个处理路径留在 GPU 上。只有端到端性能分析证明确实更快且仍能满足帧预算时,才值得将数据转移到 ANE、NPU 或 CPU,并把几何数据传回渲染器。
对于仅扫描状态的任务,应对平台运行时可用的计算单元进行基准测试。ANE 或 NPU 可以避免 GPU 争用,并加速受支持的模型;如果加速器调度和数据传输成本占主导地位,那么小型模型在 CPU 上运行可能更快。测量输入转换、同步、推理和结果交付,而不只是推理本身。对于没有帧关联叠加层的扫描,使用常规 React 状态或导航即可。
开发与生产检查
当所有原生依赖都支持时,可使用可调整大小的 iPad 形状 Mac Catalyst 或 iPad-on-Mac 构建版本,作为快速迭代测试环境。桌面 Agent 可以重新启动、调整其大小并截取屏幕截图,同时使用内置 Mac 摄像头或通过 useCameraDevice('external') 使用外接 UVC 摄像头。如果 Mac 目标或所需插件不可用,则改用手机。
Mac 测试流程用于功能迭代,而非预测性能。应在每类生产设备和有代表性的 GPU 上验证发布构建。测试时间应足够长,以暴露热降频和资源池泄漏问题。跟踪以下指标:
- 从摄像头时间戳到对应结果或呈现的延迟,包括中位数、p95 和 p99
- 丢帧数和最大在途帧数
- CPU 和 GPU 耗时、回读、映射和同步点
- 每帧分配次数、稳态内存、持续 FPS、温度和功耗
异步且稀疏地采样 GPU 计时,避免监测本身成为同步点。
权威参考资料
- VisionCamera:文档索引、性能、异步处理、外部摄像头
- 渲染与计算:VisionCamera Skia、React Native WebGPU 集成
- ML 计算:Apple Core ML 计算单元、LiteRT NPU 委托