# SmartMeeting 智能会议 这是一个基于 Docker Compose 的智能会议部署项目,包含 Speakr 前后端、Paraformer ASR、声纹向量提取服务,以及实时 WebSocket 转写桥接服务。 ## 目录结构 ```text /storage01/home/xll/202607/voice ├── docker-compose.yml # 统一启动文件 ├── config.env # 运行环境变量,主要改这里 ├── asr/main.py # ASR 适配服务代码 ├── speakr/ # Speakr 前后端代码 ├── voice-dected/ # 声纹向量提取服务代码 ├── fastapi_wss/ # 实时 WebSocket 桥接服务代码 └── deploy/data/ # 运行数据,已被 git 忽略 ``` ## 启动和停止 启动全部服务: ```bash cd /storage01/home/xll/202607/voice docker compose up -d ``` 查看状态和日志: ```bash docker compose ps docker compose logs -f ``` 停止服务: ```bash docker compose down ``` ## 服务和端口 | 服务 | 容器名 | 端口 | 作用 | | --- | --- | --- | --- | | Speakr | `voice-speakr` | `8899` | 页面和后端 | | ASR | `asr-test` | `59805` | Paraformer HTTP / WebSocket 识别 | | 声纹提取 | `voice-dected` | `18000` | `/extract_embedding` 声纹向量服务 | | 实时桥接 | `fastapi-wss` | `10095` | 页面实时 ASR WebSocket 桥接 | | Redis | `voice-redis` | `16380` | 实时桥接的缓存/会话存储 | 页面访问地址: ```text http://192.168.0.46:8899/tool/speakr/ ``` 浏览器麦克风录音需要安全上下文。局域网 IP 的 HTTP 页面可能无法调用麦克风。最快的本机访问方式是开 SSH 隧道: ```bash ssh -L 8899:127.0.0.1:8899 xll@192.168.0.46 ``` 然后浏览器打开: ```text http://localhost:8899/tool/speakr/ ``` ## 配置文件 主要修改这个文件: ```text /storage01/home/xll/202607/voice/config.env ``` 改服务地址、模型地址、LLM 配置、声纹匹配阈值时,优先改 `config.env`。修改后执行: ```bash cd /storage01/home/xll/202607/voice docker compose up -d ``` 重要变量: ```env ASR_BASE_URL=http://asr-test:59805 FUNASR_WEBSOCKET_IP=ws://fastapi-wss:10095/websocket_offline TARGET_WS_URL=ws://asr-test:59805/ws/asr VOICE_DETECTED_URL=http://voice-dected:8000 SPEAKER_DET_URL=http://voice-dected:8000/extract_embedding REDIS_URL=redis://redis:6379/0 TEXT_MODEL_BASE_URL=http://192.168.0.46:59800/v1 TEXT_MODEL_NAME=46-qwen3.5-35B TEXT_MODEL_API_KEY=none VOICEPRINT_STORE=/data/asr_voiceprints.json VOICEPRINT_MATCH_THRESHOLD=0.45 ``` 说明: - Compose 内部服务互相访问时,用 `asr-test`、`voice-dected`、`redis` 这种服务名。 - 宿主机或外部机器访问时,用 `192.168.0.46:59805`、`192.168.0.46:18000`、`192.168.0.46:10095` 这种宿主机端口。 - `FUNASR_WEBSOCKET_IP` 是 Speakr 后端实时录音代理要连接的 WebSocket 地址。 - `TARGET_WS_URL` 是 `fastapi-wss` 再往后连接的 ASR WebSocket 地址。 - `VOICEPRINT_MATCH_THRESHOLD` 是声纹匹配阈值。值越低越容易匹配,值越高越不容易误匹配。 ## 运行数据 运行数据放在: ```text /storage01/home/xll/202607/voice/deploy/data/ ``` 常见子目录: ```text deploy/data/speakr/uploads/ # 上传和录音文件 deploy/data/speakr/instance/ # Speakr SQLite 数据库 deploy/data/asr/ # ASR 声纹库 deploy/data/redis/ # Redis 持久化数据 ``` 这些运行数据已被 `.gitignore` 忽略,不会提交到仓库。 ## 声纹流程 Speakr 声纹管理页面会调用 ASR 适配层的兼容接口: ```text POST /voice_insert GET /get_voice_name DELETE /delete_voice ``` ASR 适配层会把声纹向量保存到: ```text deploy/data/asr/asr_voiceprints.json ``` 转录时,`/asr` 会先把上传音频转成 `16k 单声道 wav`,再调用 `voice-dected` 提取声纹向量,并和已录入声纹做相似度匹配。如果分数超过 `VOICEPRINT_MATCH_THRESHOLD`,返回匹配到的说话人名称。 目前这个逻辑是“整段音频匹配一个最像的人”。如果一段录音里多人轮流说话,还需要进一步接入分段说话人识别。 ## 常用检查命令 检查 ASR: ```bash curl http://127.0.0.1:59805/health ``` 检查声纹列表: ```bash curl http://127.0.0.1:59805/get_voice_name ``` 检查 Speakr 配置: ```bash curl http://127.0.0.1:8899/tool/speakr/api/config ``` 检查实时 WebSocket 链路: ```bash docker exec -it fastapi-wss python - <<'PY' import asyncio, json, websockets async def main(): async with websockets.connect("ws://127.0.0.1:10095") as ws: await ws.send(json.dumps({"mode": "2pass", "is_speaking": True})) await ws.send(json.dumps({"type": "stop", "is_speaking": False})) print(await ws.recv()) asyncio.run(main()) PY ``` ## Git 操作 仓库地址: ```text https://gitea.zkzdht.com/Ascend/SmartMeeting.git ``` 常用命令: ```bash cd /storage01/home/xll/202607/voice git status git add . git commit -m "更新说明" git push ```