# whisperSync **Repository Path**: web/whisper-sync ## Basic Information - **Project Name**: whisperSync - **Description**: 实时语音转文字 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-03 - **Last Updated**: 2026-06-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Whisper Sync 🎙️ 基于 **whisper.cpp** 的实时语音转文字服务,支持 HTTP 和 WebSocket 接口,具备智能反幻觉处理、音频预处理和繁简体转换能力。实时语音转文字受服务器硬件配置以及所选择的模型影响效率不一样,请不要直接用于生产环境。 ## ✨ 功能特性 | 功能 | 状态 | 描述 | |------|------|------| | 动态模型选择 | ✅ | 通过参数选择不同的 whisper.cpp 模型 | | HTTP 语音转写 | ✅ | 支持音频文件上传进行转写 | | WebSocket 实时转写 | ✅ | 支持实时流式语音转写,低延迟 | | 跨平台支持 | ✅ | Windows / Linux / macOS / Web | | 智能反幻觉 | ✅ | 25+ 种幻觉检测模式,自动过滤低质量结果 | | 音频预处理 | ✅ | 静音检测、噪声过滤、归一化处理 | | 参数动态调整 | ✅ | 通过 API 实时调整转写参数 | | 配置持久化 | ✅ | 参数保存到文件,重启后保持不变 | | API Key 认证 | ✅ | 可选 API Key 认证,支持 HTTP Header 和 WebSocket | | OpenAI 兼容 | ✅ | 完全兼容 OpenAI `/v1/audio/transcriptions` 接口 | | 繁简体转换 | ✅ | 自动将繁体中文转换为简体中文 | | 文本去重 | ✅ | 智能去除重复内容,保留语义完整性 | ## 🚀 快速开始 ### 1. 安装依赖 ```bash npm install ``` ### 2. 准备模型 将 whisper.cpp 的 GGML 格式模型文件放入 `./models` 目录。 **推荐模型下载地址:** - [Hugging Face - whisper.cpp models](https://huggingface.co/ggerganov/whisper.cpp/tree/main) ``` # 国内加速下载链接 https://down.nigx.cn/huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.bin?download=true https://down.nigx.cn/huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin?download=true https://down.nigx.cn/huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin?download=true https://down.nigx.cn/huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium.bin?download=true https://down.nigx.cn/huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v1.bin?download=true https://down.nigx.cn/huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v2.bin?download=true https://down.nigx.cn/huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3.bin?download=true ``` **常用模型对比:** | 模型 | 大小 | 转写质量 | 推理速度 | 推荐场景 | |------|------|----------|----------|----------| | ggml-tiny | ~77MB | 基础 | 最快 | 实时转写、低延迟场景 | | ggml-base | ~148MB | 良好 | 快 | 平衡质量和速度 | | ggml-small | ~488MB | 优秀 | 中等 | 追求更好质量 | | ggml-medium | ~1.5GB | 非常优秀 | 较慢 | 高质量转写 | | ggml-large | ~3.09GB | 最佳 | 慢 | 最高质量要求 | ### 3. 获取 whisper.cpp 二进制文件 #### 方法 1: 下载预编译的二进制文件 从 [whisper.cpp releases](https://github.com/ggerganov/whisper.cpp/releases) 下载适合你平台的预编译二进制文件,解压到 `./whisper-bin/Release/` 目录。 **目录结构:** ``` whisper-bin/ └── Release/ ├── whisper-cli.exe (Windows) ├── whisper-cli (Linux/macOS) └── 其他依赖库... ``` #### 方法 2: 从源码编译 ```bash git clone https://github.com/ggerganov/whisper.cpp.git cd whisper.cpp make mkdir -p ../whisper-sync/whisper-bin/Release cp main ../whisper-sync/whisper-bin/Release/whisper-cli ``` ### 4. 配置 API Key(可选) 创建 `.env` 文件(参考 `.env.example`): ```bash # 不设置 API_KEY 则无需认证 # 设置后所有 API 和 WebSocket 请求需要提供 API Key API_KEY=your-secret-key # 服务端口 PORT=3000 ``` > 可通过环境变量 `API_KEY` 或 `.env` 文件配置。不设置则不启用认证。 ### 5. 启动服务 ```bash npm start ``` 服务将在 `http://localhost:3000` 启动。 ## 🔐 API Key 认证 如果配置了 `API_KEY`,所有请求均需提供 API Key,支持以下方式: ### HTTP 请求 **方式 1:Header(推荐)** ```http X-API-Key: your-secret-key ``` **方式 2:Query 参数** ``` /api/models?api_key=your-secret-key ``` ### WebSocket 连接 通过 URL 查询参数提供: ``` ws://localhost:3000?api_key=your-secret-key ``` > 不设置 `API_KEY` 时,所有接口无需认证即可访问。 ## 📡 API 文档 ### HTTP 接口 #### 1. 获取可用模型 ```http GET /api/models ``` **响应示例:** ```json { "success": true, "models": [ { "name": "ggml-base", "path": "D:\\whisper-sync\\models\\ggml-base.bin", "file": "ggml-base.bin" }, { "name": "ggml-tiny", "path": "D:\\whisper-sync\\models\\ggml-tiny.bin", "file": "ggml-tiny.bin" } ] } ``` #### 2. 获取当前配置 ```http GET /api/config ``` **响应示例:** ```json { "success": true, "config": { "temperature": 0.0, "no_speech_threshold": 0.6, "compression_ratio_threshold": 2.4, "logprob_threshold": -1.0, "enableHallucinationFilter": true, "hallucinationPatterns": 25 } } ``` #### 3. 更新配置 ```http POST /api/config Content-Type: application/json ``` **请求体:** ```json { "temperature": 0.3, "no_speech_threshold": 0.7, "enableHallucinationFilter": true } ``` **参数说明:** | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | temperature | number | 0.0 | 采样温度,0-1,越低越确定性 | | no_speech_threshold | number | 0.6 | 静音检测阈值,0-1 | | compression_ratio_threshold | number | 2.4 | 熵阈值,用于检测解码器失败 | | logprob_threshold | number | -1.0 | 对数概率阈值 | | enableHallucinationFilter | boolean | true | 是否启用反幻觉过滤 | #### 4. 语音转文字 (原有接口) ```http POST /api/transcribe Content-Type: multipart/form-data ``` **参数:** - `audio`: 音频文件(必需) - `model`: 模型名称(可选,默认 ggml-base) - `language`: 语言代码(可选,默认 auto) **支持的语言代码:** - `auto`: 自动检测 - `zh`: 中文 - `en`: 英语 - `ja`: 日语 - `ko`: 韩语 - `es`: 西班牙语 - `fr`: 法语 - `de`: 德语 - `更多语言`: 参考 whisper.cpp 支持的语言列表 **响应示例:** ```json { "success": true, "result": { "text": "你好,这是转写结果", "segments": [ { "start": 0, "end": 2.5, "text": "你好" } ], "language": "zh", "model": "ggml-base", "processingTime": 28, "hallucinationsRemoved": 0 } } ``` #### 5. OpenAI 兼容接口 ```http POST /v1/audio/transcriptions Content-Type: multipart/form-data ``` **完全兼容 OpenAI 官方接口,可直接使用 OpenAI 客户端调用。** **参数:** | 参数 | 类型 | 必需 | 描述 | |------|------|------|------| | `file` | file | 是 | 要转录的音频文件 | | `model` | string | 是 | 模型类型:`ggml-tiny`、`ggml-base`、`ggml-small` | | `language` | string | 否 | 音频语言代码(如:`zh`、`en`) | | `prompt` | string | 否 | 初始提示文本 | | `response_format` | string | 否 | 响应格式:`json`、`verbose_json` | | `temperature` | number | 否 | 采样温度(0-1) | | `timestamp_granularities[]` | array | 否 | 时间戳粒度:`word`、`segment` | **模型映射:** | OpenAI 模型 | 本地 Whisper 模型 | |-------------|-------------------| | `whisper-1` | `ggml-base` | | `whisper-1-small` | `ggml-small` | | `whisper-1-tiny` | `ggml-tiny` | **基本响应格式:** ```json { "text": "这是转录的文本内容" } ``` **详细响应格式(verbose_json):** ```json { "task": "transcribe", "language": "zh", "duration": 8.47, "text": "这是转录的文本内容", "segments": [ { "start": 0.0, "end": 2.5, "text": "这是第一句话" } ], "words": [ { "word": "这是", "start": 0.0, "end": 0.5 } ] } ``` ### WebSocket 接口 **连接地址:** `ws://localhost:3000` #### 实时转写流程 1. **连接建立** ```javascript const ws = new WebSocket('ws://localhost:3000?api_key=your-secret-key'); ``` 2. **发送开始消息** ```json { "type": "start", "model": "ggml-base", "language": "zh", "format": "pcm16", "sampleRate": 16000, "step": 250, "length": 2500 } ``` 3. **发送音频数据**(二进制格式) ```javascript ws.send(audioBuffer); // ArrayBuffer 或 Buffer ``` 4. **接收部分结果** ```json { "type": "partial", "text": "你好,这是部分转写结果", "timestamp": 1699999999999, "processingTime": 50 } ``` 5. **发送结束消息** ```json { "type": "end" } ``` 6. **接收最终结果** ```json { "type": "result", "text": "完整的转写结果", "segments": [...], "language": "zh", "model": "ggml-base", "processingTime": 280 } ``` **参数说明:** | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | type | string | - | 消息类型:`start`、`end` | | model | string | ggml-base | 模型名称 | | language | string | auto | 语言代码 | | format | string | pcm16 | 音频格式 | | sampleRate | number | 16000 | 采样率 | | step | number | 250 | 处理间隔(毫秒) | | length | number | 2500 | 单次处理长度(毫秒) | ## 🛠️ 核心优化 ### 参数调优 | 参数 | 值 | 效果 | |------|-----|------| | temperature | 0.0 | 减少随机性,提高稳定性 | | beam-size | 2 | 平衡搜索质量和速度 | | best-of | 2 | 保留最佳结果 | | threads | 4 | 多线程处理 | ### 智能反幻觉过滤 内置 **25+** 种幻觉内容检测模式: 1. **常见幻觉短语**(谢谢观看、订阅、点赞等) 2. **填充词检测**(嗯、呃、啊、哦等) 3. **重复模式检测**(单字符重复、短语重复) 4. **音乐/字幕标记检测**(♪、🎵、[字幕]、(字幕:xxx)等) 5. **网站/链接幻觉检测** 6. **时间戳幻觉检测** 7. **版权/广告幻觉检测** 8. **字符多样性检测**(过滤重复字符过多的内容) 9. **词汇重复率检测**(过滤重复词语过多的内容) 10. **繁简体自动转换**(繁体→简体) 11. **文本去重**(智能去除重复内容) ### 音频预处理 - **静音检测**: 基于能量 + 零交叉率分析 - **高通滤波**: 去除低频噪音(200Hz 以下) - **低通滤波**: 去除高频噪音(3000Hz 以上) - **归一化**: 自动调整音频音量 - **格式转换**: 支持多种音频格式自动转换为 WAV ## 📁 项目结构 ``` whisper-sync/ ├── models/ # 模型文件目录 │ ├── ggml-base.bin │ └── ggml-tiny.bin ├── public/ # Web 前端文件 │ └── index.html # 可视化测试界面 ├── src/ │ ├── index.js # 主服务入口(HTTP + WebSocket) │ ├── model-manager.js # 模型管理模块 │ ├── config-manager.js # 配置管理模块(持久化) │ ├── hallucination-filter.js # 反幻觉检测模块(25+模式) │ ├── audio-preprocessor.js # 音频预处理模块 │ └── transcriber.js # 转写引擎封装 ├── whisper-bin/ # whisper.cpp 二进制文件 │ └── Release/ │ └── whisper-cli.exe ├── uploads/ # 临时上传目录 ├── .env # 环境变量配置(API Key 等) ├── .env.example # 环境变量配置示例 ├── config.json # 配置文件(自动生成) ├── package.json └── README.md ``` ## 🌐 Web 界面 访问 `http://localhost:3000` 可使用可视化测试界面: **功能特点:** - 🔑 **API Key 输入**: 支持在界面中输入 API Key,自动应用到所有请求 - 📤 **HTTP 上传**: 选择音频文件进行转写 - 🔧 **参数调整**: 实时调整 temperature、静音检测阈值等参数 - 💾 **配置保存**: 参数自动保存,刷新页面不丢失 - 🎤 **实时录音**: 使用 WebSocket 进行实时语音转写 - 📊 **结果展示**: 显示转写文本和处理时间 - 🔄 **OpenAI 兼容**: 支持通过 OpenAI 兼容接口进行转写测试 - 📋 **调试日志**: 实时显示服务端调试信息 - 📈 **音量指示**: 实时显示麦克风音量 ## 🚀 使用示例 ### OpenAI 接口调用示例 #### 1. 使用 curl 调用 ```bash # 基本转录 curl -X POST "http://localhost:3000/v1/audio/transcriptions" \ -H "Content-Type: multipart/form-data" \ -F "file=@audio.mp3" \ -F "model=whisper-1" \ -F "language=zh" # 详细响应格式 curl -X POST "http://localhost:3000/v1/audio/transcriptions" \ -H "Content-Type: multipart/form-data" \ -F "file=@audio.mp3" \ -F "model=whisper-1" \ -F "response_format=verbose_json" \ -F "timestamp_granularities[]=segment" ``` #### 2. 使用 Python 调用 ```python import requests url = "http://localhost:3000/v1/audio/transcriptions" files = {"file": open("audio.mp3", "rb")} data = { "model": "whisper-1", "language": "zh", "response_format": "verbose_json" } response = requests.post(url, files=files, data=data) print(response.json()) ``` #### 3. 使用 Node.js 调用 ```javascript const FormData = require('form-data'); const fs = require('fs'); const fetch = require('node-fetch'); const form = new FormData(); form.append('file', fs.createReadStream('audio.mp3')); form.append('model', 'whisper-1'); form.append('language', 'zh'); form.append('response_format', 'verbose_json'); const response = await fetch('http://localhost:3000/v1/audio/transcriptions', { method: 'POST', body: form, headers: form.getHeaders() }); const result = await response.json(); console.log(result); ``` #### 4. 在浏览器中使用 Fetch API ```javascript async function transcribeAudio(file) { const formData = new FormData(); formData.append('file', file); formData.append('model', 'whisper-1'); formData.append('language', 'zh'); formData.append('response_format', 'verbose_json'); const response = await fetch('/v1/audio/transcriptions', { method: 'POST', body: formData }); return await response.json(); } // 使用示例 const fileInput = document.getElementById('audioFile'); fileInput.addEventListener('change', async (e) => { const file = e.target.files[0]; if (file) { const result = await transcribeAudio(file); console.log('转录结果:', result); } }); ``` #### 5. 使用 OpenAI Python SDK ```python from openai import OpenAI # 指向本地服务 client = OpenAI( base_url="http://localhost:3000/v1", api_key="your-api-key" # 如果配置了 API Key ) audio_file = open("audio.mp3", "rb") transcription = client.audio.transcriptions.create( model="whisper-1", file=audio_file, language="zh", response_format="verbose_json" ) print(transcription.text) ``` ## 🎤 WebSocket 实时转写示例 ```javascript // 连接 WebSocket const ws = new WebSocket('ws://localhost:3000?api_key=your-secret-key'); ws.onopen = () => { // 发送开始消息 ws.send(JSON.stringify({ type: 'start', model: 'ggml-base', language: 'zh', format: 'pcm16', sampleRate: 16000, step: 250, length: 2500 })); }; ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'partial') { console.log('部分结果:', data.text); } else if (data.type === 'result') { console.log('最终结果:', data.text); } else if (data.type === 'started') { console.log('转写已开始'); } }; // 发送音频数据 // audioData 是 ArrayBuffer 格式的 PCM 音频数据 ws.send(audioData); // 结束转写 ws.send(JSON.stringify({ type: 'end' })); ``` ## 🌟 繁简体转换功能 本服务支持自动将繁体中文转换为简体中文,无需额外配置。 **转换示例:** ``` 输入(繁体):大家好,我叫劉過 输出(简体):大家好,我叫刘过 ``` 支持的常用字转换包括:劉→刘、鋼→钢、問→问、請→请、麼→么、這→这、裡→里、個→个、們→们、為→为、來→来、會→会、國→国、學→学、著→着、沒→没、過→过、與→与、給→给、誰→谁、什麼→什么、怎麼→怎么、這麼→这么等。 ## ❓ 常见问题 ### Q1: 为什么转写结果为空? **可能原因:** 1. 音频文件格式不支持(支持:flac, mp3, ogg, wav) 2. 音频文件内容为空或静音 3. 模型文件不存在或路径错误 4. 反幻觉过滤器过滤了低质量结果 **解决方案:** - 检查音频文件是否正常播放 - 确认模型文件路径正确 - 查看服务端日志获取详细错误信息 ### Q2: 实时转写延迟较高怎么办? **优化建议:** 1. 使用更小的模型(ggml-tiny 或 ggml-base) 2. 增加 `step` 参数(如 500ms) 3. 减少 `length` 参数(如 1000ms) 4. 确保服务器有足够的 CPU 资源 ### Q3: 如何提高转写准确性? **建议:** 1. 使用更大的模型(ggml-small 或 ggml-medium) 2. 设置正确的语言参数(如 `language=zh`) 3. 使用初始提示(prompt)引导模型 4. 确保音频质量良好(无噪音、清晰发音) ### Q4: 支持哪些音频格式? **支持格式:** - WAV(推荐) - MP3 - FLAC - OGG ### Q5: 如何部署到生产环境? **推荐方案:** 1. 使用 PM2 管理进程 2. 配置 Nginx 反向代理 3. 设置适当的资源限制 4. 启用 API Key 认证 ## 🚀 开发模式 ```bash npm run dev ``` 启用开发模式,支持热更新。 ## 📝 配置文件 配置文件 `config.json` 自动保存在项目根目录: ```json { "temperature": 0.0, "no_speech_threshold": 0.6, "compression_ratio_threshold": 2.4, "logprob_threshold": -1.0, "enableHallucinationFilter": true, "hallucinationPatterns": 25 } ``` ## ⚠️ 注意事项 1. **音频格式**: 支持 flac, mp3, ogg, wav 等格式 2. **内存要求**: 根据模型大小调整(tiny: ~1GB, base: ~2GB, large: ~8GB) 3. **首次加载**: 模型首次加载可能需要几秒时间 4. **FFmpeg**: 音频预处理需要安装 FFmpeg(可选,Windows 支持原生 MP3) 5. **线程数**: 根据 CPU 核心数调整 `threads` 参数 ## 🔒 生产部署 ### 使用 pm2 管理项目 ```bash npm install -g pm2 # 创建 PM2 配置文件 cat > ecosystem.config.js << 'EOF' module.exports = { apps: [{ name: 'whisper-sync', script: './src/index.js', instances: 1, autorestart: true, watch: false, max_memory_restart: '4G', env: { NODE_ENV: 'production', PORT: 3000 }, error_file: './logs/error.log', out_file: './logs/out.log', log_date_format: 'YYYY-MM-DD HH:mm:ss Z' }] } EOF # 启动服务 mkdir -p logs pm2 start ecosystem.config.js pm2 startup pm2 save ``` ### Nginx 反向代理配置 ```nginx server { listen 80; server_name your-domain.com; client_max_body_size 100M; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 86400; } } ``` ## 📜 许可证 MIT ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ## 📧 联系方式 如有问题或建议,请通过 Issue 联系。 --- **项目状态**: ✅ 稳定运行 **最后更新**: 2026年6月