# tts-converter - 语音合成

> 使用微软 Edge 浏览器的语音合成技术，将文字转换为高质量的音频文件。完全免费，支持多种语言和声音。用于将口播稿子转换成音频文件、批量生成语音内容、制作播客有声书、为视频配音、生成语音提示音

- Skill: `manke001-zhy/tts-converter` (Agent Skill, multi-file: 37 files)
- Install (CLI): `npx skillmds@latest add manke001-zhy/tts-converter`
- Raw SKILL.md: https://api.skillmd.com/api/skills/manke001-zhy/tts-converter/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: manke001-zhy (https://skillmd.com/u/manke001-zhy)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/manke001-zhy/tts-converter

---


# 文字转语音（TTS）技能

## 功能说明

使用微软 Edge 浏览器的语音合成技术，将文字转换为高质量的音频文件。完全免费，支持多种语言和声音。

## 适用场景

当你需要：
- 将口播稿子转换成音频文件
- 批量生成语音内容
- 制作播客、有声书
- 为视频配音
- 生成语音提示音

## 使用方法

### 方式1：简单命令（推荐）

直接告诉Claude：
```
把 [文件] 转成音频
把 "口播稿.txt" 转成 mp3
```

**示例**：
```
把 "演讲稿.md" 转成音频
把桌面的 "故事.txt" 转成 mp3 文件
```

### 方式2：指定声音

```
用 [声音名称] 把 [文件] 转成音频
```

**示例**：
```
用女声把 "稿子.txt" 转成音频
用xiaoxiao把 "文章.md" 转成 mp3
```

### 方式3：广播剧稿子转音频 🎭

直接把广播剧稿子转换成多角色MP3：

```
把 "广播剧稿子.txt" 转成广播剧音频
```

**稿子格式**（支持多种格式）：

**格式1：冒号分隔**
```
男主角：你好，世界。
女主角：你好！
旁白：他们相遇了。
```

**格式2：方括号** ⭐ 推荐
```
【男主角】你好，世界。
【女主角】你好！
```

**格式3：Markdown复杂格式**
```markdown
### **角色列表**

【旁白】全知视角，负责交代背景。

【男主角】男主角，二十岁，性格开朗。

【旁白】魔王城矗立在荒凉的平原之上，阴森的云层压得很低。

【男主角】唉，人生剧本是不是拿错了。
```

⚠️ **重要提示**：
- 格式3包含"角色列表"部分，需要跳过短描述（<80字）
- **开篇旁白必须保留**，用来交代背景和场景

**支持的角色名**：
- 男主角/男1/男2 → 云希（年轻男声）
- 女主角/女1 → 晓晓（温柔女声）
- 女2 → 晓伊（成熟女声）
- 旁白 → 云扬（成熟男声，更有磁性）
- 我 → 云希（年轻男声）
- AI → 晓晓（AI女声）

### 方式4：命令行使用

```bash
# 广播剧稿子转音频
python drama_to_audio.py 稿子.txt 输出.mp3

# 单个文本转音频
python tts.py input.txt output.mp3

# 指定声音
python tts.py input.txt output.mp3 --voice zh-CN-XiaoxiaoNeural

# 调整语速（0.5-2.0，默认1.0）
python tts.py input.txt output.mp3 --rate 1.2

# 调整音调（-50% 到 +100%，默认0%）
python tts.py input.txt output.mp3 --pitch +10%
```

## 支持的声音

### 中文女声（推荐）
- `zh-CN-XiaoxiaoNeural` - 晓晓（温柔女声，默认）
- `zh-CN-XiaoyiNeural` - 晓伊（温柔女声）
- `zh-CN-YunyangNeural` - 云扬（温柔女声）
- `zh-CN-XiaomengNeural` - 晓梦（活泼女声）
- `zh-CN-XiaohanNeural` - 晓涵（活泼女声）

### 中文男声
- `zh-CN-YunyangNeural` - 云扬（男声）
- `zh-CN-YunxiNeural` - 云希（年轻男声）
- `zh-CN-YunzeNeural` - 云泽（年轻男声）
- `zh-CN-YunjianNeural` - 云建（成熟男声）

### 其他语言
- `en-US-JennyNeural` - 英语女声
- `ja-JP-NanamiNeural` - 日语女声
- `ko-KR-SunHiNeural` - 韩语女声

## 特点

✅ **免费使用**：无需付费，无限制使用
✅ **音质自然**：使用微软最新的神经网络语音
✅ **支持中文**：完美的中文发音
✅ **离线处理**：在本地运行，不需要上传数据
✅ **批量转换**：支持批量处理多个文件
✅ **参数调整**：可调节语速、音调、音量

## 技术实现

**使用工具**：
- Python 3
- edge-tts（微软 Edge 语音合成）
- aiohttp（异步 HTTP 请求）

**核心优势**：
- ✅ 完全免费，无需 API key
- ✅ 音质接近商业语音合成
- ✅ 支持多种语言和声音
- ✅ 可调节语速和音调

## 依赖项

```bash
pip install edge-tts
```

## 输出格式

支持多种音频格式：
- **MP3**（推荐）：体积小，兼容性好
- **WAV**：无损音质
- **OGG**：开源格式

## 参数说明

| 参数 | 说明 | 默认值 | 范围 |
|------|------|--------|------|
| --voice | 语音名称 | zh-CN-XiaoxiaoNeural | 见上方列表 |
| --rate | 语速 | 1.0 | 0.5 - 2.0 |
| --pitch | 音调 | 0% | -50% - +100% |
| --volume | 音量 | 0% | -50% - +100% |

## 示例

### 示例1：转换口播稿

**输入**：
```
把 "口播稿.txt" 转成 mp3
```

**输出**：
- `口播稿.mp3`（使用晓晓女声）

### 示例2：使用男声

**输入**：
```
用云希的声音把 "演讲.md" 转成音频
```

**输出**：
- `演讲.mp3`（使用云希男声）

### 示例3：调整语速

**输入**：
```
把 "小说.txt" 转成 mp3，语速调快一点
```

**输出**：
- `小说.mp3`（语速 1.2 倍）

## 查看所有可用声音

```bash
# 列出所有中文声音
python tts.py --list-voices zh

# 列出所有声音
python tts.py --list-voices all
```

## 注意事项

- 首次使用需要联网下载语音数据
- 转换速度取决于文本长度和网络速度
- 建议使用 UTF-8 编码的文本文件
- 长文本可能需要较长的转换时间

## 故障排除

### 问题：转换失败或没有声音

**解决方法**：
1. 检查网络连接
2. 确认输入文件编码为 UTF-8
3. 尝试更新 edge-tts：
   ```bash
   pip install --upgrade edge-tts
   ```

### 问题：语速太快或太慢

**解决方法**：
- 使用 `--rate` 参数调整
- 正常语速：1.0
- 快速：1.2 - 1.5
- 慢速：0.8 - 0.9

### 问题：声音不够自然

**解决方法**：
1. 尝试不同的声音（推荐使用 Neural 结尾的）
2. 调整语速和音调
3. 在文本中添加适当的标点符号

## 智能广播剧制作 🎭 v2.0

### 自动角色识别与声音匹配

新增的智能版工具（`drama_to_audio_v2.py`）可以自动识别脚本中的角色信息，智能匹配声音，并根据性格调整语速。

#### 功能特点

✅ **自动识别角色**：从脚本开头的"角色列表"中提取角色特征
✅ **智能声音匹配**：根据年龄、性别自动选择合适的声音
✅ **性格语速调整**：急躁角色1.2倍速，沉稳角色0.85倍速
✅ **角色名提示**：对话前自动添加角色名（如"莱昂。唉，人生剧本..."）

#### 使用方法

**基础用法**：
```bash
python drama_to_audio_v2.py 脚本.md 广播剧.mp3
```

**可选参数**：
```bash
# 不添加角色名提示
python drama_to_audio_v2.py 脚本.md 广播剧.mp3 --no-name-prompt

# 不使用语速调整
python drama_to_audio_v2.py 脚本.md 广播剧.mp3 --no-speed-adjustment
```

#### 脚本格式要求

脚本开头必须包含"角色列表"部分：

```markdown
### **角色列表**

【旁白】全知视角，负责交代背景、环境渲染及转场衔接。

【莱昂】男主角，二十二岁，原本是见习骑士。内心充满槽点。

【汤姆】莱昂的侍从，热血少年，正义感过剩，声音宏亮。

【艾莉丝】王国公主，外表完美，实则是极度理想主义的政治狂热者。

【魔王】魔王城之主，优雅但疲惫，被公主的学术演讲折磨到濒临崩溃。

【国王】艾莉丝的父亲，重度女儿奴，情绪波动剧烈，容易老泪纵横。

---

【旁白】魔王城矗立在荒凉的平原之上...

【莱昂】唉，人生剧本是不是拿错了。
```

#### 角色识别规则

**年龄识别**：
- ≤ 25岁 → "年轻"
- 26-45岁 → "成熟"
- \> 45岁 → "中年"

**性别识别**：
- 特殊角色：旁白 → "旁白"
- 女性关键词：女主角、她、公主、女王、少女、女孩、小姐、母亲
- 男性关键词：男主角、他、骑士、王子、国王、魔王、少年、男孩、父亲

**性格识别**：
- 急躁：急躁、热血、冲动、急切、火爆 → 语速1.2倍
- 沉稳：沉稳、冷静、成熟、稳重、优雅、疲惫 → 语速0.85倍
- 活泼：活泼、开朗、欢快、愉快、兴奋 → 语速1.0倍
- 默认：正常 → 语速1.0倍

#### 声音匹配策略

| 角色类型 | 声音ID | 声音描述 | 适用场景 |
|---------|--------|---------|---------|
| 旁白 | zh-CN-YunjianNeural | 成熟男声 | 背景描述、场景转换 |
| 男-年轻 | zh-CN-YunxiNeural | 年轻男声 | 少年主角 |
| 男-成熟 | zh-CN-YunzeNeural | 稳重男声 | 成年男性 |
| 男-中年 | zh-CN-YunyangNeural | 中年男声 | 中年男性 |
| 女-年轻-活泼 | zh-CN-XiaomengNeural | 活泼女声 | 活泼少女 |
| 女-年轻-温柔 | zh-CN-XiaoxiaoNeural | 温柔女声 | 温柔少女 |
| 女-成熟 | zh-CN-XiaoyiNeural | 成熟女声 | 成熟女性 |

**冲突解决**：
- 当多个角色使用同类型声音时，优先保持第一个角色不变
- 其他角色从备选声音列表中选择
- 如果备选列表耗尽，使用相同声音但不同语速区分

#### 输出示例

```bash
[INFO] 识别到 6 个角色
  - 旁白: 旁白, 年轻, 正常
  - 莱昂: 男, 年轻, 正常
  - 艾莉丝: 女, 年轻, 活泼
  - 汤姆: 男, 年轻, 急躁
  - 魔王: 男, 成熟, 沉稳
  - 国王: 男, 成熟, 沉稳

[INFO] 声音分配结果:
  旁白: 成熟男声
  莱昂: 年轻男声
  艾莉丝: 温柔女声
  汤姆: 年轻男声 语速+20%
  魔王: 成熟男声 语速-15%
  国王: 成熟男声

[1/50] 旁白: 旁白。魔王城矗立在荒凉的平原之上...
[2/50] 莱昂。唉，人生剧本是不是拿错了。
[3/50] 汤姆: 汤姆。莱昂大人——公主殿下被魔王抓走了——
```

#### 与旧版工具的区别

| 功能 | drama_to_audio.py | drama_to_audio_v2.py |
|-----|------------------|---------------------|
| 角色识别 | ❌ 手动配置 | ✅ 自动识别 |
| 声音匹配 | ❌ 手动配置 | ✅ 智能匹配 |
| 性格语速 | ❌ 不支持 | ✅ 自动调整 |
| 角色名提示 | ❌ 不支持 | ✅ 自动添加 |
| 兼容性 | ✅ 完全向后兼容 | ✅ 完全向后兼容 |

**推荐使用场景**：
- 新项目 → 使用 `drama_to_audio_v2.py`
- 已有项目 → 两种工具都可以
- 需要精细控制 → 使用 `drama_to_audio.py`

---

## 广播剧制作完整流程 🎭

### 实战案例：制作多角色广播剧

以下是基于实际项目（广播剧《三千年后的我与AI女友还在吵架》）总结的完整流程。

#### 步骤1：准备脚本

**脚本格式要求**：
```
**\[角色名\]**：
对话内容
```

**示例**：
```markdown
**\[旁白\]**：
新东京历，3024年。这是一个人类早已习惯将意识上传到云端的时代。

**\[艾米\]**：
\[机械式的轻快感\] 喂，和也，起床了。根据早间气象和你的睡眠数据分析，今天的幸福指数只有百分之三十二。

**\[和也\]**：
\[睡眼惺忪\] 艾米……我求你了，能不能把闹钟铃声换成正常人类的？
```

#### 步骤2：提取纯对话

使用脚本提取对话，去除：
- ✂️ 动作描述（如 `\[机械式的轻快感\]`）
- ✂️ 旁白描述
- ✂️ 空行
- ✂️ 角色介绍行

**转换格式**：
```
【旁白】新东京历，3024年。这是一个人类早已习惯将意识上传到云端的时代。
【艾米】喂，和也，起床了。根据早间气象和你的睡眠数据分析，今天的幸福指数只有百分之三十二。
【和也】艾米……我求你了，能不能把闹钟铃声换成正常人类的？
```

#### 步骤3：文本优化

**关键优化点**：

1. **替换冒号为逗号** ⚠️ 重要
   - ❌ 原文："生成结果如下：意识上传就是永生"
   - ✅ 优化："生成结果如下，意识上传就是永生"
   - 原因：TTS在冒号处会有明显停顿，影响流畅度

2. **保留完整对话**
   - 确保冒号后的内容不被截断
   - 检查脚本处理逻辑，不要丢失内容

3. **去除动作提示**
   - 删除 `\[...\]` 格式的情感/动作描述
   - 只保留纯对话内容

#### 步骤4：配置角色声音

根据角色特点选择合适的声音：

| 角色类型 | 推荐声音 | 声音ID | 适用场景 |
|---------|---------|--------|---------|
| **旁白** | 云建 | zh-CN-YunjianNeural | 成熟、磁性、稳重 |
| **少年男主** | 云希 | zh-CN-YunxiNeural | 年轻、清爽 |
| **成年男主** | 云泽 | zh-CN-YunzeNeural | 成熟男声 |
| **少女AI** | 晓晓 | zh-CN-XiaoxiaoNeural | 温柔、活泼 |
| **成熟女性** | 晓伊 | zh-CN-XiaoyiNeural | 成熟、知性 |
| **活泼少女** | 晓梦 | zh-CN-XiaomengNeural | 活泼、可爱 |

**添加自定义角色映射**（在 `drama_to_audio.py` 中）：
```python
VOICE_MAP = {
    '旁白': 'zh-CN-YunjianNeural',    # 成熟男声
    '和也': 'zh-CN-YunxiNeural',       # 少年男声
    '艾米': 'zh-CN-XiaoxiaoNeural',    # AI少女
    '星空': 'zh-CN-XiaoyiNeural',      # 温柔少女
}
```

#### 步骤5：生成音频

```bash
python drama_to_audio.py 广播剧_最终版.txt 广播剧_最终版.mp3
```

**输出示例**：
```
[INFO] 识别到 65 个对话片段

[预览] 前3个片段：
  旁白 (zh-CN-YunjianNeural): 新东京历，3024年...
  艾米 (zh-CN-XiaoxiaoNeural): 喂，和也，起床了...
  和也 (zh-CN-YunxiNeural): 艾米……我求你了...

[INFO] 共 65 个片段
[INFO] 正在合并音频...
[OK] 音频已生成: 广播剧_最终版.mp3
[INFO] 文件大小: 2.9 MB
```

#### 步骤6：质量检查

**检查清单**：
- [ ] 对话内容完整，无遗漏
- [ ] 冒号已替换为逗号，朗读流畅
- [ ] 每个角色声音区分明显
- [ ] 旁白使用成熟音，角色使用少年/少女音
- [ ] 音频时长合理（约3-5分钟/1000字）

### 常见问题及解决方案

#### 问题1：对话内容被截断

**症状**：
```
原文：生成结果如下：意识上传就是永生
实际：生成结果如下（后面的内容丢失）
```

**原因**：
- 脚本把冒号当作分隔符处理
- 正则表达式匹配不当

**解决**：
- 只在对话开头提取角色名
- 保留对话中所有标点符号（包括冒号）
- 测试时先打印前几条对话验证

#### 问题2：TTS朗读有停顿

**症状**：
- 冒号处有明显停顿
- 语调不连贯

**解决**：
- 统一将冒号替换为逗号
- 检查文本，确保没有其他导致停顿的标点

#### 问题3：角色声音不明显

**症状**：
- 多个角色听起来像同一个声音

**解决**：
- 使用明显不同的声音类型
- 旁白用成熟音（云建）
- 少年角色用年轻音（云希）
- 少女角色用温柔音（晓晓）

#### 问题4：开篇旁白被误删 ⚠️ 高频问题

**症状**：
```
原文：【旁白】魔王城矗立在荒凉的平原之上...
实际：第一段旁白丢失，对话从主角台词开始
```

**原因**：
- 脚本包含"角色列表"部分
- 过滤逻辑误将开篇旁白当作角色介绍删除
- 简单的关键词匹配（如"魔王城"）导致误删

**解决方案**：
1. **识别脚本结构**：区分"角色列表"和"实际对话"
2. **使用长度判断**：跳过短描述（<80字），保留长对话
3. **保留所有长旁白**：开篇旁白通常>80字，用来交代背景

**示例代码**：
```python
skip_intro = True  # 跳过角色列表部分

for line in lines:
    match = re.match(r'^【(.+?)】(.+)$', line)
    if match:
        role, dialogue = match.groups()

        # 找到第一个长对话，说明角色列表结束
        if skip_intro and len(dialogue) > 80:
            skip_intro = False

        # 跳过角色列表
        if skip_intro:
            continue

        # 处理对话...
```

**关键原则**：
- ✅ 每个广播剧开头的长旁白（>80字）都保留
- ✅ 角色列表部分的短描述（<80字）跳过
- ❌ 不要用内容关键词来判断是否删除

### 最佳实践总结

1. **脚本处理**：
   - 使用专门的脚本提取对话
   - 批量处理动作描述
   - 保留完整对话内容
   - ⭐ **识别脚本结构**：区分角色列表和实际对话
   - ⭐ **保留开篇旁白**：长旁白（>80字）必须保留

2. **文本优化**：
   - ✅ 冒号→逗号（提升流畅度）
   - ✅ 去除动作提示
   - ✅ 保留情感标点（……、！）
   - ⭐ **不要用关键词过滤**：避免误删包含特定词汇的对话

3. **声音配置**：
   - 旁白：成熟稳重
   - 主角：少年/少女音
   - 配角：根据特点选择
   - ⭐ **提前添加角色映射**：避免未知角色用默认声音

4. **质量保证**：
   - 先生成短片段测试
   - 检查对话完整性
   - 验证声音区分度
   - ⭐ **验证开篇旁白**：确保第一段是背景交代

## 最佳实践

1. **口播稿**：使用晓晓或晓伊，语速 1.0-1.1
2. **有声书**：使用云扬，语速 1.0，注意分段
3. **快节奏**：使用晓梦，语速 1.2-1.3
4. **正式演讲**：使用云建，语速 0.9-1.0
5. **广播剧**：多角色配音，旁白用成熟音，角色用少年/少女音

