{"skill":{"slug":"voice-tts","displayName":"Voice TTS/ASR","summary":"语音输入（Whisper ASR）+ 语音输出（Edge TTS）技能，支持 agent 专属音色，可调用 send_voice_reply.mjs 发送 Telegram 语音消息。","description":"---\nname: voice-tts\ndescription: 语音输入（Whisper ASR）+ 语音输出（Edge TTS）技能，支持 agent 专属音色，可调用 send_voice_reply.mjs 发送 Telegram 语音消息。\nmetadata: {\"openclaw\": {\"emoji\": \"🎙️\", \"requires\": {\"bins\": [\"node>=18\", \"python3\", \"ffmpeg\"], \"pip\": [\"edge-tts\", \"whisper\", \"click\"]}}}\n---\n\n# voice-tts\n\n语音输入（ASR）+ 语音输出（TTS）技能，完整替代 OpenClaw 内置 tts 工具处理中文内容。\n\n## 技术概览\n\n| 方向 | 技术 | 说明 |\n|------|------|------|\n| 语音 → 文字 | Whisper（本地） | 接收语音，自动转文字 |\n| 文字 → 语音 | Edge TTS（云端） | 生成 MP3，发送 Telegram 语音消息 |\n\n---\n\n## 工作方式\n\n### ASR（语音 → 文字）\n\n用户发来语音消息 → `voice-asr.mjs` 转写为文字 → 触发 agent 处理。\n\n语音识别在 OpenClaw 工具层自动完成，agent 收到的是文字。\n\n### TTS（文字 → 语音）\n\nagent 回复文字后，如需以语音发送，调用 `send_voice_reply.mjs` 手动发送 Telegram 语音消息：\n\n```bash\nnode /path/to/voice-tts/scripts/send_voice_reply.mjs \\\n  --text \"你的回复内容\" \\\n  --chat-id 8317347201 \\\n  --agent main\n```\n\n---\n\n## 快速安装\n\n### 方式一：一键安装（推荐）\n\n```bash\n# 默认安装 turbo 模型\nbash /path/to/voice-tts/install.sh\n\n# 国内加代理\nbash /path/to/voice-tts/install.sh --proxy http://127.0.0.1:7897\n```\n\n### 方式二：手动安装\n\n```bash\npip install edge-tts whisper click\nbrew install ffmpeg   # macOS\nsudo apt install -y ffmpeg  # Ubuntu\n```\n\n安装完成后运行冒烟测试：\n\n```bash\nbash tests/smoke.sh\n```\n\n---\n\n## 配置（可选）\n\n`config.default.json` 已包含所有默认值，**不填配置可直接使用**。\n\n如需自定义 agent 音色映射或 ASR 参数，在 `openclaw.json` 的 `skills.entries.voice-tts.config` 中覆盖：\n\n```json\n{\n  \"skills\": {\n    \"entries\": {\n      \"voice-tts\": {\n        \"enabled\": true,\n        \"config\": {\n          \"tts\": {\n            \"defaultVoice\": \"zh-CN-XiaoxiaoNeural\",\n            \"agentVoices\": {\n              \"main\":       \"zh-CN-XiaoxiaoNeural\",\n              \"researcher\": \"zh-CN-YunxiNeural\",\n              \"product\":    \"zh-CN-XiaoyiNeural\",\n              \"coder\":      \"zh-CN-YunyangNeural\",\n              \"devops\":     \"zh-CN-YunjianNeural\"\n            }\n          },\n          \"asr\": {\n            \"defaultInitialPrompt\": \"以下是中文语音转文字。常见词包括：管家、研究员、邮差、码农、产品、运维、OpenClaw、小爱、Telegram。\",\n            \"defaultTemperature\": 0,\n            \"conditionOnPreviousText\": true\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n修改后执行 `openclaw gateway restart`。\n\n---\n\n## 核心脚本\n\n### 语音合成 — `bin/voice-tts.mjs`\n\n将文字转为语音文件：\n\n```bash\n# 基本用法\nnode bin/voice-tts.mjs \"你好\" -f /tmp/demo.mp3\n\n# 指定 agent 音色\nnode bin/voice-tts.mjs \"你好\" -f /tmp/demo.mp3 --agent main\n\n# 指定声音 / 语速\nnode bin/voice-tts.mjs \"你好\" -f /tmp/demo.mp3 -v zh-CN-YunxiNeural -r +10%\n```\n\n可用中文音色：`zh-CN-XiaoxiaoNeural`（女声，推荐）、`zh-CN-YunxiNeural`、`zh-CN-XiaoyiNeural`、`zh-CN-YunyangNeural`、`zh-CN-YunjianNeural`、`zh-CN-XiaomoNeural`\n\n### 语音识别 — `bin/voice-asr.mjs`\n\n将音频文件转文字：\n\n```bash\n# 基本用法\nnode bin/voice-asr.mjs audio.ogg\n\n# 指定模型 / 语言\nnode bin/voice-asr.mjs audio.ogg --model turbo --language zh\n\n# 输出 JSON（含语言检测）\nnode bin/voice-asr.mjs audio.ogg --json\n```\n\n可用模型：`tiny` `base` `small` `turbo` `large-v3`\n\n### 发送 Telegram 语音 — `scripts/send_voice_reply.mjs`\n\n一键完成\"文字 → TTS 合成 → Telegram 语音消息发送\"：\n\n```bash\nnode scripts/send_voice_reply.mjs \\\n  --text \"已收到！\" \\\n  --chat-id 8317347201 \\\n  --agent main\n```\n\n**参数说明：**\n\n| 参数 | 必填 | 说明 |\n|------|------|------|\n| `--text` | ✅ | 要语音播报的文字内容 |\n| `--chat-id` | ✅ | Telegram 目标用户 ID |\n| `--agent` | 否 | agent id，自动选对应音色 |\n| `--voice` | 否 | 覆盖默认音色，如 `zh-CN-YunxiNeural` |\n| `--rate` | 否 | 语速，如 `+10%`、`-5%` |\n| `--token` | 否 | 直接指定 Telegram Bot Token |\n\n**Token 自动查找优先级：**\n1. `--token` 参数\n2. `openclaw.json → channels.telegram.accounts.<当前agent>.botToken`\n3. `openclaw.json → channels.telegram.accounts.default.botToken`\n4. 环境变量 `TELEGRAM_BOT_TOKEN`\n\n---\n\n## 文件结构\n\n```\nvoice-tts/\n├── SKILL.md                      # 本文档\n├── config.default.json           # 默认配置（直接可用，不需修改）\n├── install.sh                    # 一键安装脚本\n│\n├── bin/\n│   ├── voice-tts.mjs             # TTS 入口\n│   └── voice-asr.mjs             # ASR 入口\n│\n├── lib/\n│   ├── config.mjs                # 配置读取（支持 openclaw.json 覆盖）\n│   ├── errors.mjs                 # 统一错误码 + 用户兜底消息\n│   └── audio.mjs                 # 音频校验\n│\n├── scripts/\n│   ├── send_voice_reply.mjs      # Telegram 语音发送（核心）\n│   └── auto_voice_check          # 批量处理未处理语音\n│\n└── tests/\n    └── smoke.sh                   # 冒烟测试\n```\n\n> **注意：** `scripts/edge_tts` 和 `scripts/whisper` 是内部 Python 封装，非直接入口；直接使用上表中的 `bin/` 入口即可。\n\n---\n\n## 错误码\n\n| 错误码 | 含义 | 用户兜底消息 |\n|--------|------|-------------|\n| `no_file_path` | 未提供音频文件 | 抱歉，没有收到音频文件，请重试。 |\n| `file_not_found` | 文件不存在 | 抱歉，音频文件没找到，请重试。 |\n| `file_empty` | 文件为空 | 抱歉，音频文件是空的，请重试。 |\n| `file_too_small` | 文件过小 | 抱歉，音频文件不完整，请重试。 |\n| `file_stale` | 文件过期 | 抱歉，音频文件已过期，请重试。 |\n| `transcription_failed` | Whisper 转写失败 | 抱歉，语音识别失败了，请重试。 |\n| `synthesis_failed` | Edge TTS 生成失败 | 抱歉，语音生成失败了，请重试。 |\n| `timeout` | 执行超时 | 抱歉，处理超时了，请稍后重试。 |\n\n---\n\n## 语音文件自动归档\n\n`voice-asr.mjs` 成功转写后，自动将原文件从 `~/.openclaw/media/inbound/` 复制到 **agent workspace** `media/inbound/`，然后删除原文件。\n\n- ✅ 成功时：复制归档，删除原文件\n- ❌ 失败时：保留原文件，可重试\n\n---\n\n## 故障排查\n\n```bash\n# 检查依赖\nffmpeg -version\npython3 -c \"import edge_tts; print('edge-tts ok')\"\npython3 -c \"import whisper; print('whisper ok')\"\n\n# 检查未处理语音文件\nls -la ~/.openclaw/media/inbound/\n\n# 直接测试 ASR\nnode bin/voice-asr.mjs ~/.openclaw/media/inbound/your-file.ogg\n\n# 直接测试 TTS\nnode bin/voice-tts.mjs \"测试\" -f /tmp/test.mp3\n\n# 运行冒烟测试\nbash tests/smoke.sh\n```\n\n常见问题：\n- **TTS 生成失败**：检查 `python3 -c \"import edge_tts; print('ok')\"`\n- **Telegram 发送失败**：确认 botToken 正确、chat-id 是数字 ID、语音文件 < 20MB\n- **语音发错对象**：检查 `conversationId` 是否与预期 chat-id 一致\n\n---\n\n## 可选：批量处理未处理语音\n\n```bash\nnode scripts/auto_voice_check\n```\n\n检查 `~/.openclaw/media/inbound/` 下未处理的 `.ogg` 文件，自动转写并归档。\n","topics":["Telegram","消息"],"tags":{"latest":"2.0.1"},"stats":{"comments":0,"downloads":1123,"installsAllTime":42,"installsCurrent":4,"stars":0,"versions":3},"createdAt":1773144199913,"updatedAt":1778997364633},"latestVersion":{"version":"2.0.1","createdAt":1774849771256,"changelog":"v2.0.1: 移除 voice-reply hook 描述，改为明确说明 ASR/TTS 为独立能力，语音发送需手动调用 send_voice_reply.mjs","license":"MIT-0"},"metadata":{"setup":[],"os":null,"systems":null},"owner":{"handle":"believe3344","userId":"s17cg2yazy67zprczptabx69b183k66w","displayName":"believe3344","image":"https://avatars.githubusercontent.com/u/176448419?v=4"},"moderation":{"isSuspicious":false,"isMalwareBlocked":false,"verdict":"clean","reasonCodes":["review.llm_review"],"summary":"Review: review.llm_review","engineVersion":"v2.4.24","updatedAt":1780090187395}}