# vinput-studio **Repository Path**: migeking_admin/vinput-studio ## Basic Information - **Project Name**: vinput-studio - **Description**: 基于 fcitx5-vinput 的 Linux 语音输入方案:按住右 Alt 说话即输,本地 sherpa-onnx 离线识别,可切豆包云端 ASR,支持 MTran AI 后处理与 HTTP ASR 网关(第三方接入) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-03 - **Last Updated**: 2026-08-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vinput-studio 语音输入

按住 右 Alt 说话,松开即可输入文字。

**vinput-studio** 是一套基于 **fcitx5-vinput** 的 Linux 桌面语音输入方案,整理为独立项目。语音识别默认在本地完成(sherpa-onnx),断网也能用;也可一键切换到豆包云端 ASR;可选接入 MTran 翻译服务做 AI 后处理。 ## 功能特性 - **本地离线识别**:语音默认不离开设备,纯 CPU 运行,无需 GPU,断网可用。 - **中英混合带标点**:默认模型支持中英文混合识别,自动输出标点。 - **按住即说**:按住 右 Alt 录音,松开识别,与打字输入无缝切换。 - **热键自定义**:触发键、命令键、场景菜单、ASR 菜单、翻页键均可改。 - **云端 ASR 可切换**:本地 sherpa-onnx 与豆包大模型 ASR 一键切换。 - **LLM 后处理**:命令模式 / 翻译等场景,可接 MTran 翻译服务改写或翻译文本。 - **一键部署与检查**:`install.sh` 部署配置与脚本(自动备份),`check.sh` 全项状态检查。 ## 架构 ``` ┌─────────────┐ Fcitx 5 输入框架 │ 应用窗口 │ └──────┬──────┘ │ 输入法事件(D-Bus) ┌──────▼──────┐ 系统包:fcitx5-vinput (2.3.3) │ fcitx5-vinput.so │ (addon) │──► 拉起 /usr/bin/vinput-daemon └──────┬──────┘ │ 触发热键:右 Alt(按住录音,松开识别) ┌──────▼──────────┐ │ vinput-daemon │ systemd user 服务 │ (录音 / VAD) │ /usr/share/systemd/user/vinput-daemon.service └──────┬──────────┘ │ PCM 音频 (stdin) ┌──────▼──────────────┐ │ ASR Provider │ 本地:sherpa-onnx zipformer (中英带标点) │ │ 云端:providers/doubao_batch.py (豆包) └──────┬──────────────┘ │ 识别文本(可选后处理) ┌──────▼──────────────┐ │ LLM Adapter │ adapters/mtranserver_proxy.py │ │ OpenAI 兼容翻译服务 └─────────────────────┘ ``` ## 目录结构 ``` vinput-studio/ ├── README.md # 本文件:项目主页 ├── index.html # 介绍性落地页(浏览器打开) ├── config/ │ ├── vinput-config.json # vinput 主配置(ASR 提供商、VAD、场景) │ └── fcitx5-vinput.conf # Fcitx5 热键配置 ├── providers/ │ ├── doubao_batch.py # 豆包云端 ASR provider(纯 Python) │ └── sherpa_local.py # sherpa-onnx 本地 ASR provider(离线识别) ├── adapters/ │ ├── mtranserver_proxy.py # MTran 翻译代理(纯 Python) │ └── asr_gateway.py # HTTP ASR 网关(托管网页前端 + 第三方 API) ├── frontend/ # 网页前端(Vue 3 + Vite,推荐入口) │ ├── src/ # UI 组件 / API 客户端 / 录音引擎 │ └── dist/ # 构建产物(npm run build 后由网关同源托管) ├── scripts/ │ ├── install.sh # 一键部署(配置 + 自写脚本,自动备份) │ ├── uninstall.sh # 移除部署 │ ├── check.sh # 状态检查(addon/daemon/模型/热键) │ └── start-web.sh # 一键启动网页服务(前端 + ASR + 聊天代理) └── docs/ ├── ARCHITECTURE.md # 组件与协议详细说明 ├── QUICKSTART.md # 新手快速上手 ├── HOTKEYS.md # 热键详解与自定义 ├── MODELS.md # 本地语音模型说明 ├── ASR_PROVIDERS.md # ASR 提供商与协议 └── FAQ.md # 常见问题排查 ``` ## 快速开始 ```bash # 1. 安装依赖(fcitx5-vinput 系统包,已装可跳过) sudo apt install fcitx5-vinput # 2. 部署本项目配置与脚本到系统位置 ./scripts/install.sh # 3. 检查状态 ./scripts/check.sh # 4. 重新加载 Fcitx5 生效 fcitx5-remote -r ``` 之后按住 右 Alt 说话,松开即输入文字。 ## 热键(config/fcitx5-vinput.conf) | 功能 | 热键 | |---|---| | 触发语音输入(按住说话/切换) | 右 Alt | | 命令模式 | 右 Ctrl | | 场景菜单 | 右 Shift | | ASR 菜单 | F8 | | 候选上一页 | Page Up | | 候选下一页 | Page Down | 修改热键:编辑 `config/fcitx5-vinput.conf` → `./scripts/install.sh` → `fcitx5-remote -r`。 详见 [docs/HOTKEYS.md](docs/HOTKEYS.md)。 ## ASR 提供商 | | 本地 sherpa-onnx(默认) | 豆包云端 | |---|---|---| | 模型 | zipformer transducer,中英混合带标点 | 豆包 bigmodel flash | | 网络 | 不需要 | 需要 | | 延迟 | 松开后整段识别 | 上传识别 | | 配置 | 无需额外配置 | 填写 APP_ID / ACCESS_TOKEN | 切换方式:编辑 `config/vinput-config.json` 中 `asr.active_provider`。 详见 [docs/ASR_PROVIDERS.md](docs/ASR_PROVIDERS.md)。 ## LLM 后处理(可选) `adapters/mtranserver_proxy.py` 把本地 MTran 翻译服务包装成 OpenAI 兼容接口,供 vinput 的 LLM 场景(命令模式 `__command__`、翻译)使用。 ```bash python3 adapters/mtranserver_proxy.py # 默认 http://127.0.0.1:8990,上游 MTran 默认 http://localhost:8989 # 环境变量:MTRAN_PORT / MTRAN_URL / MTRAN_TOKEN ``` ## HTTP ASR 网关(第三方接入) `adapters/asr_gateway.py` 把 ASR Provider 协议(stdin PCM → stdout 文本)包装成 OpenAI 兼容的 HTTP 接口,同时**托管构建后的 Vue 前端**(`frontend/dist`), 供浏览器直接访问(同源、无跨域): ```bash # 启动网关(默认 http://127.0.0.1:8991,识别走豆包云端 ASR) python3 adapters/asr_gateway.py ``` ### 使用本地模型(sherpa-onnx,离线识别) 网关默认走豆包云端;要第三方调用**本地模型**,先装 sherpa-onnx 运行时(一次性): ```bash python3.12 -m venv ~/.local/share/vinput/venv ~/.local/share/vinput/venv/bin/pip install sherpa-onnx numpy ``` 然后以本地识别启动网关: ```bash GATEWAY_PROVIDER=sherpa python3 adapters/asr_gateway.py ``` - 模型自动定位 `~/.local/share/vinput/models/sherpa-onnx/`(默认 `x-asr-zipformer-zh-en-punct-int8`,中英混合带标点;也可用 `VINPUT_SHERTA_MODEL` 切换流式 CTC 模型) - 每次请求独立进程加载模型(约 3-4 秒),请求量大时建议 `GATEWAY_TIMEOUT` 调大到 120 - 页面调用时也可在"设置 → Provider"里选 `sherpa(本地)`,无需重启网关 ### 端点 | 端点 | 方法 | 说明 | |---|---|---| | `/` | GET | 构建后的 Vue 前端页面(同源托管) | | `/v1/audio/transcriptions` | POST | 上传音频,返回 `{"text": "..."}` | | `/v1/chat/completions` | POST | 可选:转发到 `GATEWAY_LLM_URL`(如 MTran 代理) | | `/v1/models` | GET | 可用 Provider 列表 | | `/v1/config` | GET | 网关能力:provider / llm / web 托管状态 | | `/health` | GET | 存活检查(不要求鉴权) | 音频要求 **16kHz / 单声道 / 16-bit PCM**(WAV 或裸 PCM 均可),三种上传方式: ```bash # 1. 原始音频(curl / 后端最简用法) curl -X POST http://127.0.0.1:8991/v1/audio/transcriptions \ -H "Content-Type: audio/wav" --data-binary @rec.wav # 2. OpenAI 兼容 multipart(file 字段) curl -X POST http://127.0.0.1:8991/v1/audio/transcriptions \ -F "file=@rec.wav" -F "model=whisper-1" # 3. JSON base64 curl -X POST http://127.0.0.1:8991/v1/audio/transcriptions \ -H "Content-Type: application/json" \ -d "{\"audio\": \"$(base64 -w0 rec.wav)\"}" ``` 浏览器前端(MediaRecorder 录音 → FormData 上传): ```js const form = new FormData(); form.append("file", blob, "rec.wav"); // blob 为 16k 单声道录音 const res = await fetch("http://127.0.0.1:8991/v1/audio/transcriptions", { method: "POST", body: form, }); const { text } = await res.json(); ``` ### 环境变量 | 变量 | 默认 | 说明 | |---|---|---| | `GATEWAY_PORT` | `8991` | 监听端口 | | `GATEWAY_HOST` | `127.0.0.1` | 绑定地址;`0.0.0.0` 可暴露到局域网 | | `GATEWAY_TOKEN` | 空 | 设置后 `/v1/*` 需 `Authorization: Bearer ` | | `GATEWAY_CORS_ORIGIN` | `*` | CORS 允许来源 | | `GATEWAY_PROVIDER` | `doubao` | 识别后端:`sherpa`(本地)/ `doubao`(云端)/ `custom` | | `GATEWAY_WEB_DIR` | 自动定位 | 前端构建目录(默认 `frontend/dist` 或 `web/dist`) | | `GATEWAY_LLM_URL` | 空 | 聊天代理上游(如 `http://127.0.0.1:8990`),空 = 关闭 | | `GATEWAY_LLM_TOKEN` | 空 | 转发给 LLM 上游的 Bearer Token | | `GATEWAY_DOUBAO_CMD` | 自动定位 | 豆包 provider 脚本命令(覆盖自动查找) | | `GATEWAY_PROVIDER_CMD` | 空 | `custom` 提供商命令(测试/自定义用) | | `GATEWAY_SHERTA_CMD` | 自动定位 | sherpa provider 命令(覆盖自动查找) | | `GATEWAY_SHERTA_PYTHON` | `~/.local/share/vinput/venv/bin/python3` | 装有 sherpa-onnx 的解释器 | | `GATEWAY_MAX_BYTES` | `20971520` | 请求体大小上限(字节) | | `GATEWAY_TIMEOUT` | `60` | Provider 识别超时(秒) | 豆包凭据沿用 `VINPUT_ASR_APP_ID` / `VINPUT_ASR_ACCESS_TOKEN` / `VINPUT_ASR_RESOURCE_ID` 环境变量。 ### 安全注意 - 默认只绑定 `127.0.0.1`,仅本机可访问;需要跨机器/公网使用时务必 先设置 `GATEWAY_TOKEN`,再以 `GATEWAY_HOST=0.0.0.0` 启动。 - `sherpa` 本地识别完全离线,音频不出设备;`doubao` 需网络与凭据。 ## 网页前端(Vue 3 + Vite) `frontend/` 是基于 **Vue 3 + Vite** 的语音对话前端(聊天 / 录音识别 / 上传 / LLM 回复), 替代旧的静态页 `web/voice-chat.html`(静态页与后端交互有跨域、URL 配置等一堆问题)。 核心思路:**让 ASR 网关直接托管前端构建产物**,页面与 API 同源,彻底消除跨域。 ```bash cd frontend npm install # 首次 npm run dev # 开发:http://127.0.0.1:5173(/v1 自动代理到 8991,无跨域) npm run build # 生产构建 → frontend/dist ``` ```bash cd frontend npm install # 首次 npm run dev # 开发:http://127.0.0.1:5173(/v1 自动代理到 8991,无跨域) npm run build # 生产构建 → frontend/dist ``` 构建后启动网关即可访问整个应用(同源,无需任何配置): ```bash GATEWAY_LLM_URL=http://127.0.0.1:8990 python3 adapters/asr_gateway.py # 浏览器打开 http://127.0.0.1:8991 ``` ### 一键启动 `scripts/start-web.sh` 自动选择 provider 并拉起前端 + 聊天代理: ```bash ./scripts/start-web.sh # 已装本地 sherpa 则自动选 sherpa,否则豆包 ./scripts/start-web.sh --no-llm # 不启动 MTran 聊天代理 ``` - 首页左上角有网关在线状态(每 15s 自动检测,点击可刷新) - ⚙ 设置:网关地址(留空 = 同源)、Token、Provider、LLM 聊天开关(自动持久化) - 📋 请求日志:实时查看每次 API 调用与耗时 - 麦克风录音自动转 16kHz/单声道 WAV 上传;也支持直接上传 WAV 或输入文字 - 环境变量 `GATEWAY_WEB_DIR` 可覆盖前端目录;`GATEWAY_LLM_URL` 开启聊天代理 - 调试:`http://127.0.0.1:8991/?engine=worklet` 强制 AudioWorklet 采集管线 ## 系统服务 - `vinput-daemon.service`:系统包自带,开机自启,负责录音与识别调度。 状态:`systemctl --user status vinput-daemon`,重启:`systemctl --user restart vinput-daemon` - `vocotype.service`(可选):另一独立 VoCoType 后端,与本项目互不干扰。 ## 文档导航 | 文档 | 内容 | |---|---| | [docs/QUICKSTART.md](docs/QUICKSTART.md) | 新手快速上手 | | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | 组件与协议详解 | | [docs/HOTKEYS.md](docs/HOTKEYS.md) | 热键详解与自定义 | | [docs/MODELS.md](docs/MODELS.md) | 本地语音模型说明 | | [docs/ASR_PROVIDERS.md](docs/ASR_PROVIDERS.md) | ASR 提供商与协议 | | [docs/FAQ.md](docs/FAQ.md) | 常见问题排查 | | [index.html](index.html) | 介绍性落地页 | ## 许可证 fcitx5-vinput 及本项目的脚本遵循各自上游许可证。