Files

100 lines
5.8 KiB
Markdown
Raw Permalink Normal View History

# 手术室耗材语音确认客户端(桌面版)
独立桌面程序:按可配置间隔(默认 **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` 启动;若启用自动指派,开录成功后本机将自动开始待确认轮询。