文档库

HTTP接口与同帧预览

ESP32-S3-CAM-Mini 产品与硬件、快速上手、视觉案例、接口与图传使用说明。
ESP32-S3-CAM-Mini 使用与开发手册

本章按固件分组;路径大小写与字段名必须一致。接口用于可信局域网,不能把同网访问能力当成用户鉴权。

factory接口

方法/端口路径含义
GET / 80/控制页
GET / 80/api/status相机、网络、帧计数、内存和切换状态
GET / 80/capture.jpg单张JPEG
GET / 81/streamMJPEG流
GET / 80/api/led?value=1LED开;0为关
GET / 80/api/camera?framesize=VGA请求档位,选QVGA/VGA/SVGA/XGA
GET / 80/api/camera?hmirror=1水平镜像;0为关
GET / 80/api/camera?vflip=1垂直翻转;0为关

一次请求只修改一个相机选项。档位切换返回202,随后轮询状态;确认camera_reconfiguring=false、实际framesize等于目标,且camera=true。错误时读取camera_reconfigure_error。本固件帧计数字段使用frames_ok等下划线命名,不能与六足图传的驼峰字段混用。

nodehexa-video接口

方法/端口路径行为
GET / 80/statusJSON诊断,不返回密码或流令牌
GET / 81/stream?session=当前令牌绑定模式MJPEG

状态字段包括cameraId、robotId、bssid、bound、wifiPhase、wifiError、sensor、camera、wifi、ip、framesize、profilePending、framesOk、captureFailures、encodeFailures、overCurrent、heapFree、psramFree。

wifi=true与camera=true是不同状态,绑定还要看bound。错误计数用于观察趋势,单次非零不能独立定位硬件原因。GET /status不会帮你初始化运动策略或切换分辨率;档位控制走UART。

客户端应从主控GET /api/caps读取peripherals.camera.streamUrl。绑定未就绪或令牌过期时流返回403;流资源忙时可能503。旧未绑定单机模式允许裸/stream,不要将它当成新版绑定模式的通用地址。

vision-demos配置接口

方法路径请求/返回
GET/api/config算法、字段、当前值、范围及版本
POST/api/configJSON,部分字段更新
POST/api/config/resetJSON正文{},恢复默认
GET/api/frame?after=0获取与某一帧对应的元数据和JPEG

POST的Content-Type使用application/json,正文非空且不超过1024字节。未知字段、重复字段、越界/非整数值、当前算法不适用字段会拒绝;配置整组生效。若带Origin,必须与当前Host同源。网页可以调参数不代表接口有登录鉴权。

{"interval_ms":200,"jpeg_quality":60}
字段默认合法范围适用
interval_ms1000–5000全部
jpeg_quality6020–85全部
color_min_samples961–19200色块
color_min_brightness700–255色块
color_min_chroma350–255色块
line_threshold651–255巡线
motion_threshold241–255运动
motion_min_samples1201–4800运动
bright_threshold2350–254亮点
bright_min_samples41–19200亮点

运行时以/api/config返回为准。预览JPEG质量、相机驱动中的jpeg_quality和模型内部参数不是同一配置项。

同帧包格式

返回204表示当前没有不同于after的可用预览帧;稍后再请求。返回200时正文是二进制,不可直接调用response.json():

uint32_le JSON字节长度N | N字节UTF-8 JSON | 剩余JPEG字节

先检查长度,再解码JSON和图片。下面是独立解析函数,不包含轮询或UI逻辑:

async function readFrame(after = 0) {
  const response = await fetch(`/api/frame?after=${after}`, {cache: 'no-store'});
  if (response.status === 204) return null;
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const buf = await response.arrayBuffer();
  if (buf.byteLength < 4) throw new Error('short packet');
  const n = new DataView(buf).getUint32(0, true);
  if (n === 0 || n > buf.byteLength - 4) throw new Error('invalid JSON length');
  const meta = JSON.parse(new TextDecoder().decode(new Uint8Array(buf, 4, n)));
  const jpeg = new Blob([buf.slice(4 + n)], {type: 'image/jpeg'});
  return {meta, jpeg};
}

元数据seq是32位处理帧号,config_revision是实际使用的配置版本,capture_ms来自相机帧时间戳(启动后毫秒),latency_ms仅计识别。overlay为box/line/statistics/none;geometry按像素表达,框为[左,上,宽,高],线为[x1,y1,x2,y2]。

after用于避免重复读取同一缓存帧,不是历史帧分页;设备只保留最新预览,可能跳号。不要要求seq必须连续。发生设备重启后应允许重新建立序号基线。

网页需要把同一包的JPEG和结果一起显示,并按图像缩放比例转换像素坐标。不能独立拉MJPEG再把“最新结果”叠上去,否则运动场景中框与图像容易错帧。解码图片完成前也不要先绘制下一帧标注。