Files
Kevin 9941e0d131 feat(voice-client): 双层配置持久化、精简手术号 UI 与 WS/服务端排查日志
- machine_config:系统级 + 用户级 voice_client.json 合并,界面失焦保存至用户目录
- 移除「当前手术号」表单项与占位文案;指派后仅在窗口标题显示手术号
- WebSocket 连接日志附带绑定/开录路径排查说明
- 开录未推送时服务端 WARNING(无站点绑定或 camera_ids 不匹配)
- 测试、README、.env.example 同步

Made-with: Cursor
2026-04-27 11:45:11 +08:00

100 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 手术室耗材语音确认客户端(桌面版)
独立桌面程序:按可配置间隔(默认 **5 秒**)轮询 `GET /client/surgeries/{surgery_id}/pending-confirmation`,播放服务端返回的 **MP3 话术**,录制医生麦克风为 **16 kHz 单声道 WAV**,并调用 `POST .../pending-confirmation/{confirmation_id}/resolve``multipart` 字段名 `audio`)。协议与 `[docs/客户端手术通信接口说明.md](../docs/客户端手术通信接口说明.md)` 一致。
## 环境
- Python **3.13+**(与主项目一致)
- 安装可选依赖组 **voice-client**PySide6、httpx、numpy、sounddevice、websocket-client
```bash
cd /path/to/operation-room-monitor-server
uv sync --group voice-client
```
## 运行(开发态)
未配置项目 `build-system` 时,`uv` 可能不会注册 `voice-confirmation-client` 命令,推荐:
```bash
./start_voice_confirmation_client.sh
```
或在仓库根目录:
```bash
uv run --group voice-client python -m voice_confirmation_client
```
Windows仓库根目录
```bat
start_voice_confirmation_client.bat
```
若 entry point 已可用,也可:
```bash
uv run --group voice-client voice-confirmation-client
```
**术间 / 摄像头 / 语音终端对应关系**只在服务端 `**OR_SITE_CONFIG_JSON_FILE`** 里维护一份(`voice_or_room_bindings`);桌面程序不读该文件。
本机要做的只有两件事:**服务端 Base URL**,以及 **本机语音终端 ID**(须等于 JSON 里某条 `voice_terminal_id`)。**手术号不在客户端输入**:勾选 **启用服务端自动指派** 后,开录/停录仅通过 **WebSocket** `voice_assignment` 下发(断线后自动重连,不用 HTTP 轮询);当前手术号在**窗口标题**中显示;停录后自动停止。可用 **停止监控(本机)** 做本地紧急中断。
### 配置文件(系统级 + 用户级)
字段均为 **UTF-8 JSON**`voice_terminal_id``http_base_url`,均可选)。启动时 **合并** 两层配置:**用户级覆盖系统级** 同名字段。
| 层级 | 用途 | 默认路径 |
|------|------|----------|
| **系统级** | 运维装机下发(只读亦可) | **Windows** `%ProgramData%\OperationRoomMonitor\voice_client.json`**macOS** `/Library/Application Support/OperationRoomMonitor/voice_client.json`**Linux** `/etc/operation-room-monitor/voice_client.json` |
| **用户级** | 在界面修改「服务端 Base URL」或「本机语音终端 ID」并 **离开输入框** 后自动保存 | **Windows** `%LOCALAPPDATA%\OperationRoomMonitor\voice_client.json`**macOS** `~/Library/Application Support/OperationRoomMonitor/voice_client.json`**Linux** `~/.config/operation-room-monitor/voice_client.json` |
测试或定制安装可用环境变量 **`VOICE_CLIENT_MACHINE_CONFIG_FILE`**、**`VOICE_CLIENT_USER_CONFIG_FILE`** 分别覆盖上述两个路径。
示例见 `voice_confirmation_client/resources/voice_client.sample.json`(通常用作系统级模板)。
## 日志loguru
客户端使用 **loguru****右侧日志区**与**启动终端 stderr** 会同时输出。开录无反应时请看是否出现「本机语音终端 ID 为空」、`WebSocket 已连接``收到 voice_assignment start`、或反复「WebSocket 断开」等行。
## 音频说明
- **播放 MP3**:优先使用本机 `ffplay`ffmpeg其次 macOS 使用 `afplay`;可将 `ffplay` 放到 `voice_confirmation_client/bin/`(与包同级目录下的 `bin/`)以便离线环境使用。
- **录音**:默认使用 **sounddevice** 录制并重采样为 16 kHz 单声道 WAV与浏览器 Demo 一致)。可选勾选 **优先使用 ffmpeg 录音**(依赖本机 ffmpeg 及可用的设备参数Windows 默认设备名可能需按现场调整,见 `voice_confirmation_client/core/record.py``default_ffmpeg_input_args`)。
## 打包PyInstaller
**目标操作系统** 上构建(不要交叉编译 Qt 桌面程序)。
```bash
uv sync --group voice-client-build
uv run --group voice-client-build pyinstaller voice_client.spec --noconfirm
# 或
uv run --group voice-client-build python scripts/build_voice_client.py
```
**Windows 一键打包(仓库根目录)**:双击或在 `cmd` 中执行 `build_voice_confirmation_client.bat`;需要干净构建时加参数 `--clean`(会先删除 `build/``dist/`)。
产物目录:`dist/voice-confirmation-client/`目录分发内含可执行文件。Windows 下可执行文件为 `voice-confirmation-client.exe`
**说明**
- 体积较大(含 PySide6杀毒软件可能对 PyInstaller 打包的 exe 误报,可向医院 IT 申请加白。
- **macOS**:未签名/未公证的 `.app` 可能需在「隐私与安全性」中手动允许;正式发布需 Apple 开发者签名与公证。
- **可选**:将 `ffmpeg`/`ffplay` 二进制放入打包目录下的 `voice_confirmation_bin/`,程序会优先使用(需在 spec 中增加 `datas` 将该目录打入包内,或手动复制到分发目录)。
## 术间排查
1. **网络**:客户端机器能访问监控服务 HTTP/HTTPS 端口(默认文档为 `38080`)。
2. **麦克风**:在「输入设备」中选择正确设备;无列表时检查系统隐私权限(麦克风)。
3. **无待确认**:轮询返回 404 为常态;可关闭「隐藏 404 轮询日志」观察请求节奏。
4. **解析失败**:使用 **重试本轮** 重新播放 + 录音 + 上传;或使用 **仅重播话术** 听清提示。
## 与浏览器 Demo 的差异
- 浏览器 Demo`scripts/demo_client/`)默认 **10 秒** 轮询;本客户端默认 **5 秒**,可在界面修改。
- 本客户端无「开始/结束手术」按钮;手术需由既有流程或他端调用 `POST /client/surgeries/start` 启动;若启用自动指派,开录成功后本机将自动开始待确认轮询。