# dsh-voice-mic [English](README.en.md) DeepSeek Harness Web GUI 语音输入插件。录音后实时转写并写入输入框,不自动发送。 ## 安装 要求:dsh `>=0.1.0-rc.6`、Node.js `>=18`。浏览器识别需 Chrome/Edge;本地后端另需 Python `3.9+`。 ```bash dsh plugin --profile web add github:Zachary7456/dsh-voice-mic # 或(npm 发布后):dsh plugin --profile web add dsh-voice-mic ``` 安装后重启 `dsh web`。插件带 bundle patch,会自动挂进 profile,无需手动改 `cordis.patch.yml`。 验证: ```bash dsh --profile web --dump-config | grep dsh-voice-mic curl -s http://127.0.0.1:3080/plugins/dsh-voice-mic/client.js | head -c 100 ``` ## 使用 - 输入框左侧麦克风按钮:点按切换录音,默认快捷键 `Alt+V`(设置页可改) - 录音期间识别结果实时写入输入框草稿;停止后提交,不自动发送 - 快捷键仅在页面获得焦点时生效(浏览器限制) - 实时写入采用追尾替换:只更新上次追加的尾缀,不覆盖手动输入;无结果或出错时自动回滚 ## 识别引擎 设置 → 语音输入 → 识别引擎,三选一。 ### 浏览器内置(默认) 零配置,走 Web Speech API。中文质量与延迟取决于浏览器与网络。说话停顿导致浏览器自行断开识别会话时,插件自动重启识别器继续监听,直到手动停止。 ### 本地离线后端 设置页一键部署:检测 Python → pip 安装依赖 → 下载模型(断点续传,可取消)→ 启动 `asr_server.py` → 轮询就绪。已下载的模型会缓存,切换模型免重复下载。 模型: | 模型 | 适用 | 大小 | |---|---|---| | SenseVoiceSmall int8 | 中/英/日/韩/粤,日常使用 | ~158MB | | Paraformer | 仅普通话,准确率与标点最佳 | ~223MB | - 模型目录:`~/.dsh/voice/models/`(可用 `DSH_VOICE_MIC_MODEL_DIR` 覆盖);下载缓存:`~/.dsh/voice/cache` - 服务端口默认 `7860`,只绑定 `127.0.0.1` - 后端进程由 dsh 托管:dsh 重启后需重新点部署(或配置 `autoStart: true` 自动拉起) - 转写期间音频不出本机 ### 云端 API OpenAI 兼容的 `POST /v1/audio/transcriptions`(multipart `file` + `model`,返回 `{text}`)。需配置 base URL、API key、模型名;内置 OpenAI / Groq / 硅基流动预设。密钥存于浏览器 localStorage,由浏览器直连服务商,不经过 dsh。 设置页「测试 API 连接」发送静音样本验证配置:`401/403` 为密钥错误,`404` 通常表示填了完整端点而不是 base URL。 离线验证完整链路可用仓库内的 mock 服务: ```bash python server/mock_api.py # 127.0.0.1:7861/v1,key 任意 ``` 实时上屏时录音期间约每秒调用一次 API,会产生相应费用。 ## 工作原理 两半结构: ``` lib/index.js host 半:配置下发(GET /config)、后端部署管理(/backend/status|deploy|cancel|stop) lib/client.js client 半:输入框按钮与快捷键、录音、转写、设置页 server/ 本地 ASR 服务(sherpa-onnx + SenseVoice/Paraformer)与 API mock ``` 录音与转写: - 浏览器引擎:Web Speech 的 interim 结果直接上屏,final 累积,仅在显式停止/超时/致命错误时结束会话 - 后端/API 引擎:AudioContext 直采 PCM → 16kHz WAV;录音期间每 1 秒将累积音频送转写(部分结果上屏,按序号丢弃过期响应);停止时全量转写一次提交 - 三种引擎共用同一录音采集与上屏逻辑,仅转写函数不同 部署流程(host 半):`findPython` → 依赖自检 → 模型自检/下载 → `spawn asr_server.py`(注入 `DSH_VOICE_MIC_MODEL_DIR/TYPE`)→ `/health` 轮询就绪。下载与安装步骤可由 `/backend/cancel` 中断。 ## 配置 设置页可改全部用户配置(存浏览器 localStorage)。服务端配置亦可: ```yaml # ~/.dsh/profiles/web/cordis.patch.yml - insert: - id: dsh-voice-mic name: dsh-voice-mic config: hotkey: alt+v port: 7860 autoStart: false ``` 环境变量: | 变量 | 作用 | 默认 | |---|---|---| | `DSH_VOICE_MIC_HOTKEY` | 快捷键 | `alt+v` | | `DSH_VOICE_MIC_LANG` | 浏览器识别语言 | `zh-CN` | | `DSH_VOICE_MIC_BACKEND` | 本地后端地址 | 空 | | `DSH_VOICE_MIC_PORT` | 后端端口 | `7860` | | `DSH_VOICE_MIC_MODEL_TYPE` | 默认模型类型 | `sensevoice-small-int8` | | `DSH_VOICE_MIC_MODEL_DIR` | 模型目录 | `~/.dsh/voice/models/` | | `DSH_VOICE_MIC_AUTOSTART` | 启动时自动部署后端 | `false` | | `DSH_VOICE_MIC_API_BASE` / `_MODEL` / `_KEY` | 云端 API 配置 | 空 | 优先级:设置页(localStorage)> 环境变量 > cordis 配置 > 默认值。 ## 测试 ```bash node test/smoke.mjs # 两半插件加载/路由/配置合并 node test/verify-install.mjs # 已安装实例的激活检查 node test/deploy-test.mjs # 一键部署端到端(占用 7862 端口) node test/e2e-backend.mjs [url] # 本地后端转写 node test/e2e-api.mjs [base] [key] [model] # 云端 API 协议(配合 server/mock_api.py) ``` ## 开发 无构建步骤,直接改 `lib/*.js`。client 半改动刷新页面即生效;host 半改动需重启 `dsh web`。 ## License MIT