Replace chain 1 with RTSP slice batch pipeline and add 24h segment TTL.
Route live recording through ffmpeg MP4 segments and the 5.15 batch subprocess, remove simulated RTSP chain 2, purge expired slices on startup and hourly, and expose TTL settings to the demo client. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,21 +4,29 @@
|
||||
|
||||
- **推荐**:`Linux x86_64` + **glibc**(与当前 `python:3.13-slim-bookworm` 一致)。
|
||||
- **不推荐**:Alpine(musl)加载海康预编译 `.so` 往往失败。
|
||||
- 镜像已安装 **ffmpeg** 与 OpenCV 常用系统库,便于 `cv2.VideoCapture(..., cv2.CAP_FFMPEG)` 拉 RTSP。
|
||||
- 镜像已安装 **ffmpeg** 与 OpenCV 常用系统库,便于 RTSP 录像切片与预览。
|
||||
|
||||
## RTSP 模式(默认)
|
||||
|
||||
1. 配置 `**camera_id` → RTSP URL** 映射:
|
||||
- `**OR_SITE_CONFIG_JSON_FILE**`(推荐):UTF-8 JSON 文件,**仅支持**站点对象:`{"video_rtsp_urls":{...},"voice_or_room_bindings":[...]}`。根级只允许这两个键;`voice_or_room_bindings` 可为 `[]`。见 `[app/resources/or_site_config.sample.json](../app/resources/or_site_config.sample.json)`。服务每次解析映射时会重新读文件,便于联调覆盖 `video_rtsp_urls`。
|
||||
- `**VIDEO_RTSP_URL_TEMPLATE**`(可选):单模板字符串,可用 `{camera_id}`;在 `video_rtsp_urls` 未给出某路时使用。
|
||||
2. 调用 `POST /client/surgeries/start` 时,`camera_ids` 必须能在上述配置中解析出 RTSP 地址。
|
||||
3. **开录确认**:每路摄像头在超时内成功打开并读到**首帧**后,才认为该路已开录。
|
||||
2. 调用 `POST /client/surgeries/start` 时,`camera_ids` 用于语音终端绑定;**默认仅 `RTSP_PRIMARY_CAMERA_ID`(or-cam-03)** 参与 RTSP 录像与 batch 算法。
|
||||
3. **开录确认**:主摄 RTSP 录像进程在超时内成功连接并写入首段数据后,才认为开录成功。
|
||||
|
||||
## RTSP 录像切片(链路 1)
|
||||
|
||||
- FastAPI 进程内 **ffmpeg** 从 RTSP 拉流,默认每 **120 秒**(`RTSP_SEGMENT_DURATION_SEC`)落盘一个 MP4 切片到 `logs/rtsp_segments/{surgery_id}/{camera_id}/`。
|
||||
- 每个完整切片通过 [`BatchAlgorithmService`](../backend/app/algo_host/batch_service.py) 子进程调用 `algorithm_subprocesses/5.15/main.py`(与链路 3 相同),解析 `result.tsv` 后写入活跃会话。
|
||||
- 停录时 flush 尾切片并等待 batch 队列 drain(`RTSP_SLICE_BATCH_DRAIN_TIMEOUT_SEC`)。
|
||||
- 落盘切片默认 **24 小时**后自动删除(`RTSP_SEGMENT_TTL_HOURS`;进程启动与后台定时 sweep)。
|
||||
- 设置 `RTSP_RECORD_ALL_CAMERAS=true` 可对请求中所有可解析 RTSP 的机位分别录像+跑 batch(多机位代码已预留)。
|
||||
|
||||
## Docker 与 RTSP 地址
|
||||
|
||||
- **站点 JSON 中的局域网 IP**(如 `[or_site_config.sample.json](../app/resources/or_site_config.sample.json)` 的 `192.168.3.x`):API 在默认 **bridge** 网络下出站流量经 **宿主机** 转发,只要**宿主机**能访问该网段,容器内一般可直接使用相同 URL,无需改成 `172.x` 等。
|
||||
- **`127.0.0.1` / `localhost`**:在容器内指向**容器自身**。若 RTSP 服务跑在宿主机(含 `fake_rtsp_from_file.py`、本机 MediaMTX),URL 应使用 **`rtsp://host.docker.internal:<端口>/<路径>`**。[`backend/docker-compose.yml`](../backend/docker-compose.yml) 已为 `api` 服务配置 `extra_hosts: host.docker.internal:host-gateway`(Linux 兼容;macOS/Windows Desktop 通常已内置该主机名)。
|
||||
- **传输协议**:compose 默认设置环境变量 **`OPENCV_FFMPEG_CAPTURE_OPTIONS=rtsp_transport;tcp`**,使 OpenCV 经 FFmpeg 以 **TCP** 拉 RTSP,降低容器/NAT 下 UDP 丢包导致的首帧超时;可通过环境变量覆盖。
|
||||
- **`127.0.0.1` / `localhost`**:在容器内指向**容器自身**。若 RTSP 服务跑在宿主机或本机 MediaMTX,URL 应使用 **`rtsp://host.docker.internal:<端口>/<路径>`**。[`backend/docker-compose.yml`](../backend/docker-compose.yml) 已为 `api` 服务配置 `extra_hosts: host.docker.internal:host-gateway`(Linux 兼容;macOS/Windows Desktop 通常已内置该主机名)。
|
||||
- **传输协议**:compose 默认设置环境变量 **`OPENCV_FFMPEG_CAPTURE_OPTIONS=rtsp_transport;tcp`**,使 ffmpeg/OpenCV 经 **TCP** 拉 RTSP,降低容器/NAT 下 UDP 丢包导致的首帧超时;可通过环境变量覆盖。
|
||||
|
||||
## 海康官方 SDK 模式(可选)
|
||||
|
||||
@@ -37,11 +45,11 @@ SDK **不作为构建期依赖**:将厂商提供的 Linux x86_64 动态库挂
|
||||
|
||||
## 推理与结果查询
|
||||
|
||||
### 链路 1/2:实时(`python -m app.algorithm_runner`)
|
||||
### 链路 1:RTSP 切片 + batch(`5.15/main.py`)
|
||||
|
||||
- 开录后子进程从 RTSP 读帧,经 ActionFormer gated 流水线(VideoSwin → 段检测 + 手检/好坏帧/耗材投票)产出 JSONL 事件。
|
||||
- 开录后 FastAPI 用 ffmpeg 录像并按 `RTSP_SEGMENT_DURATION_SEC` 切片;每段 MP4 经 batch 子进程推理,结果按 TSV 置信度写入会话。
|
||||
- **候选耗材清单**(`candidate_consumables`):非空时**仅**清单内名称参与自动记账与待确认;**缺省或 `[]`** 时,用 `consumable_classifier_labels.yaml` 的 **全部类名**作为候选。
|
||||
- 当段内 Top1 置信度 **≥** `VIDEO_AUTO_CONFIRM_CONFIDENCE`(**默认 0.9**)且标签在候选清单内时,自动写入 `source=vision` 明细;中间区间产生 `needs_voice_confirm`,由语音终端 TTS/确认。
|
||||
- 当 Top1 置信度 **≥** `VIDEO_AUTO_CONFIRM_CONFIDENCE`(**默认 0.9**)且标签在候选清单内时,自动写入 `source=video_batch` 明细;中间区间入待确认队列,由语音终端 TTS/确认。
|
||||
- 客户端 `GET /client/surgeries/{surgery_id}/pending-confirmation`,确认后 `POST .../pending-confirmation/{id}/resolve` 等。
|
||||
|
||||
### 链路 3:离线 batch(`POST /internal/demo/offline-batch`)
|
||||
@@ -52,10 +60,8 @@ SDK **不作为构建期依赖**:将厂商提供的 Linux x86_64 动态库挂
|
||||
|
||||
### 通用
|
||||
|
||||
- `GET /client/surgeries/{surgery_id}/result` 仅在存在**至少一条**消耗明细时返回 200;否则 503 `RESULT_NOT_READY`。
|
||||
- `GET /client/surgeries/{surgery_id}/result` 仅在存在**至少一条**消耗明细时返回 200;无明细(已开录但尚未记账、已结束但零消耗、或尚无归档等)返回 503 `RESULT_NOT_READY`。
|
||||
- 同类物品写入受 `VIDEO_DETAIL_COOLDOWN_SEC` 节流。
|
||||
- RTSP 读帧连续失败达到 `VIDEO_READ_FAILURE_RECONNECT_THRESHOLD` 时会 `release` 并尝试重连,间隔 `VIDEO_RECONNECT_BACKOFF_SECONDS`。
|
||||
|
||||
## Demo 联调台:HLS 浏览器预览
|
||||
|
||||
@@ -69,13 +75,12 @@ SDK **不作为构建期依赖**:将厂商提供的 Linux x86_64 动态库挂
|
||||
| 链路 | 行为 |
|
||||
|------|------|
|
||||
| **链路 1**(真 RTSP) | `POST /internal/demo/hls-preview/ensure` 按 `or_site_config` 的 `video_rtsp_urls` 配置 MediaMTX 路径 |
|
||||
| **链路 2**(模拟实时) | 不使用 HLS;联调台在各路槽位用本地 `<video>` 预览所选文件 |
|
||||
|
||||
- 播放地址:`GET /internal/demo/hls-preview/{camera_id}/index.m3u8`(playlist 内 URL 重写为 API 路径)。
|
||||
- Compose 需将 **docker.sock** 挂入 `api`(用于 reload mediamtx-hls),与模拟假流 orchestrator 相同。
|
||||
- Compose 需将 **docker.sock** 挂入 `api`(用于 reload mediamtx-hls)。
|
||||
|
||||
单帧 JPEG 预览仍保留:`GET /internal/demo/rtsp-preview/{camera_id}/frame.jpg`。
|
||||
|
||||
## 相关环境变量
|
||||
|
||||
详见 `backend/.env.example` 中「视频:RTSP + 可选海康 HCNetSDK」与 HLS 预览相关注释。
|
||||
详见 `backend/.env.example` 中「视频:RTSP + 切片 batch」、HLS 预览与可选海康 HCNetSDK 相关注释。
|
||||
Reference in New Issue
Block a user