# Demo Client 独立浏览器联调页,用于手动触发监控 API 的部分 `/client/*` 接口:开始/结束手术、查询结果等。语音待确认、TTS 与麦克风录音请使用同级的 [`../voice-confirmation/`](../voice-confirmation/) 或其它专用客户端。 ## 结构 ``` clients/demo-client/ start.sh # 启动入口(默认 0.0.0.0:38081) server.py # stdlib 静态服务器;额外暴露 /labels.json index.html # 单文件页面(原生 JS,零构建依赖) labels.yaml # 耗材类名快照(与后端 app/resources/consumable_classifier_labels.yaml 同步) fake_rtsp_from_file.py # 无真摄像头时:本地视频推 RTSP(ffmpeg + Docker MediaMTX) ``` **`labels.yaml`**:本目录自带副本,与后端解耦。后端类名变更时,请同步更新此文件。 ## 运行 ```bash # 1) 在仓库根目录启动 Docker 后端 docker compose up -d --build # 2) 在本目录启动 Demo 页 ./start.sh # 或:python server.py -p 38081 --host 0.0.0.0 # 3) 浏览器访问 open http://127.0.0.1:38081/ ``` 页面「服务端 Base URL」默认指向同主机 `:38080`;后端在其他机器时手动改为 `http://:38080`。 ## 调试:无真实摄像头,用录好的视频模拟 RTSP 监控服务**只从 RTSP URL 拉流**,没有视频上传 HTTP 接口。推荐在宿主机用 **ffmpeg + MediaMTX** 推假流: **单路**: ```bash python3 fake_rtsp_from_file.py /path/to/recording.mp4 --port 18554 --path demo ``` **两路**: ```bash python3 fake_rtsp_from_file.py --port 18554 \ --stream 'or-cam-01|./a.mp4|demo1' \ --stream 'or-cam-02|./b.mp4|demo2' ``` `--stream` 格式:`CAMERA_ID|文件路径|RTSP_PATH`。脚本会在 stderr 打印站点 JSON 片段,可合并进后端的 `OR_SITE_CONFIG_JSON_FILE`。 ### API 在 Docker、假 RTSP 在宿主机 容器内访问宿主机 RTSP 应使用 `rtsp://host.docker.internal:<端口>/<路径>`(compose 已配置 `extra_hosts`)。详见 [`../../docs/video-backends.md`](../../docs/video-backends.md)。 ## 一键开录 Demo 页勾选「一键联调」后上传视频,调用 `POST /internal/demo/orchestrate-and-start`。需后端 `.env` 中 `DEMO_ORCHESTRATOR_ENABLED=true`,且 API 容器能执行 `docker`/`ffmpeg`(通常需挂载 docker.sock)。 ## 页面功能 - `GET /health` 连通性检查 - `POST /client/surgeries/start|end`、`GET /client/surgeries/{id}/result` - 调试区:多路视频、假 RTSP、`camera_id` 同步 不含语音确认 UI(见 [`../voice-confirmation/`](../voice-confirmation/))。 ## CORS 跨域访问 API 时,后端需 `DEMO_CORS_ENABLED=true`;生产环境收窄 `DEMO_CORS_ORIGINS`。