Skip to content

kcd-dev/voice-input

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mason Voice Input

Mason Voice Input 是一个面向 macOS 的轻量语音输入工具:按快捷键或执行命令开始录音,把音频发送到一个 兼容的语音转文字 HTTP 服务,拿到文字后自动写入剪贴板,并可 自动粘贴到当前光标位置

它适合想要“像系统语音输入一样快速说话输入”,但又希望识别服务可以自由选择的人:你可以接 自建 faster-whisper/Whisper 服务,也可以通过一个轻量 adapter 接 第三方语音转文字服务。当前版本 不是完整输入法,也 不内置 Whisper 模型;它是一个本地客户端,需要配合一个 HTTP 语音转文字服务使用

Why do this / 为什么要做这个

很多输入法都已经支持语音输入,但它们通常是一个完整的输入法产品:功能多、接入深、权限也更多。以常见商业输入法为例,语音转文字往往需要在使用时上传语音到服务端处理,部分增强功能还可能涉及输入内容、剪贴板、词库、跨设备同步等数据处理。

Mason Voice Input 想解决的是另一个更小、更透明的问题:

我只想在 macOS 上快速说一句话,把它变成文字,并粘贴到当前输入框;识别服务、数据流向和接口格式都由我自己决定。

所以这个项目刻意保持简单:

  • 不是完整输入法:不接管系统输入法,不做候选词、词库、联想、账号体系。
  • 客户端不内置云服务:默认只请求你配置的 api_url,可以是本机服务、远程自建服务,或你自己写的第三方 adapter。
  • 接口透明:音频以 multipart/form-data 上传到 /upload,返回 JSON 文本;README 里写清楚请求和响应格式。
  • 不把 API Key 放进客户端:如果接第三方 STT,推荐放在 adapter 或服务端环境变量里,而不是写进 App 或仓库。
  • 默认不保存录音历史:临时音频使用后删除;只有你显式加 --keep 才保留。
  • 开源可审计:你可以直接看代码确认录音、上传、剪贴板和粘贴流程。

它不是为了替代所有输入法,而是给需要 可控、轻量、可自建、可审计 的用户一个选择。

它解决什么问题

你说话
  ↓
Mac 本地录音
  ↓
发送到语音转文字 HTTP API
  ↓
返回文字
  ↓
写入剪贴板 / 自动粘贴到当前应用

你可以用它在浏览器、Obsidian、微信、备忘录、编辑器等任何能输入文字的地方快速输入。

当前功能

  • macOS 本地录音。
  • 支持固定时长录音:record-once
  • 支持 VAD 自动停顿断句:listen-auto
  • 支持转写本地音频文件:transcribe-file
  • 支持把结果写入剪贴板。
  • 支持自动模拟 Cmd+V 粘贴到当前应用。
  • 支持简单文本后处理:去掉明显重复片段和重复标点。
  • 支持可选 SSH 本地端口转发,方便连接远程 Whisper 服务。
  • 附带一个 macOS 菜单栏热键程序原型:mason-voice-hotkey

当前不是什么

  • 不是完整 macOS 输入法 IME。
  • 不内置 Whisper / faster-whisper 模型。
  • 不是真流式识别;listen-auto 是本地分段后上传。
  • 不负责提供云服务账号。
  • 不保存你的录音历史;默认临时音频会在使用后删除。

系统要求

项目 要求 说明
系统 macOS 目前录音使用 ffmpeg avfoundation,主要面向 macOS。
Go 1.20+ 建议 用来编译 CLI。
ffmpeg 必需 用来录音、列出麦克风设备。
pbcopy macOS 自带 用来写剪贴板。
cliclick 可选 用来更稳定地模拟粘贴;没有时会降级到 AppleScript。
ssh 可选 如果你的 Whisper 服务在远程服务器上,可用 SSH tunnel。
语音转文字 HTTP API 必需 需要提供兼容 /upload 的接口;第三方服务通常需要 adapter 转成该格式。

一、安装依赖

1. 安装 Homebrew

如果你还没有 Homebrew,先到官网按提示安装:

https://brew.sh/

2. 安装 ffmpeg

brew install ffmpeg

检查是否安装成功:

ffmpeg -version

能看到版本信息就说明成功。

3. 可选:安装 cliclick

cliclick 用来模拟按下 Cmd+V,自动粘贴会更稳定。

brew install cliclick

不安装也能用,只是自动粘贴会降级到 AppleScript;如果粘贴失败,文字仍会在剪贴板里,你可以手动 Cmd+V

二、准备语音转文字 HTTP 服务

本项目默认请求这个地址:

http://127.0.0.1:19000/upload

也就是说,你需要有一个本地或远程服务,能接收音频文件上传并返回 JSON 文字。这个服务可以是自建的 faster-whisper/Whisper 服务,也可以是你写的第三方服务 adapter。

当前客户端直连支持的接口格式

当前 CLI 直连支持的是一个 multipart upload 格式,路径固定为 /upload

请求方式:

POST /upload?task=transcribe&batch_size=5&timestamp=chunk&diarise_audio=false
Content-Type: multipart/form-data

表单字段:

字段 类型 必需 说明
file 文件 要识别的音频文件,来自本地录音或 transcribe-file

客户端会自动追加这些 query 参数:

参数 示例 说明
task transcribe 表示转写,不做翻译。
batch_size 5 传给后端的批处理大小。
timestamp chunk 兼容部分 faster-whisper HTTP 服务的参数。
diarise_audio false 不做说话人分离。
language zh / en 仅当配置不是 auto 时才会追加。

返回 JSON 至少需要包含以下任意一种字段:

{"text":"识别出来的文字"}

或:

{"output":{"text":"识别出来的文字"}}

也支持:

{"result":{"text":"识别出来的文字"}}
{"data":{"text":"识别出来的文字"}}

支持哪些第三方服务格式

当前客户端 不直接内置第三方厂商鉴权和各家专有 API 格式。为了避免把 API Key 写进客户端,推荐用一个本地或服务器上的 adapter 做转换:

Mason Voice Input
  -> POST /upload multipart/form-data
  -> 你的 adapter
  -> OpenAI / Groq / Deepgram / AssemblyAI / 其他 STT 服务
  -> adapter 返回 {"text":"..."}
服务类型 当前是否可直接调用 推荐接入方式 adapter 需要做什么
自建 faster-whisper HTTP 服务 是,如果接口兼容 /upload 直接把 api_url 指向服务地址 返回 textoutput.text
自建 Whisper 服务 是,如果你封装成 /upload 直接接入或加一层 adapter 接收 file,调用模型,返回 text
OpenAI Audio Transcriptions 否,当前不直连 写 adapter adapter 持有 API Key,把 /upload 转成厂商转写请求,再返回 text
Groq / OpenAI-compatible Whisper 类接口 否,当前不直连 写 adapter 同上,隐藏 Key 和厂商差异。
Deepgram / AssemblyAI 等第三方 STT 否,当前不直连 写 adapter 把 multipart 文件转换成厂商要求的请求,再统一返回 text

一句话:客户端只认 /upload + file + JSON text。任何第三方服务只要通过 adapter 转成这个格式,就可以接入。

例子 1:兼容服务的最小请求和响应

Mason Voice Input 最终会发出类似这样的请求:

curl -X POST \
  -F "file=@demo.wav" \
  "http://127.0.0.1:19000/upload?task=transcribe&batch_size=5&timestamp=chunk&diarise_audio=false"

一个最小可用响应长这样:

{
  "text": "你好,这是一段语音识别结果。"
}

或者长这样也可以:

{
  "output": {
    "text": "你好,这是一段语音识别结果。"
  }
}

只要你的服务能做到这件事,客户端就能直接接入。

例子 2:把 OpenAI/Groq-compatible 转写接口包装成 /upload

很多第三方转写接口不是 /upload,而是类似:

POST https://example.com/v1/audio/transcriptions
Authorization: Bearer <你的 API Key>
multipart/form-data:
  file=@demo.wav
  model=whisper-large-v3

这时不要把 API Key 写进 Mason Voice Input 客户端。推荐做一个 adapter:

Mason Voice Input
  -> http://127.0.0.1:19000/upload
  -> 你的 adapter
  -> 第三方 /v1/audio/transcriptions
  -> adapter 返回 {"text":"..."}

下面是一个 Go 标准库版最小 adapter 模板。它接收 Mason Voice Input 的 /upload 请求,再转发到一个 OpenAI-compatible 的转写接口。

注意:这是模板。不同厂商的字段名、模型名、返回 JSON 可能不同,你只需要改环境变量和解析字段即可。

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	addr := env("ADAPTER_ADDR", ":19000")
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		_, _ = w.Write([]byte("ok"))
	})
	http.HandleFunc("/upload", handleUpload)
	log.Println("adapter listening on", addr)
	log.Fatal(http.ListenAndServe(addr, nil))
}

func handleUpload(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
		return
	}

	file, header, err := r.FormFile("file")
	if err != nil {
		http.Error(w, "missing form file: file", http.StatusBadRequest)
		return
	}
	defer file.Close()

	var body bytes.Buffer
	mw := multipart.NewWriter(&body)

	fw, err := mw.CreateFormFile("file", header.Filename)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if _, err := io.Copy(fw, file); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// OpenAI/Groq-compatible 转写接口通常需要 model 字段。
	_ = mw.WriteField("model", env("STT_MODEL", "whisper-large-v3"))

	// 如果你的厂商支持 language,可以按需传;不需要就删掉。
	if lang := os.Getenv("STT_LANGUAGE"); lang != "" && lang != "auto" {
		_ = mw.WriteField("language", lang)
	}

	if err := mw.Close(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	upstreamURL := env("STT_TRANSCRIBE_URL", "https://example.com/v1/audio/transcriptions")
	req, err := http.NewRequest(http.MethodPost, upstreamURL, &body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	req.Header.Set("Content-Type", mw.FormDataContentType())
	if key := os.Getenv("STT_API_KEY"); key != "" {
		req.Header.Set("Authorization", "Bearer "+key)
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadGateway)
		return
	}
	defer resp.Body.Close()

	respBody, _ := io.ReadAll(resp.Body)
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		http.Error(w, fmt.Sprintf("upstream status=%d body=%s", resp.StatusCode, string(respBody)), http.StatusBadGateway)
		return
	}

	// 兼容常见返回:{"text":"..."}
	var parsed struct {
		Text string `json:"text"`
	}
	if err := json.Unmarshal(respBody, &parsed); err != nil || parsed.Text == "" {
		http.Error(w, "upstream response missing text", http.StatusBadGateway)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	_ = json.NewEncoder(w).Encode(map[string]string{"text": parsed.Text})
}

func env(k, fallback string) string {
	if v := os.Getenv(k); v != "" {
		return v
	}
	return fallback
}

运行方式示例:

export STT_TRANSCRIBE_URL="https://example.com/v1/audio/transcriptions"
# 不要把真实 Key 写进 README;请只在本机 shell 或服务端环境变量里设置
export STT_API_KEY="<YOUR_STT_API_KEY>"
export STT_MODEL="whisper-large-v3"
go run ./adapter.go

然后 Mason Voice Input 配置成:

mason-voice-input setup \
  --api-url http://127.0.0.1:19000 \
  --device 0

例子 3:不同服务应该怎么映射

你的服务 Mason Voice Input 发给 adapter adapter 发给第三方 adapter 返回给客户端
自建 faster-whisper POST /upload + file 可直接处理,或转内部模型 {"text":"..."}
OpenAI-compatible 转写 POST /upload + file POST /v1/audio/transcriptions + file + model {"text":"..."}
Groq-compatible Whisper POST /upload + file 类 OpenAI-compatible,模型名按厂商填写 {"text":"..."}
Deepgram / AssemblyAI POST /upload + file 按厂商要求上传音频、带鉴权 Header {"text":"..."}

例子 4:如果你的服务返回字段不是 text

假设第三方返回:

{
  "results": {
    "channels": [
      {
        "alternatives": [
          {"transcript": "你好世界"}
        ]
      }
    ]
  }
}

adapter 要把它转换成:

{
  "text": "你好世界"
}

Mason Voice Input 不关心第三方原始格式,只关心最后有没有 text

如果兼容服务就在本机

只要你的兼容服务或 adapter 监听在 127.0.0.1:19000,可以直接使用默认配置。

如果服务在远程服务器

你有两种方式。

方式 A:你自己先开 SSH 隧道:

ssh -N -L 19000:127.0.0.1:9000 your-ssh-host

这条命令的意思是:

部分 含义
ssh 通过 SSH 连接服务器。
-N 不执行远程命令,只做端口转发。
-L 19000:127.0.0.1:9000 把本机 19000 转发到服务器上的 127.0.0.1:9000
your-ssh-host 你的 SSH 主机名,可以是 user@example.com,也可以是 ~/.ssh/config 里的别名。

方式 B:把 ssh_hostssh_remote_hostssh_remote_port 写入配置,让工具自动尝试启动隧道。注意:ssh_remote_port 必须按你的服务实际端口显式设置,不会偷偷使用某台私有机器的默认端口。

三、编译安装

进入项目目录:

git clone <你的仓库地址> mason-voice-input
cd mason-voice-input

编译 CLI:

go build -buildvcs=false -o ./bin/mason-voice-input ./cmd/mason-voice-input

可选但推荐:把 CLI 放到你的 PATH 里。

mkdir -p ~/bin
cp ./bin/mason-voice-input ~/bin/mason-voice-input

如果你的 shell 还找不到 mason-voice-input,把这行加到 ~/.zshrc

export PATH="$HOME/bin:$PATH"

然后执行:

source ~/.zshrc

检查是否安装成功:

mason-voice-input help

四、第一次配置

1. 查看麦克风设备

mason-voice-input list-devices

你会看到类似输出:

AVFoundation audio devices:
[0] MacBook Pro Microphone
[1] Some External Microphone

记住你要用的音频设备编号,比如 01

2. 写入配置

假设你的麦克风编号是 0,兼容语音转文字服务地址是默认的 http://127.0.0.1:19000

mason-voice-input setup \
  --device 0 \
  --api-url http://127.0.0.1:19000 \
  --duration 8

如果你希望工具自动用 SSH 建隧道:

mason-voice-input setup \
  --device 0 \
  --api-url http://127.0.0.1:19000 \
  --local-port 19000 \
  --ssh-host your-ssh-host \
  --ssh-remote-host 127.0.0.1 \
  --ssh-remote-port 9000 \
  --duration 8

配置会保存到:

~/.config/mason-voice-input/config.json

查看当前配置:

mason-voice-input config

3. 检查环境

mason-voice-input doctor

它会检查:

  • ffmpeg 是否存在。
  • ffprobe 是否存在。
  • ssh 是否存在。
  • pbcopy 是否存在。
  • cliclick 是否存在。
  • Whisper API 是否能访问。

五、macOS 权限设置

第一次使用时,macOS 可能会弹权限提示。权限没给对时,录音或自动粘贴会失败。

麦克风权限

用途:允许录音。

路径:

系统设置 → 隐私与安全性 → 麦克风

你需要给实际运行命令的程序授权。常见是:

  • Terminal
  • iTerm2
  • 你使用的快捷键工具
  • MasonVoiceHotkey.app(如果你使用菜单栏热键程序)

辅助功能权限

用途:允许自动按 Cmd+V 粘贴文字。

路径:

系统设置 → 隐私与安全性 → 辅助功能

你需要给实际负责粘贴的程序授权。常见是:

  • Terminal
  • iTerm2
  • Raycast / Alfred / Keyboard Maestro
  • MasonVoiceHotkey.app

如果没有辅助功能权限,通常 识别仍然能成功,文字也会写入剪贴板,只是 不能自动粘贴。你可以手动 Cmd+V

六、基础使用

固定录音 8 秒

把光标放在输入框里,然后执行:

mason-voice-input record-once --duration 8

流程:

录音 8 秒 → 上传 → 转写 → 写剪贴板 → 自动粘贴

只写剪贴板,不自动粘贴

mason-voice-input record-once --duration 8 --no-paste

适合你想先看看识别结果,或者当前 App 不适合自动粘贴。

保留临时音频文件

mason-voice-input record-once --duration 8 --keep

默认临时音频会删除。加 --keep 后会保留,方便排查录音质量。

七、自动停顿识别 listen-auto

listen-auto 是推荐的日常模式:它会持续监听麦克风,用本地 VAD 状态机判断你什么时候开始说话、什么时候停顿结束,然后把每个片段上传识别。

识别一句话后退出

mason-voice-input listen-auto --once

适合绑定快捷键:按一下快捷键,说一句话,停顿后自动识别并退出。

持续监听

mason-voice-input listen-auto

Ctrl+C 结束。

常用调参

mason-voice-input listen-auto \
  --silence-ms 750 \
  --start-ms 180 \
  --min-segment-ms 800 \
  --max-segment-ms 25000 \
  --energy-threshold 0.018

参数解释:

参数 默认值 小白解释 什么时候要改
--start-ms 180 连续检测到声音多久后,才认为你真的开始说话。 经常被键盘声触发就调大;开头容易漏字就调小。
--silence-ms 750 你停顿多久后,认为一句话结束。 断句太早就调大;等太久才识别就调小。
--min-segment-ms 800 太短的声音会被当成噪声丢掉。 咳嗽、敲键盘误识别就调大;短词总被丢掉就调小。
--max-segment-ms 25000 单段最长时间,超过会强制切开。 长篇讲话被切太碎就调大;希望更快返回就调小。
--pre-roll-ms 300 保留说话前一点点音频,避免漏掉第一个字。 开头第一个字经常没了就调大。
--energy-threshold 0.018 声音能量阈值,超过才算“有声”。 环境吵就调高;说话轻总识别不到就调低。
--max-pending 2 最多允许几个片段排队上传。 网络慢但不想占太多资源就保持默认。
--listen-seconds 0 最多监听多久,0 表示一直监听。 想定时退出时设置。
--once false 第一个有效片段识别完成后退出。 快捷键触发时建议加。
--no-paste false 不自动粘贴,只写剪贴板。 调试或不想自动输入时加。
--keep false 保留切分后的临时 wav 文件。 排查录音质量时加。

八、转写已有音频文件

mason-voice-input transcribe-file /path/to/audio.mp3

写剪贴板但不粘贴:

mason-voice-input transcribe-file /path/to/audio.mp3 --clip

写剪贴板并自动粘贴:

mason-voice-input transcribe-file /path/to/audio.mp3 --paste

九、配置文件详解

配置文件位置:

~/.config/mason-voice-input/config.json

示例:

{
  "api_url": "http://127.0.0.1:19000",
  "ssh_host": "",
  "local_port": 19000,
  "ssh_remote_host": "127.0.0.1",
  "ssh_remote_port": 0,
  "device": "0",
  "language": "auto",
  "duration_seconds": 8,
  "paste": true,
  "batch_size": 5,
  "audio_codec": "mp3",
  "post_process": true
}

逐项解释:

配置项 类型 默认值 解释
api_url 字符串 http://127.0.0.1:19000 兼容语音转文字 HTTP API 的基础地址。程序会请求 api_url + /upload
ssh_host 字符串 可选。SSH 主机名。如果 API 不通且这里不为空,程序会尝试自动执行 SSH 本地端口转发。
local_port 数字 19000 本地端口。自动 SSH 转发时会使用它,例如监听本机 19000
ssh_remote_host 字符串 127.0.0.1 SSH 登录到远程机器后,要连接的远端服务 host。多数服务只监听远程机器本地地址,所以默认是 127.0.0.1
ssh_remote_port 数字 0 SSH 登录到远程机器后,要连接的远端服务端口。使用 SSH 自动隧道时必须改成你的 Whisper 服务实际端口,例如 9000
device 字符串 0 或你配置的编号 ffmpeg avfoundation 音频设备编号,通过 list-devices 查看。
language 字符串 auto 识别语言。auto 表示让后端自动判断;如果写 zh/en,会传给后端。
duration_seconds 数字 8 record-once 默认录音秒数。
paste 布尔 true 是否默认自动粘贴。即使为 true,命令行也可以用 --no-paste 临时关闭。
batch_size 数字 5 传给 Whisper API 的 batch size。显存越大通常可以越高;不懂就保持默认。
audio_codec 字符串 mp3 固定录音模式的音频格式配置,目前主要保留为配置项。
post_process 布尔 true 是否启用本地轻度后处理,例如去掉重复标点、重复短句。

十、菜单栏热键程序原型

仓库里还有一个 Swift 写的菜单栏小程序:

cmd/mason-voice-hotkey/main.swift

它用于监听长按或双击 fn,然后执行:

mason-voice-input listen-auto --once

编译

mkdir -p bin
swiftc cmd/mason-voice-hotkey/main.swift -o bin/mason-voice-hotkey

直接运行

./bin/mason-voice-hotkey --debug

日志

tail -f /tmp/mason-voice-hotkey.log
tail -f /tmp/mason-voice-input-launcher.log

重要提醒:辅助功能授权看的是程序身份

macOS 的辅助功能权限不是简单看文件名,而是看程序身份。 裸二进制如果反复重新编译,可能出现“系统设置里看起来开了,但进程里仍然没有权限”的情况。

更稳定的做法是把热键程序包装成 .app,设置 Bundle ID,并签名后再授权这个 .app

验收时不要只看系统设置开关,要看日志里是否有:

accessibility trusted=true
event tap enabled

十一、绑定快捷键的简单方案

如果你不想用 Swift 热键程序,可以用这些工具绑定命令:

  • Raycast
  • Alfred
  • Keyboard Maestro
  • macOS Shortcuts

建议绑定:

mason-voice-input listen-auto --once

或者更简单的固定 8 秒录音:

mason-voice-input record-once --duration 8

十二、开发与测试

运行单元测试:

go test ./...

重新编译:

go build -buildvcs=false -o ./bin/mason-voice-input ./cmd/mason-voice-input
swiftc cmd/mason-voice-hotkey/main.swift -o ./bin/mason-voice-hotkey

建议每次发布新本地程序时,在启动日志、菜单或 --version 输出中带上 版本号、构建时间、commit、实际路径和 pid,避免不知道当前运行的是旧版还是新版。

十三、常见问题 QA

Q1:我运行后没有自动粘贴,但剪贴板里有文字,为什么?

通常是 辅助功能权限没给对。去:

系统设置 → 隐私与安全性 → 辅助功能

给实际运行程序授权,例如 Terminal、iTerm2、Raycast、Alfred 或 MasonVoiceHotkey.app。

Q2:为什么系统设置里已经打开权限,日志还是 trusted=false

macOS 辅助功能权限看的是程序身份,不只是名字。 裸二进制重新编译后身份可能变化。建议使用 .app + Bundle ID + codesign,然后授权 .app。最终以程序日志里的 trusted=trueevent tap enabled 为准。

Q3:doctor 提示语音转文字 API 不通怎么办?

先确认你的服务是否真的在跑:

curl http://127.0.0.1:19000/

如果服务在远程机器,确认 SSH 隧道是否建立:

ssh -N -L 19000:127.0.0.1:9000 your-ssh-host

如果你的远程语音转文字服务或 adapter 不是 9000 端口,请把命令和配置里的 ssh_remote_port 改成实际端口。

再运行:

mason-voice-input doctor

Q4:怎么知道麦克风编号?

运行:

mason-voice-input list-devices

在输出里找到你的麦克风名称,前面的 [数字] 就是设备编号。然后:

mason-voice-input setup --device 这个数字

Q5:录音时报 Input/output error 或没有声音怎么办?

常见原因:

  • 麦克风权限没给 Terminal/iTerm。
  • device 设备编号选错。
  • 外接麦克风断开了。
  • 当前 App 或系统正在独占麦克风。

先重新运行:

mason-voice-input list-devices
mason-voice-input setup --device 正确编号

Q6:listen-auto 太容易误触发怎么办?

把阈值调高一点:

mason-voice-input listen-auto --once --energy-threshold 0.025

也可以提高开始确认时间:

mason-voice-input listen-auto --once --start-ms 260

Q7:listen-auto 总是漏掉开头第一个字怎么办?

加大 pre-roll:

mason-voice-input listen-auto --once --pre-roll-ms 500

或者降低开始确认时间:

mason-voice-input listen-auto --once --start-ms 120

Q8:一句话还没说完就上传了怎么办?

把静音等待时间调大:

mason-voice-input listen-auto --once --silence-ms 1200

Q9:识别结果有重复句子怎么办?

默认开启 post_process=true,会做轻度去重。但它不是大模型纠错,只处理明显重复。你可以查看配置:

mason-voice-input config

Q10:这个项目会把录音发到哪里?

发到你配置的 api_url 对应的兼容服务或 adapter。默认是:

http://127.0.0.1:19000/upload

如果你把 api_url 指向远程服务,音频就会发到那个服务。请只连接你信任的后端。

Q11:临时录音文件保存在哪里?

默认保存在系统临时目录下的 mason-voice-input 子目录,用完会删除。加 --keep 才会保留。

Q12:支持 Windows 或 Linux 吗?

当前不作为主要目标。录音部分使用 macOS 的 ffmpeg avfoundation 输入,Windows/Linux 需要替换录音参数和权限处理。

Q13:为什么不直接做真正流式识别?

当前路线是先稳定可用:本地 VAD 断句 + 分段上传。很多 faster-whisper HTTP 服务本身不是严格真流式,直接改成 WebSocket 真流式会显著增加后端复杂度。

Q14:开源使用时需要提交哪些文件?

建议提交:

  • cmd/
  • docs/
  • scripts/
  • go.mod
  • README.md
  • .gitignore

不要提交:

  • .env / .env.*
  • bin/ 编译产物
  • 私有服务器地址
  • 私有日志
  • API key / token / password

Star History

如果这个项目对你有帮助,欢迎给一个 Star。

Star History Chart

License

MIT. See LICENSE.

About

语音识别工具,替代微信语音输入法

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors