内容
<!-- ---
!-- Timestamp: 2026-03-14 07:25:51
!-- Author: ywatanabe
!-- File: /home/ywatanabe/proj/scitex-audio/README.md
!-- --- -->
# SciTeX 音频
<p align="center">
<a href="https://scitex.ai">
<img src="docs/scitex-logo-blue-cropped.png" alt="SciTeX" width="400">
</a>
</p>
<p align="center"><b>统一的文本转语音,自动后端故障转移</b></p>
<p align="center">
<a href="https://scitex-audio.readthedocs.io/">完整文档</a> · <code>pip install scitex-audio[all]</code>
</p>
<!-- scitex-badges:start -->
<p align="center">
<a href="https://pypi.org/project/scitex-audio/"><img src="https://img.shields.io/pypi/v/scitex-audio?label=pypi" alt="pypi"></a>
<a href="https://pypi.org/project/scitex-audio/"><img src="https://img.shields.io/pypi/pyversions/scitex-audio?label=python" alt="python"></a>
<a href="https://github.com/ywatanabe1989/scitex-audio/actions/workflows/rtd-sphinx-build-on-ubuntu-latest.yml"><img src="https://img.shields.io/github/actions/workflow/status/ywatanabe1989/scitex-audio/rtd-sphinx-build-on-ubuntu-latest.yml?branch=develop&label=docs" alt="docs"></a>
<a href="https://github.com/ywatanabe1989/scitex-audio/actions/workflows/pytest-matrix-on-ubuntu-py3-11-3-12-3-13.yml"><img src="https://img.shields.io/github/actions/workflow/status/ywatanabe1989/scitex-audio/pytest-matrix-on-ubuntu-py3-11-3-12-3-13.yml?branch=develop&label=tests" alt="tests"></a>
<a href="https://codecov.io/gh/ywatanabe1989/scitex-audio"><img src="https://img.shields.io/codecov/c/github/ywatanabe1989/scitex-audio/develop?label=cov" alt="cov"></a>
<a href="https://www.gnu.org/licenses/agpl-3.0"><img src="https://img.shields.io/badge/license-AGPL_v3-blue.svg" alt="License: AGPL v3"></a>
</p>
<!-- scitex-badges:end -->
---
## 问题与解决方案
| # | 问题 | 解决方案 |
|---|---------|----------|
| 1 | **文本转语音库分散** -- ElevenLabs REST + gTTS HTTP + pyttsx3 native 各自有不同的 API、故障模式、语音格式 | **`stx.audio.speak(text)`** -- 一次调用;自动故障转移 ElevenLabs → LuxTTS → gTTS → pyttsx3 当上游失败或 API 密钥丢失 |
| 2 | **离线 TTS 听起来像机器人** -- espeak 是 pi-era 的临时解决方案 | **LuxTTS** -- 离线 48 kHz 语音克隆在 CPU;首次加载预热后接近实时 |
| 3 | **脚本无法从无头会话提醒用户** -- `print` 在日志中丢失 | **MCP 工具 `audio_speak`** -- 代理和长时间运行的脚本可听觉地向操作员报告状态,并带有桌面通知故障转移 |
## 文本转语音后端
| 后端 | 质量 | 成本 | 互联网 | 离线 | 默认速度 |
|---------|---------|------|----------|---------|---------------|
| **ElevenLabs** | 高 | 付费 | 需要 | 否 | 1.2x |
| **LuxTTS** | 高 | 免费 | 首次下载 | 是 | 2.0x |
| **Google TTS** | 良好 | 免费 | 需要 | 否 | 1.5x |
| **系统 TTS** | 基本 | 免费 | 否 | 是 | 150 wpm |
<p align="center"><sub><b>表 1.</b> 支持的 TTS 后端。故障转移顺序(elevenlabs → luxtts → gtts → pyttsx3)确保始终使用最佳可用质量。</sub></p>
## 安装
需要 Python >= 3.10。
```bash
pip install scitex-audio
```
安装特定后端:
```bash
pip install scitex-audio[gtts] # Google TTS
pip install scitex-audio[pyttsx3] # 系统 TTS (+ apt install espeak-ng)
pip install scitex-audio[elevenlabs] # ElevenLabs
pip install scitex-audio[luxtts] # LuxTTS(语音克隆,离线)
pip install scitex-audio[all] # 所有
```
## 架构
```
src/scitex_audio/
├── _engines/ # 后端实现(gtts, pyttsx3, elevenlabs, luxtts)
├── _cli/ # `scitex-audio` Click CLI
├── _mcp/ # MCP 服务器入口
├── _speak.py # 高级 speak() 接口
├── _tts.py # 文本转语音调度
├── _stt.py # 语音转文本调度
├── _relay.py # 跨进程音频中继
├── _cross_process_lock.py # 序列化并发播放
├── _env_loader.py # 环境变量驱动的后端选择
└── mcp_server.py # MCP 工具注册
```
## 演示
```mermaid
flowchart LR
User[speak text] --> Speak[scitex_audio.speak]
Speak --> Sel{后端?}
Sel -->|gtts| GTTS[gTTS 引擎]
Sel -->|pyttsx3| Local[pyttsx3 / espeak-ng]
Sel -->|elevenlabs| EL[ElevenLabs API]
Sel -->|luxtts| Lux[LuxTTS 离线克隆]
GTTS & Local & EL & Lux --> Relay[跨进程中继] --> Audio[(扬声器 / .mp3)]
```
## 快速开始
```python
from scitex_audio import speak, available_backends
# 检查可用后端
print(available_backends()) # 例如,['gtts', 'pyttsx3']
# 使用自动选择的后端说话
speak("你好,来自 SciTeX 音频!")
# 选择特定后端
speak("Bonjour", backend="gtts", voice="fr")
# 保存而不播放
speak("保存此", output_path="output.mp3", play=False)
```
## 四个接口
<details open>
<summary><strong>Python API</strong></summary>
<br>
```python
import scitex_audio
scitex_audio.speak("你好!") # 自动后端
scitex_audio.speak("快速", backend="gtts", speed=1.5)
scitex_audio.available_backends() # 列出后端
scitex_audio.check_wsl_audio() # WSL 音频状态
scitex_audio.generate_bytes("作为字节") # 原始 MP3 字节
scitex_audio.stop_speech() # 停止播放
tts = scitex_audio.get_tts("gtts") # 获取引擎
tts.speak("使用引擎", voice="fr")
```
> **[完整 API 参考](https://scitex-audio.readthedocs.io/en/latest/api/scitex_audio.html)**
</details>
<details>
<summary><strong>CLI 命令</strong></summary>
<br>
```bash
scitex-audio --help-recursive # 显示所有命令
scitex-audio speak "你好,世界" # 说话
scitex-audio speak "Bonjour" -b gtts -v fr
scitex-audio backends # 列出后端
scitex-audio check # 音频状态(WSL)
scitex-audio stop # 停止播放
scitex-audio relay --port 31293 # 启动中继服务器
scitex-audio list-python-apis # 列出 Python API 树
scitex-audio mcp list-tools # 列出 MCP 工具
```
> **[完整 CLI 参考](https://scitex-audio.readthedocs.io/en/latest/quickstart.html)**
</details>
<details>
<summary><strong>MCP 服务器 — 面向 AI 代理</strong></summary>
<br>
AI 代理可以通过 MCP 协议进行通知和无障碍访问。代理生成文本,MCP 服务器在主机上合成语音,音频通过用户的本地扬声器播放 — 即使代理在远程服务器上运行(通过 [中继](#远程音频中继) 在端口 `31293`)。
| 工具 | 描述 |
|------|-------------|
| `audio_speak` | 将文本转换为语音,并具有后端故障转移 |
| `list_backends` | 列出可用的 TTS 后端和状态 |
| `check_audio_status` | 检查 WSL 音频连接性 |
| `announce_context` | 宣布当前目录和 git 分支 |
<sub><b>表 2.</b> 面向 AI 辅助音频的四个 MCP 工具。所有工具都接受 JSON 参数并返回 JSON 结果。</sub>
#### Claude 代码设置
在项目根目录添加 `.mcp.json`。使用 `SCITEX_AUDIO_ENV_SRC` 从 `.src` 文件加载所有配置 — 这使 `.mcp.json` 在不同环境中保持静态:
```json
{
"mcpServers": {
"scitex-audio": {
"command": "scitex-audio",
"args": ["mcp", "start"],
"env": {
"SCITEX_AUDIO_ENV_SRC": "${SCITEX_AUDIO_ENV_SRC}"
}
}
}
}
```
然后通过 shell 配置文件切换环境:
```bash
# 本地机器(有扬声器)
export SCITEX_AUDIO_ENV_SRC=~/.scitex/audio/local.src
# 远程服务器(无扬声器,使用中继)
export SCITEX_AUDIO_ENV_SRC=~/.scitex/audio/remote.src
```
生成模板 `.src` 文件:
```bash
scitex-audio env-template -o ~/.scitex/audio/local.src
```
`local.src` 示例:
```bash
export SCITEX_AUDIO_MODE=local
export SCITEX_AUDIO_RELAY_PORT=31293
export SCITEX_AUDIO_ELEVENLABS_API_KEY="your-key-here"
```
`remote.src` 示例:
```bash
export SCITEX_AUDIO_MODE=remote
export SCITEX_AUDIO_RELAY_PORT=31293
export SCITEX_AUDIO_ELEVENLABS_API_KEY="your-key-here"
```
或全局安装:
```bash
scitex-audio mcp install
```
> **[完整 MCP 规范](https://scitex-audio.readthedocs.io/en/latest/api/scitex_audio._mcp.html)**
</details>
<details>
<summary><strong>技能</strong></summary>
<br>
技能提供工作流导向的指南,供 AI 代理查询以发现功能和用法模式。
```bash
scitex-audio skills list # 列出可用技能页面
scitex-audio skills get SKILL # 显示主技能页面
scitex-dev skills export --package scitex-audio # 导出到 Claude Code
```
| 技能 | 内容 |
|-------|---------|
| `quick-start` | 基本用法、首次调用、返回值 |
| `available-backends` | 所有 TTS 后端、功能、安装命令 |
| `smart-routing` | 自动/本地/远程模式、中继服务器、SSH 隧道 |
| `cli-commands` | 完整的 CLI 参考 |
| `mcp-tools-for-ai-agents` | MCP 工具和安装 |
| `common-workflows` | 通知模式、多后端、保存音频 |
</details>
<details>
<summary><strong>远程音频中继</strong></summary>
<br>
当代理在远程服务器上运行时(NAS、云、HPC),它们没有扬声器。**中继服务器** 解决了这个问题:本地机器(有扬声器)运行一个轻量级 HTTP 服务器,远程代理通过 SSH 隧道发送语音请求。
### 架构
```
远程服务器(NAS/云) 本地机器(有扬声器)
┌─────────────────────┐ ┌──────────────────────┐
│ AI 代理 │ │ 中继服务器 │
│ speak("你好") │ │ scitex-audio relay │
│ ↓ │ │ ↓ │
│ POST /speak ────────┼── SSH ─────┼→ TTS 引擎 │
│ (端口 31293) │ 隧道 │ ↓ │
│ │ │ 🔊 扬声器 │
└─────────────────────┘ └──────────────────────┘
```
### 设置
**步骤 1:在本地机器上启动中继(有扬声器)**
```bash
scitex-audio relay --port 31293
```
**步骤 2:从本地到远程的 SSH 隧道**
在 `~/.ssh/config` 中添加:
```ssh-config
Host my-server
HostName 192.168.0.69
User myuser
RemoteForward 31293 127.0.0.1:31293 # 音频中继
```
然后连接:`ssh my-server`。隧道将远程端口 31293 映射回您的本地中继。
**步骤 3:配置远程环境**
在远程服务器上设置:
```bash
export SCITEX_AUDIO_MODE=remote
export SCITEX_AUDIO_RELAY_PORT=31293
# URL 会从隧道自动检测(localhost:31293)
```
现在,在远程服务器上调用 `speak("你好")` 会在您的本地扬声器上播放音频。
### 中继端点
| 端点 | 方法 | 描述 |
|----------|--------|-------------|
| `/speak` | POST | 播放 TTS (`{"text": "...", "backend": "gtts"}`) |
| `/health` | GET | 健康检查(返回 `{"status": "ok"}`) |
| `/list_backends` | GET | 列出可用后端 |
### 自动启动中继(Shell 配置文件)
将以下内容添加到您的 shell 配置文件(例如 `~/.bashrc`)**本地机器**(具有扬声器):
```bash
export SCITEX_AUDIO_RELAY_PORT=31293
export SCITEX_AUDIO_MODE=local
_audio_health_ok() {
local port="${SCITEX_AUDIO_RELAY_PORT:-31293}"
curl -sf --connect-timeout 2 "http://localhost:$port/health" >/dev/null 2>&1
}
_start_audio_relay() {
local port="${SCITEX_AUDIO_RELAY_PORT:-31293}"
# 已经健康 -> 跳过
_audio_health_ok && return
# 在后台启动中继
scitex-audio relay --port "$port" --force &>/dev/null &
disown
}
_start_audio_relay
```
在 **远程服务器**(NAS、云、HPC)上,添加到 shell 配置文件:
```bash
export SCITEX_AUDIO_RELAY_PORT=31293
export SCITEX_AUDIO_MODE=remote
# 中继 URL 会从 SSH RemoteForward 隧道自动检测
```
使用此设置,每个 SSH 会话都会自动将音频路由到您的扬声器。运行在远程服务器上的 AI 代理调用 `speak()`,音频会在本地播放。
</details>
<details>
<summary><strong>环境变量</strong></summary>
<br>
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `SCITEX_AUDIO_MODE` | `auto` | 音频模式:`local`、`remote` 或 `auto` |
| `SCITEX_AUDIO_RELAY_URL` | *(自动)* | 完整的中继 URL(例如 `http://localhost:31293`) |
| `SCITEX_AUDIO_RELAY_HOST` | *(无)* | 中继主机(与端口组合以构建 URL) |
| `SCITEX_AUDIO_RELAY_PORT` | `31293` | 中继服务器端口 |
| `SCITEX_AUDIO_HOST` | `0.0.0.0` | 中继服务器绑定主机 |
| `SCITEX_AUDIO_ELEVENLABS_API_KEY` | *(无)* | ElevenLabs API 密钥 |
| `SCITEX_DIR` | `~/.scitex` | 音频缓存文件的基本目录 |
| `SCITEX_CLOUD` | *(无)* | 设置为 `true` 以使用浏览器中继模式(OSC 转义) |
<p align="center"><sub><b>表 3.</b> 环境变量。端口 31293 编码了日语电话按键映射中的“sa-i-te-ku-su”(サイテクス)。</sub></p>
### 模式解析
- **`auto`**(默认):检查本地音频可用性。如果挂起/不可用并且检测到中继 URL,则路由到中继。否则使用本地。
- **`local`**:始终使用本地 TTS 引擎和扬声器。
- **`remote`**:始终将语音发送到中继服务器。如果中继不可达,则失败。
</details>
## SciTeX 的一部分
`scitex-audio` 是 [**SciTeX**](https://scitex.ai) 的一部分。可以通过 `pip install scitex[audio]` 安装为 `scitex.audio`(Python)或 `scitex audio ...`(CLI)。
SciTeX 系统遵循以下四项研究自由,灵感来自 [自由软件定义](https://www.gnu.org/philosophy/free-sw.en.html):
> 四项研究自由
>
> 0. **运行** 您的研究 - 您的机器,您负责。
> 1. **研究** 了解每个步骤的工作原理 - 从原始数据到最终的手稿。
> 2. **重新分发** 您的工作流,而不仅仅是您的论文。
> 3. **修改** 任何模块并与社区分享改进。
> AGPL-3.0 -- 因为我们相信研究基础设施应该与运行它的软件具有相同的自由。
## 致谢
- [LuxTTS](https://github.com/ysharma3501/LuxTTS) -- 开源离线 TTS 引擎,具有语音克隆支持
---
<p align="center">
<a href="https://scitex.ai" target="_blank"><img src="docs/scitex-icon-navy-inverted.png" alt="SciTeX" width="40"/></a>
</p>
<!-- EOF -->
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器