Install
openclaw skills install @noaheleven/local-tts文本转语音(TTS)。三条通道:edge-tts(微软神经网络语音,免费无需 key,15 个中文音色可用)、Azure Speech 官方 API(75 个中文音色全解锁,含晓秋/晓辰/HD/MAI,50 万字符/月免费)、pyttsx3(Windows SAPI 离线兜底)。当用户/agent 需要把文本转成语音文件(mp3/wav)、生成语音播报、配音、解锁被 edge-tts 封锁的音色时使用。
openclaw skills install @noaheleven/local-tts把任意文本转成本地音频文件,给 agent 或脚本调用。
⚠️ 默认行为:不传任何参数 = 联网 edge-tts + 晓晓女声(
zh-CN-XiaoxiaoNeural)。只有显式加--offline才走离线引擎。这是唯一默认。
📌 选型原则(2026-08-10 定稿):只用云端托管 TTS,免费无需注册优先。不部署任何本地开源模型(Kokoro/CosyVoice 等一律不装),pyttsx3 仅作断网最后兜底。
☁️ Azure 通道(2026-09-18 打通):edge-tts 拿不到的音色(晓秋/晓辰/晓涵等)走 Azure 官方 API,75 个中文音色全通。凭据见「Azure 官方通道」章节。
| 通道 | 音色数 | 音质 | 联网 | 成本 | 何时用 |
|---|---|---|---|---|---|
| edge-tts(默认) | 15 个中文可用 | ⭐⭐⭐ 神经网络 | 需要 | 免费无 key | 默认、通用播报 |
| Azure 官方 | 75 个中文全通 | ⭐⭐⭐~⭐⭐⭐⭐⭐(含 HD) | 需要 | 50 万字符/月免费 | 要 edge-tts 封锁的音色 / HD / 情感风格 |
pyttsx3(--offline) | 1 个(Huihui) | ⭐ 老式合成音 | 完全离线 | 免费 | 断网兜底 |
# 基础用法:edge-tts 神经网络语音(默认晓晓女声),未指定 -o 则存 tts_output/
python scripts/tts.py "要合成的文本" -o 输出路径.mp3
# 生成后自动播放(转 wav 用 winsound 同步播放,阻塞到播完,不弹窗)
python scripts/tts.py "文本" -o out.mp3 --play
# 指定音色 / 语速 / 音量(倍率 0.5~1.5)
python scripts/tts.py "文本" -o out.mp3 -v zh-CN-YunxiNeural -r 1.1 --volume 1.2
# 强制离线引擎(断网可用)
python scripts/tts.py "文本" -o out.wav --offline
# 列出 edge-tts 全部可用音色
python scripts/tts.py --list-voices
用途:edge-tts 免费通道对较新一批中文音色做了封锁(返回 NoAudioReceived),
Azure 官方 API 是唯一解锁路径,且音色库大 5 倍。
按优先级查找,任选一处即可:
AZURE_SPEECH_KEYS_FILE 指向的路径scripts/keys.env(脚本同目录)keys.env~/.workbuddy/azure_speech.env(全局兜底)文件格式:
AZURE_SPEECH_KEY=<密钥>
AZURE_SPEECH_REGION=eastasia
🔒 保密铁律:
keys.env不进版本控制、不写入可对外文件、不发第三方。本仓库已加.gitignore防呆。
# 单条
python scripts/azure_tts.py --text "要合成的文本" \
--voice zh-CN-XiaoqiuNeural --out out.mp3
# 批量(JSON 结构:{"segments":[{"text":"第 1 段"},{"text":"第 2 段"}]},
# 也兼容 slides 数组及 narration/vo 字段,输出 01.mp3 ~ N.mp3)
python scripts/azure_tts.py --json script.json --voice zh-CN-XiaoqiuNeural --outdir audio_out
# 列全部 75 个中文音色(含官方标签与风格)
python scripts/azure_tts.py --list-zh
python scripts/azure_tts.py --list-zh --voice xiaoqiu # 只看某个
# 语速/音调/音量/情感风格(SSML prosody + mstts:express-as)
python scripts/azure_tts.py --text "..." --out o.mp3 --rate +10% --pitch +0Hz --style newscast
https://{region}.tts.speech.microsoft.com/cognitiveservices/v1
https://xxx.services.ai.azure.com/)不能用于标准 TTS 调用,这是最容易踩的坑Ocp-Apim-Subscription-Key + Content-Type: application/ssml+xml + X-Microsoft-OutputFormat*Neural)在免费额度内;DragonHD 系列与 MAI-Voice-2 系列按量计费,不在免费额度内,用前先确认| 音色 ID | 标签 | 备注 |
|---|---|---|
zh-CN-XiaoqiuNeural | Calm, Engaging, Soothing | 晓秋,知性治愈,无风格标签(靠 prosody 调) |
zh-CN-XiaoxiaoNeural | Warm, Well-Rounded | 晓晓,20 种风格(newscast/calm/gentle…) |
zh-CN-XiaochenNeural | Friendly, Casual, Upbeat | 晓辰 |
zh-CN-XiaohanNeural | Gentle, Warm, Emotional | 晓涵,10 种情感 |
zh-CN-XiaomoNeural | Deep, Casual, Calm | 晓墨,低沉知性 |
zh-CN-XiaoruiNeural | Confident, Emotional, Hoarse | 晓睿,沙哑质感 |
zh-CN-XiaozhenNeural | Calm, Serious, Confident | 晓臻,沉稳 |
--play)⚠️ 内容红线:语音只播报最终总结/结论内容。严禁播放思考过程、执行过程、工具调用过程、中间日志。若任务无总结,则不播。
播放链路(已固化):文本 → 生成 mp3/wav →(mp3 则 ffmpeg 静默转 wav 到系统 temp)→ winsound 同步播放(阻塞到播完)→ 清理 → 退出。
技术要求:
SND_ASYNC:agent 调用是「生成即退」短进程,异步播放会在进程退出时被掐断 → 听不到声音winsound.PlaySound 返回值(成功返回 None,失败抛异常)local_tts_play.wav)三种触发方式:
--play(已实现)--play;只播总结不播过程;启停由会话约定,不写死进脚本--play--list-voices 返回的音色 ≠ 实际能合成的音色。 edge-tts 服务端对较新一批中文音色做了封锁(返回 NoAudioReceived)。
先查下表,别照 list 盲选;要用的音色在右列被封锁 → 直接走 Azure 通道。
| 音色 ID | 说明 |
|---|---|
zh-CN-XiaoxiaoNeural | 晓晓,女,万金油 |
zh-CN-XiaoyiNeural | 晓伊,女,活泼 |
zh-CN-XiaoxuanNeural | 晓萱,女 |
zh-CN-YunxiNeural | 云希,男(网文常误写为女声,注意) |
zh-CN-YunjianNeural | 云健,男,浑厚 |
zh-CN-YunyangNeural | 云扬,男,新闻播报 |
zh-CN-YunxiaNeural | 云夏,男,少年 |
zh-CN-liaoning-XiaobeiNeural | 晓北,女,东北话 |
zh-CN-shaanxi-XiaoniNeural | 晓妮,女,陕西话 |
zh-HK-HiuGaaiNeural / HiuMaanNeural / WanLungNeural | 粤语(女/女/男) |
zh-TW-HsiaoChenNeural / HsiaoYuNeural / YunJheNeural | 台湾国语(女/女/男) |
Xiaochen Xiaohan Xiaomeng Xiaomo Xiaoqiu Xiaorui Xiaoshuang Xiaoyan
Xiaoyou Xiaozhen Yunfeng Yunhao Yunye Yunze
规律:可用 = 较早期一批;被拒 = 较新一批。上列 14 个在 Azure 通道全部可用(Azure 共 75 个中文音色全通)。
即使是可用音色也可能临时被拒:实测云希 +35% 成功、+0% 连试 3 次全败。
→ 务必保留退避重试(脚本已内置),别因单次失败就换音色。Azure 通道无此问题。
python scripts/probe_voices.py # 探测内置快照清单(edge-tts)
python scripts/probe_voices.py --all-zh # 探测全部 zh-* 音色(慢)
python scripts/probe_voices.py --voice zh-CN-XiaochenNeural # 只测一个
python scripts/azure_tts.py --list-zh # Azure 端权威音色清单
pip install pyttsx3 edge-tts imageio-ffmpeg(Azure 通道零第三方依赖,纯标准库)import 延迟到函数内:--list-voices/--offline 等场景不会因缺依赖而整体崩溃-o;未指定时固定生成到 本 skill 目录下 tts_output/(用脚本 __file__ 定位,与调用时工作目录无关)20260918_新闻早报.mp3),不用乱码/序号.mp3;离线引擎 → .wav--play 的转码 wav 放系统临时目录,不会留在工作区{region}.tts.speech.microsoft.com 区域终结点json.load(response) 偶发 IncompleteRead → 脚本已改为「先读完整 bytes 再 json.loads」并带退避重试--play 播放细节见「🔈 自动播放方案」;转码用 imageio-ffmpeg 隔离版(装于 venv 内)