feat: 站点 JSON、语音终端 WebSocket 指派与客户端联调

- 用 OR_SITE_CONFIG_JSON_FILE 统一术间配置(video_rtsp_urls + voice_or_room_bindings)
- VoiceTerminalHub:assignment、WS 推送与 HTTP 查询;开录/停录后 notify
- 一键联调 orchestrate-and-start 与 /client/surgeries/start 共用指派逻辑,修复 demo 路径不发 WS
- 语音桌面端:SIGINT 退出、shutdown 清理、仅 WS 指派、固定 pending 轮询间隔、界面仅保留录音时长
- 新增/调整契约与绑定测试,文档与示例配置同步

Made-with: Cursor
This commit is contained in:
Kevin
2026-04-27 11:21:16 +08:00
parent 4c3f9a367b
commit 6b3adb4ad8
36 changed files with 1194 additions and 162 deletions

View File

@@ -3,7 +3,7 @@
The Operation Room server only opens RTSP URLs (OpenCV); there is no video-upload API.
This script does NOT change the application backend: it runs ffmpeg + a small
RTSP server (MediaMTX) so you can point VIDEO_RTSP_URLS_JSON to rtsp://.../yourpath.
RTSP server (MediaMTX); put the printed ``video_rtsp_urls`` into ``OR_SITE_CONFIG_JSON_FILE``.
Requires:
- ffmpeg in PATH
@@ -210,14 +210,18 @@ def main() -> int:
p = subprocess.Popen(publish_cmd) # noqa: S603
procs.append(p)
j_compact = json.dumps(url_map, ensure_ascii=False, separators=(",", ":"))
site_doc = {"video_rtsp_urls": url_map, "voice_or_room_bindings": []}
print("---", file=sys.stderr)
print("RTSP mapping (set on monitoring server):", file=sys.stderr)
print("RTSP mapping (per camera):", file=sys.stderr)
for k, u in url_map.items():
print(f" {k}: {u}", file=sys.stderr)
print("", file=sys.stderr)
print("export (same machine as monitoring server, env snippet):", file=sys.stderr)
print(f" export VIDEO_RTSP_URLS_JSON='{j_compact}'", file=sys.stderr)
print(
"OR site config (merge video_rtsp_urls into OR_SITE_CONFIG_JSON_FILE; "
"add voice_or_room_bindings as needed):",
file=sys.stderr,
)
print(json.dumps(site_doc, ensure_ascii=False, indent=2), file=sys.stderr)
print("", file=sys.stderr)
print("If the server runs in Docker on Mac/Win, use host.docker.internal, e.g.:", file=sys.stderr)
for cam, u in url_map.items():