Skill: luogao2333/moss-tts-voice (version 1.2.2)

--- name: moss-tts-voice description: | MOSS-TTS 语音合成与音色克隆工具。生成适合各渠道的音频文件。 触发场景： - 用户要求生成语音、TTS - 用户提到"用我的声音"、"克隆声音"、"MOSS语音" - 需要生成语音文件用于发送 功能：文本转语音、实时克隆、预注册音色、多格式输出 metadata: openclaw: requires: env: - MOSS_API_KEY bins: - python3 - ffmpeg primaryEnv: MOSS_API_KEY homepage: https://studio.mosi.cn emoji: "🎙️" --- # MOSS-TTS 语音合成 > ⚠️ **注意**：本工具负责生成音频文件，发送到各渠道需要配合其他工具（如 OpenClaw message 工具） ## 快速开始（3 步） ### 1. 获取 API Key 访问 https://studio.mosi.cn → 注册/登录 → 控制台 → API 密钥 → 创建 ```bash export MOSS_API_KEY="sk-你的密钥" ``` ### 2. 安装依赖 ```bash # 系统依赖 brew install python3 ffmpeg # Python 依赖 pip3 install requests ``` ### 3. 生成语音 ```bash python3 scripts/tts.py \ --text "你好，我是MOSS" \ --channel feishu \ --json ``` 输出： ```json { "success": true, "file": "/tmp/openclaw/moss-tts/voice-xxx.ogg", "format": "ogg" } ``` --- ## ⚠️ 隐私与安全 ### API Key 安全 - **不要提交到 Git**：将 `MOSS_API_KEY` 添加到 `.gitignore` - **使用环境变量**：不要在代码中硬编码密钥 - **定期轮换**：建议定期更换 API Key ### 语音数据上传 - **克隆音色**：上传的音频会存储在 MOSS Studio 服务器 - **实时克隆**：每次请求都会上传音频数据到 MOSS API - **数据保留**：参考 MOSS Studio 隐私政策 **建议**： - 使用公开/非敏感音频进行克隆 - 避免上传包含敏感信息的录音 - 定期清理 MOSS Studio 中不需要的音色 --- ## 功能说明 本工具提供以下功能： 1. **文本转语音** - 将文本转换为自然语音 2. **实时克隆** - 从音频即时克隆声音 3. **预注册音色** - 上传并保存音色供后续使用 4. **格式转换** - 自动转换为适合各渠道的格式 **不包含**： - 直接发送到 IM 渠道（需要配合其他工具） - 音色管理（删除、修改等） --- ## 使用模式 ### 模式一：实时克隆 ```bash python3 scripts/tts.py \ --text "要说的内容" \ --reference_audio "参考音频.ogg" \ --channel feishu ``` ### 模式二：预注册音色（推荐） ```bash # 1. 上传并克隆 curl -X POST https://studio.mosi.cn/api/v1/files/upload \ -H "Authorization: Bearer $MOSS_API_KEY" \ -F "file=@voice.ogg" # → {"file_id": "YOUR_FILE_ID"} curl -X POST https://studio.mosi.cn/api/v1/voice/clone \ -H "Authorization: Bearer $MOSS_API_KEY" \ -d '{"file_id": "YOUR_FILE_ID", "name": "我的声音"}' # → {"voice_id": "YOUR_VOICE_ID"} # 2. 使用（等待 10 秒后） python3 scripts/tts.py \ --text "你好" \ --voice_id "YOUR_VOICE_ID" \ --channel feishu ``` --- ## 输出格式 | 渠道 | 格式 | 说明 | |------|------|------| | feishu | ogg (opus) | 飞书语音消息格式 | | telegram | ogg (opus) | Telegram 语音消息格式 | | whatsapp | ogg (opus) | WhatsApp 语音消息格式 | | discord | mp3 | Discord 文件格式 | | signal | mp3 | Signal 文件格式 | | slack | mp3 | Slack 文件格式 | --- ## 参数说明 | 参数 | 说明 | 必填 | |------|------|------| | `--text` | 待合成文本 | ✅ | | `--reference_audio` | 参考音频（实时克隆） | 二选一 | | `--voice_id` | 预注册音色 ID | 二选一 | | `--channel` | 目标渠道 | ❌ | | `--format` | 输出格式 | ❌ | | `--output` | 输出路径 | ❌ | | `--json` | JSON 输出 | ❌ | --- ## 音频要求 - **格式**: ogg, mp3, wav, m4a - **时长**: 10-30 秒（推荐 20 秒以上） - **音质**: 清晰人声，无背景噪音 - **大小**: < 10MB --- ## 常见问题 ### Q: 如何发送生成的语音？ 本工具只生成音频文件。发送需要： 1. 使用返回的文件路径 2. 配合 OpenClaw message 工具或其他方式发送 ### Q: 飞书发送后是文件而不是语音？ 确保音频格式正确： ```bash file voice.ogg # 应显示: Ogg data, Opus audio ``` ### Q: 克隆效果不好？ - 时长 20 秒以上 - 清晰人声，无噪音 - 正常语速 --- ## API 端点 | 用途 | 端点 | |------|------| | 文本转语音 | `POST /v1/audio/tts` | | 上传文件 | `POST /api/v1/files/upload` | | 克隆音色 | `POST /api/v1/voice/clone` | | 查询音色 | `GET /api/v1/voices` | --- ## 详细文档 - [API 技术细节](references/api-guide.md) - [渠道格式说明](references/channel-formats.md) - [问题排查](references/troubleshooting.md) --- _版本: 1.2.0 | 更新: 2026-03-10_

path: _meta.json
content: ownerId: kn70gaeqx7vz827j991snvbmw58216hd
slug: moss-tts-voice
version: 1.2.1
publishedAt: 1773140944690

path: requirements.txt
content: requests>=2.28.0


path: README.md
content: # MOSS-TTS Voice

> 🎙️ MOSS-TTS 语音合成与音色克隆工具

## 功能

- **文本转语音** - 将文本转换为自然语音
- **实时克隆** - 从音频即时克隆声音
- **预注册音色** - 保存音色供后续使用
- **格式转换** - 自动转换为各渠道格式

> ⚠️ **注意**：本工具生成音频文件，发送到各渠道需要配合其他工具

---

## 安装

### 1. 获取 API Key

访问 https://studio.mosi.cn → 注册 → API 密钥 → 创建

```bash
export MOSS_API_KEY="sk-你的密钥"
```

### 2. 安装依赖

```bash
# 系统依赖
brew install python3 ffmpeg

# Python 依赖
pip3 install -r requirements.txt
```

---

## 使用

### 实时克隆

```bash
python3 scripts/tts.py \
  --text "你好" \
  --reference_audio "voice.ogg" \
  --channel feishu \
  --json
```

### 预注册音色（推荐）

```bash
# 1. 上传音频
curl -X POST https://studio.mosi.cn/api/v1/files/upload \
  -H "Authorization: Bearer $MOSS_API_KEY" \
  -F "file=@voice.ogg"
# → {"file_id": "YOUR_FILE_ID"}

# 2. 克隆
curl -X POST https://studio.mosi.cn/api/v1/voice/clone \
  -H "Authorization: Bearer $MOSS_API_KEY" \
  -d '{"file_id": "YOUR_FILE_ID", "name": "我的声音"}'
# → {"voice_id": "YOUR_VOICE_ID"}

# 3. 使用
python3 scripts/tts.py \
  --text "你好" \
  --voice_id "YOUR_VOICE_ID" \
  --channel feishu
```

---

## 输出格式

| 渠道 | 格式 |
|------|------|
| 飞书 | ogg (opus) |
| Telegram | ogg (opus) |
| WhatsApp | ogg (opus) |
| Discord | mp3 |
| Signal | mp3 |
| Slack | mp3 |

---

## 参数

| 参数 | 说明 | 必填 |
|------|------|------|
| `--text` | 待合成文本 | ✅ |
| `--reference_audio` | 参考音频 | 二选一 |
| `--voice_id` | 预注册音色 ID | 二选一 |
| `--channel` | 目标渠道 | ❌ |
| `--format` | 输出格式 | ❌ |
| `--output` | 输出路径 | ❌ |
| `--json` | JSON 输出 | ❌ |

---

## ⚠️ 隐私与安全

### API Key
- 不要提交到 Git
- 使用环境变量
- 定期轮换

### 语音数据
- 克隆会上传音频到 MOSS Studio
- 避免上传敏感录音
- 定期清理不需要的音色

---

## 音频要求

- **格式**: ogg, mp3, wav, m4a
- **时长**: 10-30 秒（推荐 20+ 秒）
- **音质**: 清晰人声，无噪音
- **大小**: < 10MB

---

## 更新日志

- **1.2.0** (2026-03-10) - 音色克隆、格式支持
- **1.0.0** - 初始版本

---

## License

MIT


path: scripts/list_voices.py
content: import requests, os, json

def list_voices():
    [REDACTED_SECRET]"MOSS_API_KEY")
    url = "https://studio.mosi.cn/api/v1/voices?limit=10&status=ACTIVE"
    headers = {"Authorization": f"Bearer {api_key}"}

    resp = requests.get(url, headers=headers)
    voices = resp.json().get("voices", [])
    
    print("| Voice Name | Voice ID | Description |")
    print("|---|---|---|")
    for v in voices:
        print(f"| {v['voice_name']} | {v['voice_id']} | {v.get('transcription_text', 'N/A')[:20]}... |")

if __name__ == "__main__":
    list_voices()

path: scripts/tts.py
content: import requests, base64, argparse, os, json, subprocess, sys, time

# 不同渠道推荐格式 (飞书需要 opus/ogg 才能显示为语音消息)
CHANNEL_FORMATS = {
    "feishu": "ogg",   # opus 编码的 ogg → 飞书语音消息
    "discord": "mp3", 
    "telegram": "ogg", # opus 编码
    "whatsapp": "ogg",
    "signal": "mp3",
    "slack": "mp3",
    "default": "mp3"
}

def convert_audio(input_file, output_file, target_format):
    """使用 ffmpeg 转换音频格式"""
    try:
        if target_format == "ogg":
            cmd = ["ffmpeg", "-y", "-i", input_file, "-c:a", "libopus", "-b:a", "64k", output_file]
        else:
            cmd = ["ffmpeg", "-y", "-i", input_file, "-c:a", "libmp3lame", "-q:a", "2", output_file]
        result = subprocess.run(cmd, capture_output=True, text=True)
        return result.returncode == 0
    except FileNotFoundError:
        return False

def tts():
    parser = argparse.ArgumentParser(description="MOSS-TTS 语音合成")
    parser.add_argument("--text", required=True, help="待合成的文本")
    parser.add_argument("--voice_id", default=None, help="音色ID（预注册的）")
    parser.add_argument("--reference_audio", default=None, help="参考音频路径（实时克隆）")
    parser.add_argument("--output", default=None, help="输出文件路径 (可选)")
    parser.add_argument("--channel", default=None, help="目标渠道: feishu, discord, telegram, whatsapp, signal, slack")
    parser.add_argument("--target", default=None, help="发送目标 (用户ID/频道ID，可选)")
    parser.add_argument("--format", default=None, help="输出格式: mp3, ogg, wav (可选，默认根据 channel 自动选择)")
    parser.add_argument("--json", action="store_true", help="输出 JSON 格式结果")
    args = parser.parse_args()

    [REDACTED_SECRET]"MOSS_API_KEY")
    if not [REDACTED_SECRET] = {"error": "MOSS_API_KEY 环境变量未设置"}
        print(json.dumps(result) if args.json else f"Error: {result['error']}")
        sys.exit(1)

    # 必须提供 voice_id 或 reference_audio
    if not args.voice_id and not args.reference_audio:
        result = {"error": "必须提供 --voice_id 或 --reference_audio 参数"}
        print(json.dumps(result) if args.json else f"Error: {result['error']}")
        sys.exit(1)

    # 确定输出格式
    target_format = args.format
    if not target_format and args.channel:
        target_format = CHANNEL_FORMATS.get(args.channel, CHANNEL_FORMATS["default"])
    if not target_format:
        target_format = "wav"
    
    # 确定输出路径
    if args.output:
        output_file = args.output
    else:
        tmp_dir = "/tmp/openclaw/moss-tts"
        # 检测 /tmp 目录是否可写
        try:
            test_file = "/tmp/.openclaw_write_test"
            with open(test_file, "w") as f:
                f.write("test")
            os.remove(test_file)
        except (PermissionError, OSError) as e:
            result = {"error": f"/tmp 目录无写入权限: {e}"}
            print(json.dumps(result) if args.json else f"Error: {result['error']}")
            sys.exit(1)
        os.makedirs(tmp_dir, exist_ok=True)
        output_file = f"{tmp_dir}/voice-{int(time.time()*1000)}.{target_format}"

    # 构建请求
    url = "https://studio.mosi.cn/v1/audio/tts"
    headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
    payload = {
        "model": "moss-tts",
        "text": args.text,
    }
    
    if args.voice_id:
        payload["voice_id"] = args.voice_id
    elif args.reference_audio:
        with open(args.reference_audio, "rb") as f:
            payload["reference_audio"] = base64.b64encode(f.read()).decode("utf-8")

    try:
        resp = requests.post(url, json=payload, headers=headers, timeout=60)
        data = resp.json()
    except Exception as e:
        result = {"error": f"API 请求失败: {e}"}
        print(json.dumps(result) if args.json else f"Error: {result['error']}")
        sys.exit(1)

    if "audio_data" not in data:
        result = {"error": data.get("error", data.get("message", str(data)))}
        print(json.dumps(result) if args.json else f"Error: {result['error']}")
        sys.exit(1)

    # 保存原始 WAV
    raw_output = output_file if target_format == "wav" else output_file.replace(f".{target_format}", ".wav")
    with open(raw_output, "wb") as f:
        f.write(base64.b64decode(data["audio_data"]))

    # 格式转换
    if target_format != "wav":
        if convert_audio(raw_output, output_file, target_format):
            os.remove(raw_output)
        else:
            output_file = raw_output
            target_format = "wav"

    # 输出结果
    result = {
        "success": True,
        "file": output_file,
        "format": target_format,
        "channel": args.channel,
        "target": args.target
    }
    
    if args.json:
        print(json.dumps(result))
    else:
        print(f"✅ 音频已生成: {output_file}")
        if args.channel:
            print(f"   渠道: {args.channel}")
        if args.target:
            print(f"   目标: {args.target}")

if __name__ == "__main__":
    tts()


path: scripts/clone.py
content: import requests, os, argparse

def clone_voice():
    parser = argparse.ArgumentParser()
    parser.add_argument("--file", required=True)
    parser.add_argument("--name", default="ClonedVoice")
    args = parser.parse_args()

    [REDACTED_SECRET]"MOSS_API_KEY")
    headers = {"Authorization": f"Bearer {api_key}"}

    # 1. Upload
    with open(args.file, "rb") as f:
        up_resp = requests.post("https://studio.mosi.cn/api/v1/files", 
                               headers=headers, files={"file": f})
    file_id = up_resp.json().get("file_id")

    # 2. Clone
    payload = {"file_id": file_id, "voice_name": args.name}
    cl_resp = requests.post("https://studio.mosi.cn/api/v1/voice/clone", 
                            headers=headers, json=payload)
    print(cl_resp.text)

if __name__ == "__main__":
    clone_voice()

path: references/channel-formats.md
content: # 渠道格式说明

## 为什么需要格式转换？

不同平台对语音消息的要求不同：

- **飞书/Telegram/WhatsApp** - 要求 opus 编码的 ogg 格式才能显示为语音消息
- **Discord/Signal/Slack** - 只能显示为文件附件

## 格式对照表

| 渠道 | 推荐格式 | 编码 | 消息类型 | 说明 |
|------|----------|------|----------|------|
| feishu | ogg | libopus | 语音消息 | ✅ 真正的语音 |
| telegram | ogg | libopus | 语音消息 | ✅ 真正的语音 |
| whatsapp | ogg | libopus | 语音消息 | ✅ 真正的语音 |
| discord | mp3 | libmp3lame | 文件 | 文件附件 |
| signal | mp3 | libmp3lame | 文件 | 文件附件 |
| slack | mp3 | libmp3lame | 文件 | 文件附件 |

## FFmpeg 转换命令

### WAV → OGG (opus)
```bash
ffmpeg -y -i input.wav -c:a libopus -b:a 64k output.ogg
```

### WAV → MP3
```bash
ffmpeg -y -i input.wav -c:a libmp3lame -q:a 2 output.mp3
```

## OpenClaw 飞书插件逻辑

```javascript
// media.ts 第 274-277 行
const msgType = fileType === "opus" ? "audio" : fileType === "mp4" ? "media" : "file";
```

- `opus` → 发送 `msg_type: "audio"` → 语音消息
- 其他 → 发送 `msg_type: "file"` → 文件附件

## 最佳实践

### 飞书语音消息
```bash
# 必须用 ogg 格式
python3 scripts/tts.py --text "测试" --channel feishu --reference_audio voice.ogg
```

### Discord 文件
```bash
# mp3 即可
python3 scripts/tts.py --text "测试" --channel discord --reference_audio voice.ogg
```

## 注意事项

1. **文件后缀** - 必须是 `.ogg`，不能是 `.oga`
2. **编码** - 必须是 `libopus`，不是默认编码
3. **比特率** - 推荐 64k，足够清晰


path: references/troubleshooting.md
content: # 问题排查

## 快速诊断

```bash
# 1. 检查 API Key
echo $MOSS_API_KEY
# 应该显示: sk-xxx...

# 2. 测试连通性
curl https://studio.mosi.cn/api/v1/voices \
  -H "Authorization: Bearer $MOSS_API_KEY"
# 应该返回 JSON（非 401）

# 3. 检查依赖
which python3 && which ffmpeg
# 两个都应该有路径
```

---

## 常见错误

### 1. "MOSS_API_KEY 环境变量未设置"

**原因**：未配置 API Key

**解决**：
```bash
# 临时（当前终端）
export MOSS_API_KEY="sk-xxx"

# 永久（写入配置文件）
echo 'export MOSS_API_KEY="sk-xxx"' >> ~/.zshrc
source ~/.zshrc
```

---

### 2. "ffmpeg: command not found"

**原因**：未安装 ffmpeg

**解决**：
```bash
brew install ffmpeg

# 验证
ffmpeg -version
```

---

### 3. 飞书收到文件而不是语音消息

**原因**：音频格式不对

**检查**：
```bash
file voice.ogg
# 应该显示: Ogg data, Opus audio

# 如果不是，重新转换：
ffmpeg -y -i input.wav -c:a libopus -b:a 64k output.ogg
```

**确保**：
- 文件后缀是 `.ogg`
- 编码是 `libopus`
- 不是 `libvorbis` 或其他编码

---

### 4. "Voice Not Found: voice not found"

**原因**：voice_id 无效

**解决**：
```bash
# 查询可用音色
curl https://studio.mosi.cn/api/v1/voices \
  -H "Authorization: Bearer $MOSS_API_KEY"

# 确认：
# 1. voice_id 正确
# 2. status 为 ACTIVE（不是 PENDING 或 FAILED）
```

---

### 5. API 返回 429 错误

**原因**：请求频率超限

**解决**：
1. 等待 5-10 秒后重试
2. 减少并发请求
3. 升级 MOSS Studio 套餐

---

### 6. 克隆任务失败 (status: FAILED)

**原因**：音频质量问题

**检查**：
- 音频时长是否 10-30 秒
- 是否清晰人声（无噪音、BGM）
- 文件是否损坏

**解决**：
```bash
# 检查音频
ffprobe voice.ogg

# 重新录制，确保：
# 1. 安静环境
# 2. 正常语速
# 3. 无背景音乐
```

---

### 7. Python "ModuleNotFoundError: No module named 'requests'"

**原因**：缺少依赖

**解决**：
```bash
cd ~/.openclaw/workspace/skills/moss-tts-voice
python3 -m venv .venv
source .venv/bin/activate
pip install requests
```

---

### 8. "Data too long for column 'input_source'"

**原因**：base64 音频太大

**解决**：
1. 使用预注册音色（推荐）
2. 或压缩音频：
   ```bash
   ffmpeg -i voice.ogg -t 20 -c:a libopus -b:a 32k compressed.ogg
   ```

---

### 9. 克隆效果不好

**原因**：参考音频质量差

**建议**：
- ✅ 时长 20 秒以上
- ✅ 清晰人声，无背景噪音
- ✅ 正常语速
- ❌ 不要有背景音乐
- ❌ 不要有其他人声
- ❌ 不要太快或太慢

---

### 10. 音频转换失败

**原因**：ffmpeg 参数错误

**解决**：
```bash
# 正确的转换命令
ffmpeg -y -i input.wav -c:a libopus -b:a 64k output.ogg

# 注意：
# - 必须用 libopus 编码
# - 不要用默认的 libvorbis
# - 比特率 64k 足够清晰
```

---

## 调试技巧

### 检查 API 连通性

```python
import requests, json

[REDACTED_SECRET]"
headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# 测试 TTS
resp = requests.post(
    "https://studio.mosi.cn/v1/audio/tts",
    headers=headers,
    json={"model": "moss-tts", "text": "测试", "voice_id": "YOUR_VOICE_ID"},
    timeout=30
)

print(f"Status: {resp.status_code}")
print(f"Response: {json.dumps(resp.json(), ensure_ascii=False)[:200]}")
```

### 检查音频格式

```bash
# 查看详细信息
ffprobe -v error -show_streams voice.ogg

# 检查编码
ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 voice.ogg
# 应该输出: opus
```

### 检查音色状态

```bash
curl https://studio.mosi.cn/api/v1/voices \
  -H "Authorization: Bearer $MOSS_API_KEY" | jq .
```

---

## 联系支持

- **MOSS Studio**: https://studio.mosi.cn
- **OpenClaw 社区**: https://discord.com/invite/clawd

---

## 日志收集

如果问题持续，收集以下信息：

```bash
# 系统信息
uname -a
python3 --version
ffmpeg -version | head -1

# API 测试
curl -v https://studio.mosi.cn/api/v1/voices \
  -H "Authorization: Bearer $MOSS_API_KEY" 2>&1 | grep -E "HTTP|code|error"

# 音频信息
ffprobe -v error -show_format -show_streams your_audio.ogg
```


path: references/api-guide.md
content: # MOSS-TTS API 技术指南

## API 端点

| 用途 | 方法 | 端点 |
|------|------|------|
| 文本转语音 | POST | `https://studio.mosi.cn/v1/audio/tts` |
| 上传文件 | POST | `https://studio.mosi.cn/api/v1/files/upload` |
| 克隆音色 | POST | `https://studio.mosi.cn/api/v1/voice/clone` |
| 查询音色 | GET | `https://studio.mosi.cn/api/v1/voices` |

## 认证

```http
[REDACTED_SECRET]
Content-Type: application/json
```

---

## 1. 文本转语音 (TTS)

### 请求

```
POST /v1/audio/tts
```

### 必填参数

| 参数 | 类型 | 说明 |
|------|------|------|
| `model` | string | 固定值 `"moss-tts"` |
| `text` | string | 待合成文本 |

### 音色参数（二选一）

| 参数 | 类型 | 说明 |
|------|------|------|
| `voice_id` | string | 预注册音色ID（推荐） |
| `reference_audio` | string | Base64 编码的参考音频 |

### 可选参数

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `sampling_params.temperature` | float | 1.7 | 采样温度 |
| `sampling_params.top_p` | float | 0.8 | Top-p 采样 |
| `sampling_params.top_k` | int | 25 | Top-k 采样 |

### 示例

**使用预注册音色：**
```bash
curl -X POST https://studio.mosi.cn/v1/audio/tts \
  -H "Authorization: Bearer $MOSS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "moss-tts",
    "text": "你好，我是MOSS",
    "voice_id": "YOUR_VOICE_ID"
  }'
```

**使用实时克隆：**
```python
import requests, base64

with open("voice.ogg", "rb") as f:
    audio_base64 = base64.b64encode(f.read()).decode()

resp = requests.post(
    "https://studio.mosi.cn/v1/audio/tts",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "moss-tts",
        "text": "要合成的文本",
        "reference_audio": audio_base64
    }
)

audio_wav = base64.b64decode(resp.json()["audio_data"])
```

### 响应

**成功：**
```json
{
  "audio_data": "UklGRiQAAABXQVZFZm10..."
}
```

**错误：**
```json
{
  "code": 4004,
  "error": "Voice Not Found: voice not found"
}
```

---

## 2. 上传文件

### 请求

```
POST /api/v1/files/upload
Content-Type: multipart/form-data
```

### 参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `file` | file | ✅ | 音频文件 |

### 示例

```bash
curl -X POST https://studio.mosi.cn/api/v1/files/upload \
  -H "Authorization: Bearer $MOSS_API_KEY" \
  -F "file=@voice.ogg"
```

### 响应

```json
{
  "file_id": "YOUR_FILE_ID",
  "file_name": "voice.ogg",
  "file_size": 65391,
  "content_type": "audio/ogg",
  "status": "uploaded"
}
```

---

## 3. 克隆音色

### 请求

```
POST /api/v1/voice/clone
Content-Type: application/json
```

### 参数

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `file_id` | string | ✅ | 上传文件返回的 ID |
| `name` | string | ❌ | 音色名称 |

### 示例

```bash
curl -X POST https://studio.mosi.cn/api/v1/voice/clone \
  -H "Authorization: Bearer $MOSS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_id": "YOUR_FILE_ID", "name": "我的声音"}'
```

### 响应

```json
{
  "job_id": "2030984715560816640_xxx",
  "status": "PENDING",
  "voice_id": "YOUR_VOICE_ID",
  "transcription_source": "AUTO_ASR"
}
```

### 状态流转

```
PENDING → PROCESSING → ACTIVE
                   ↘ FAILED
```

---

## 4. 查询音色列表

### 请求

```
GET /api/v1/voices
```

### 响应

```json
{
  "count": 1,
  "voices": [
    {
      "voice_id": "YOUR_VOICE_ID",
      "voice_name": "我的声音",
      "status": "ACTIVE",
      "created_at": "2026-03-10T17:24:03+08:00"
    }
  ]
}
```

---

## 错误码

| 代码 | 说明 |
|------|------|
| 4000 | 请求参数错误 |
| 4001 | 缺少必要参数 |
| 4004 | 音色未找到 |
| 4290 | 请求频率超限 |
| 5000 | 服务器内部错误 |

---

## 音频要求

### 参考音频（克隆用）

| 项目 | 要求 |
|------|------|
| 格式 | ogg, mp3, wav, m4a |
| 时长 | 10-30 秒（推荐 20 秒以上） |
| 内容 | 清晰人声，无背景噪音 |
| 大小 | < 10MB |

### 输出音频

- 格式：WAV（原始）
- 采样率：16000 Hz
- 声道：单声道

---

## 速率限制

- 具体 QPS 限制参考 MOSS Studio 控制台
- 遇到 429 错误时等待后重试
- 建议使用预注册音色（减少音频传输）

---

## 调试技巧

### 测试 API 连通性

```bash
MOSS_API_KEY="sk-xxx" python3 -c "
import requests, json
headers = {'Authorization': f'Bearer \$MOSS_API_KEY', 'Content-Type': 'application/json'}
resp = requests.post('https://studio.mosi.cn/v1/audio/tts',
                    headers=headers,
                    json={'model': 'moss-tts', 'text': 'test'},
                    timeout=10)
print(f'Status: {resp.status_code}')
print(json.dumps(resp.json(), ensure_ascii=False)[:200])
"
```

### 检查音频格式

```bash
ffprobe -v error -show_entries stream=codec_name,codec_type -of default=noprint_wrappers=1 voice.ogg
```

---

## 联系支持

- MOSS Studio: https://studio.mosi.cn
- OpenClaw 社区: https://discord.com/invite/clawd


path: .clawhub/origin.json
content: version: 1
registry: https://clawhub.ai
slug: moss-tts-voice
installedVersion: 1.2.1
installedAt: 1773037029049

Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)