# 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