Files
operating-room-monitor-server/docs/video-backends.md
Kevin 30e6acea70 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>
2026-05-25 10:24:25 +08:00

7.1 KiB
Executable File
Raw Blame History

视频双后端说明RTSP / 海康 HCNetSDK

目标容器

  • 推荐Linux x86_64 + glibc(与当前 python:3.13-slim-bookworm 一致)。
  • 不推荐Alpinemusl加载海康预编译 .so 往往失败。
  • 镜像已安装 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 未给出某路时使用。
  1. 调用 POST /client/surgeries/start 时,camera_ids 用于语音终端绑定;默认仅 RTSP_PRIMARY_CAMERA_IDor-cam-03 参与 RTSP 录像与 batch 算法。
  2. 开录确认:主摄 RTSP 录像进程在超时内成功连接并写入首段数据后,才认为开录成功。

RTSP 录像切片(链路 1

  • FastAPI 进程内 ffmpeg 从 RTSP 拉流,默认每 120 秒RTSP_SEGMENT_DURATION_SEC)落盘一个 MP4 切片到 logs/rtsp_segments/{surgery_id}/{camera_id}/
  • 每个完整切片通过 BatchAlgorithmService 子进程调用 algorithm_subprocesses/5.15/main.py(与链路 3 相同),解析 result.tsv 后写入活跃会话。
  • 停录时 flush 尾切片并等待 batch 队列 drainRTSP_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.xAPI 在默认 bridge 网络下出站流量经 宿主机 转发,只要宿主机能访问该网段,容器内一般可直接使用相同 URL无需改成 172.x 等。
  • 127.0.0.1 / localhost:在容器内指向容器自身。若 RTSP 服务跑在宿主机或本机 MediaMTXURL 应使用 rtsp://host.docker.internal:<端口>/<路径>backend/docker-compose.yml 已为 api 服务配置 extra_hosts: host.docker.internal:host-gatewayLinux 兼容macOS/Windows Desktop 通常已内置该主机名)。
  • 传输协议compose 默认设置环境变量 OPENCV_FFMPEG_CAPTURE_OPTIONS=rtsp_transport;tcp,使 ffmpeg/OpenCV 经 TCP 拉 RTSP降低容器/NAT 下 UDP 丢包导致的首帧超时;可通过环境变量覆盖。

海康官方 SDK 模式(可选)

SDK 不作为构建期依赖:将厂商提供的 Linux x86_64 动态库挂载到容器内(例如 /opt/hikvision/lib/libhcnetsdk.so),并设置:

  • HIKVISION_SDK_ENABLED=true
  • HIKVISION_DEVICE_IP / HIKVISION_USER / HIKVISION_PASSWORD(以及可选端口)
  • HIKVISION_PREVIEW_RTSP_TEMPLATEHIKVISION_CAMERA_RTSP_URLS_JSON:登录成功后仍通过 RTSP 取帧送模型与常见部署一致SDK 负责设备会话,码流仍走 RTSP

行为概要:

  1. 进程内对 NET_DVR_Init 使用引用计数;每路使用 SDK 的工作线程在登录后 NET_DVR_Logout,线程结束时配对 NET_DVR_Cleanup
  2. HIKVISION_SDK_FALLBACK_TO_RTSP=true(默认),在无法加载动态库登录失败未配置凭据时,自动回退到 OR 站点配置中的 video_rtsp_urlsVIDEO_RTSP_URL_TEMPLATE 拉流。

注意NET_DVR_Login_V30 的设备信息结构体在不同 SDK 版本上可能存在差异;若登录异常,请优先使用 RTSP 回退或按厂商文档校对 ctypes 绑定。

推理与结果查询

链路 1RTSP 切片 + batch5.15/main.py

  • 开录后 FastAPI 用 ffmpeg 录像并按 RTSP_SEGMENT_DURATION_SEC 切片;每段 MP4 经 batch 子进程推理,结果按 TSV 置信度写入会话。
  • 候选耗材清单candidate_consumables):非空时清单内名称参与自动记账与待确认;缺省或 [] 时,用 consumable_classifier_labels.yaml全部类名作为候选。
  • 当 Top1 置信度 VIDEO_AUTO_CONFIRM_CONFIDENCE默认 0.9)且标签在候选清单内时,自动写入 source=video_batch 明细;中间区间入待确认队列,由语音终端 TTS/确认。
  • 客户端 GET /client/surgeries/{surgery_id}/pending-confirmation,确认后 POST .../pending-confirmation/{id}/resolve 等。

链路 3离线 batchPOST /internal/demo/offline-batch

  • FastAPI 编排层 app/algo_host 为 5.15 准备工作目录(config.yaml、白名单、商品表),子进程直调 algorithm_subprocesses/5.15/main.py --config;解析 result.tsv 后入库。在 API 进程内加载模型,修改 5.15 源码。
  • 可选标注视频由子进程 visualize_result_video.py 生成;结果缓存键为 sha256(video) + candidate_list(跨手术号复用)。
  • 启动实时会话、触发语音终端。

通用

  • GET /client/surgeries/{surgery_id}/result 仅在存在至少一条消耗明细时返回 200无明细已开录但尚未记账、已结束但零消耗、或尚无归档等返回 503 RESULT_NOT_READY
  • 同类物品写入受 VIDEO_DETAIL_COOLDOWN_SEC 节流。

Demo 联调台HLS 浏览器预览

浏览器无法直接播放 RTSP。联调台通过 MediaMTX 将 RTSP 转为 HLS,由 FastAPI 反代 m3u8/ts 后由 hls.js 播放。

部署方式 行为
Docker Compose推荐 固定服务 mediamtx-hls(宿主机 127.0.0.1:18888,容器内 mediamtx-hls:8888hls-preview-init 种子共享卷后 MediaMTX 直接读 /config/mediamtx.yml(官方镜像是 scratch勿用 /bin/sh entrypointensure 写共享 mediamtx.ymldocker restart orm-mediamtx-hlsDEMO_HLS_PREVIEW_UPSTREAM=http://mediamtx-hls:8888
本机 uvicorn 未设 upstream 时按需 docker run 临时 MediaMTX端口默认 127.0.0.1:18888
链路 行为
链路 1(真 RTSP POST /internal/demo/hls-preview/ensureor_site_configvideo_rtsp_urls 配置 MediaMTX 路径
  • 播放地址:GET /internal/demo/hls-preview/{camera_id}/index.m3u8playlist 内 URL 重写为 API 路径)。
  • Compose 需将 docker.sock 挂入 api(用于 reload mediamtx-hls

单帧 JPEG 预览仍保留:GET /internal/demo/rtsp-preview/{camera_id}/frame.jpg

相关环境变量

详见 backend/.env.example 中「视频RTSP + 切片 batch」、HLS 预览与可选海康 HCNetSDK 相关注释。