v2收尾:手势升级 + 暂停退出 + 结局语音化 + 分支补全 + 12条新音频
gestures.js: 新增长按(1s)、两指长按(暂停)、三指点击(退出),支持多指检测 engine.js: REPLY_COUNT变量、长按重播/状态广播、暂停恢复退出机制、 选择提示音、结局台词预录音频替换TTS、内容预警+心理热线 story.js: MSG-10/11 follow-up补全down(沉默)选项 index.html: 操作指南添加长按/安全手势、内容预警文字 batch_tts_voxcpm.py: 新增12条台词(结局旁白+系统提示+分支NPC反应) audio/mp3/tts: 12个VoxCPM2生成的林夏声线MP3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+126
-260
@@ -1,7 +1,9 @@
|
||||
# 《林夏》音频素材本地制作执行文档
|
||||
|
||||
> **前置文档**:`林夏.md`(游戏设计)、`SOP_AI音频生产.md`(生产规范)
|
||||
> **执行环境**:本机 WSL2 · RTX 5090 32GB · CosyVoice2-0.5B · FFmpeg 7.0
|
||||
> **执行环境**:本机 WSL2 · RTX 5090 32GB · FFmpeg 7.0
|
||||
> **TTS 主链路**:**VoxCPM2**(见 `林夏.md` §7.2),批量脚本 `audio/batch_tts_voxcpm.py`
|
||||
> **TTS 备用**:CosyVoice2-0.5B(见附录 B)
|
||||
> **目标**:按 SOP 规范在本地生产全部音频素材
|
||||
|
||||
---
|
||||
@@ -10,12 +12,14 @@
|
||||
|
||||
| 资源 | 路径 / 状态 | 用途 |
|
||||
|---|---|---|
|
||||
| CosyVoice 2.0 (0.5B) | `/home/xsl/tools/CosyVoice` · conda env: `cosyvoice` | TTS 主力(替代 SOP 中 MiniMax/豆包方案) |
|
||||
| **VoxCPM2** | `bash /home/xsl/AutoVideo/start-voxcpm.sh` → `http://127.0.0.1:8000` | **TTS 主链路**(声音克隆 + 合成) |
|
||||
| CosyVoice 2.0 (0.5B) | `/home/xsl/tools/CosyVoice` · conda env: `cosyvoice` | TTS 备用(见附录 B) |
|
||||
| FFmpeg 7.0 | `/usr/local/bin/ffmpeg` | 音频格式转换、响度归一化、听筒效果 |
|
||||
| GPU | RTX 5090 32GB | 跑 CosyVoice 推理 |
|
||||
| GPU | RTX 5090 32GB | 跑 VoxCPM2 / CosyVoice 推理 |
|
||||
| MuseTalk | `/home/xsl/work/MuseTalk` | **注意:这是唇形同步工具,不是 TTS** |
|
||||
|
||||
> **SOP 中的 MiniMax / 豆包 API 全部替换为本地 CosyVoice**。音乐(Suno)、音效(ElevenLabs SFX)、环境采样(Freesound)仍走云端。
|
||||
> **SOP 中的 MiniMax / 豆包 API 全部替换为本地 VoxCPM2**。音乐(Suno)、音效(ElevenLabs SFX)、环境采样(Freesound)仍走云端。
|
||||
> CosyVoice2 保留作为备用方案(见附录 B),仅在 VoxCPM2 表现不佳时切换。
|
||||
|
||||
---
|
||||
|
||||
@@ -26,51 +30,27 @@
|
||||
```bash
|
||||
cd /home/xsl/blind
|
||||
mkdir -p audio/{00_raw/{tts,music,sfx,ambience,ringtone},01_processed/{tts,music,sfx,ambience,ringtone},02_final/{tts,music,sfx,ambience,ringtone},03_qa_reports,99_legal}
|
||||
mkdir -p audio/00_raw/tts/prompt_ref # 存放角色参考音频
|
||||
mkdir -p voice/{linxia,mom,azhe,xiaomei,zhounan,hr,anan,dorm_a,dorm_b,dorm_c,delivery,system} # 各角色参考音频
|
||||
```
|
||||
|
||||
### 1.2 验证 CosyVoice 环境
|
||||
### 1.2 启动 VoxCPM2 服务
|
||||
|
||||
```bash
|
||||
# 激活 conda 环境
|
||||
conda activate cosyvoice
|
||||
|
||||
# 验证依赖
|
||||
cd /home/xsl/tools/CosyVoice
|
||||
python -c "
|
||||
import sys
|
||||
sys.path.append('third_party/Matcha-TTS')
|
||||
from cosyvoice.cli.cosyvoice import CosyVoice2
|
||||
model = CosyVoice2('pretrained_models/CosyVoice2-0.5B')
|
||||
print('可用预训练音色:', model.list_available_spks())
|
||||
print('采样率:', model.sample_rate)
|
||||
print('CosyVoice2 加载成功')
|
||||
"
|
||||
# 启动 VoxCPM2 TTS 服务
|
||||
bash /home/xsl/AutoVideo/start-voxcpm.sh
|
||||
# uvicorn 服务: http://127.0.0.1:8000
|
||||
```
|
||||
|
||||
如果报错 `ModuleNotFoundError`,先装依赖:
|
||||
验证服务可用:
|
||||
```bash
|
||||
conda activate cosyvoice
|
||||
cd /home/xsl/tools/CosyVoice
|
||||
pip install -r requirements.txt
|
||||
curl -s http://127.0.0.1:8000/docs | head -5
|
||||
# 应返回 API 文档页面
|
||||
```
|
||||
|
||||
### 1.3 启动 CosyVoice WebUI
|
||||
|
||||
```bash
|
||||
conda activate cosyvoice
|
||||
cd /home/xsl/tools/CosyVoice
|
||||
python webui.py --port 8000
|
||||
```
|
||||
|
||||
浏览器访问 `http://localhost:8000`。WebUI 提供 4 种推理模式:
|
||||
|
||||
| 模式 | 说明 | 本项目用途 |
|
||||
|---|---|---|
|
||||
| **预训练音色** | 从内置音色列表选择 | 快速试听、系统 TTS |
|
||||
| **3s极速复刻** | 提供 3-30s 参考音频 + 对应文字 | **主力模式**:为每个角色准备参考音频 |
|
||||
| **跨语种复刻** | 跨语言克隆 | 暂不需要 |
|
||||
| **自然语言控制** | 用文字描述控制语气风格 | CosyVoice2 不支持此模式,改用 instruct2 API |
|
||||
**VoxCPM2 API 接口**(详见 `林夏.md` §7.2):
|
||||
- `POST /v1/voices` — 注册参考音频(wav_base64)→ 返回 voice_id
|
||||
- `POST /v1/speech` — 合成语音(text + voice_id)→ 返回 WAV
|
||||
- 输出格式:48kHz 16-bit PCM WAV
|
||||
|
||||
### 1.4 验证 FFmpeg
|
||||
|
||||
@@ -87,7 +67,7 @@ echo "FFmpeg loudnorm 可用"
|
||||
|
||||
## 2. 角色参考音频准备(关键步骤)
|
||||
|
||||
CosyVoice2 的"3s极速复刻"需要**每个角色一段 5-20 秒的参考音频**。参考音频的音色决定了最终 TTS 的音色。
|
||||
VoxCPM2 的声音克隆需要**每个角色一段参考音频**(WAV 格式)。参考音频的音色决定了最终 TTS 的音色。参考音频存放在 `voice/{角色}/` 目录下(详见 `林夏.md` §7.3 角色音色配置)。
|
||||
|
||||
### 2.1 参考音频来源方案
|
||||
|
||||
@@ -101,7 +81,7 @@ CosyVoice2 的"3s极速复刻"需要**每个角色一段 5-20 秒的参考音频
|
||||
| `anan` 安安 | 23 岁,可爱 | 年轻女性活泼语调截取 |
|
||||
| `dorm-a/b/c` | 三个不同年轻女声 | 需要 3 段风格不同的女声参考 |
|
||||
| `delivery` 外卖小哥 | 30 岁,北方腔 | 短视频/影视截取 |
|
||||
| `system` 系统 | 中性 AI 女声 | 用 CosyVoice 预训练音色即可 |
|
||||
| `system` 系统 | 中性 AI 女声 | VoxCPM2 注册一个中性女声参考音频 |
|
||||
| `self-3y` 3年前自己 | 同 xiaomei 基底 | 复用 xiaomei 参考音频,调速度和音调 |
|
||||
|
||||
### 2.2 参考音频制作规格
|
||||
@@ -111,229 +91,80 @@ CosyVoice2 的"3s极速复刻"需要**每个角色一段 5-20 秒的参考音频
|
||||
- **内容**:完整的中文句子(需同时记录对应文字)
|
||||
- **质量**:干声为主,避免底噪、混响、BGM
|
||||
|
||||
存放路径:`audio/00_raw/tts/prompt_ref/{角色代号}_ref.wav`
|
||||
存放路径:`voice/{角色代号}/`(与 `林夏.md` §7.3 保持一致)
|
||||
|
||||
```bash
|
||||
# 如果参考音频不是 wav 或采样率不对,用 FFmpeg 转换
|
||||
ffmpeg -i input.mp3 -ar 16000 -ac 1 audio/00_raw/tts/prompt_ref/mom_ref.wav
|
||||
ffmpeg -i input.mp3 -ar 16000 -ac 1 voice/mom/ref.wav
|
||||
```
|
||||
|
||||
### 2.3 创建参考音频记录表
|
||||
|
||||
在 `audio/00_raw/tts/prompt_ref/` 下创建 `ref_manifest.txt`,记录每条参考音频对应的文字:
|
||||
在 `voice/` 下创建 `ref_manifest.txt`,记录每条参考音频对应的文字:
|
||||
|
||||
```
|
||||
mom_ref.wav | 今天天气不错,妈妈给你做了红烧排骨,等你回来吃饭。
|
||||
azhe_ref.wav | 好的,我知道了,那件事明天再说吧。
|
||||
xiaomei_ref.wav | 哎你猜怎么着,今天路上遇到一个超级搞笑的事!
|
||||
zhounan_ref.wav | 嗯,其实我也不太确定,就是觉得应该跟你说一声。
|
||||
hr_ref.wav | 好的,那我们下周三前把流程走完,有什么问题随时联系我。
|
||||
anan_ref.wav | 天呐天呐你快来!这边超级好玩的!
|
||||
dorm_a_ref.wav | 嘿你们看看我,今天升职了!请大家吃饭!
|
||||
dorm_b_ref.wav | 恭喜恭喜啊,太厉害了,我就知道你行的。
|
||||
dorm_c_ref.wav | 嗯,不错,对了夏夏怎么不说话啊。
|
||||
delivery_ref.wav | 你好你的外卖到了,放门口了啊,麻辣烫注意别洒了。
|
||||
mom/ref.wav | 今天天气不错,妈妈给你做了红烧排骨,等你回来吃饭。
|
||||
azhe/ref.wav | 好的,我知道了,那件事明天再说吧。
|
||||
xiaomei/ref.wav | 哎你猜怎么着,今天路上遇到一个超级搞笑的事!
|
||||
zhounan/ref.wav | 嗯,其实我也不太确定,就是觉得应该跟你说一声。
|
||||
hr/ref.wav | 好的,那我们下周三前把流程走完,有什么问题随时联系我。
|
||||
anan/ref.wav | 天呐天呐你快来!这边超级好玩的!
|
||||
dorm_a/ref.wav | 嘿你们看看我,今天升职了!请大家吃饭!
|
||||
dorm_b/ref.wav | 恭喜恭喜啊,太厉害了,我就知道你行的。
|
||||
dorm_c/ref.wav | 嗯,不错,对了夏夏怎么不说话啊。
|
||||
delivery/ref.wav | 你好你的外卖到了,放门口了啊,麻辣烫注意别洒了。
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. TTS 生产流程
|
||||
|
||||
### 3.1 用 WebUI 逐条生产(推荐新手)
|
||||
### 3.1 VoxCPM2 声音克隆流程
|
||||
|
||||
1. 浏览器打开 `http://localhost:8000`
|
||||
2. 选择模式:**3s极速复刻**
|
||||
3. 上传对应角色的参考音频
|
||||
4. 在"prompt文本"中输入参考音频对应的文字
|
||||
5. 在"合成文本"中输入要合成的台词
|
||||
6. 调整速度(对应 SOP §4.2 各角色 Speed 值)
|
||||
7. 点击"生成音频"
|
||||
8. 试听满意后,右键保存音频
|
||||
**前置**:确认 VoxCPM2 服务已启动(§1.2)。
|
||||
|
||||
### 3.2 用 Python 脚本批量生产(推荐熟练后)
|
||||
**单条合成步骤**:
|
||||
1. 将角色参考音频注册为 voice_id:`POST /v1/voices`(wav_base64)
|
||||
2. 调用合成接口:`POST /v1/speech`(text + voice_id)
|
||||
3. 获得 48kHz 16-bit PCM WAV
|
||||
4. 用 FFmpeg atempo 调速(按 `林夏.md` §7.3 各角色语速配置)
|
||||
5. 保存到 `audio/00_raw/tts/`
|
||||
|
||||
创建批量生产脚本 `audio/batch_tts.py`:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
《林夏》TTS 批量生产脚本
|
||||
用法: conda activate cosyvoice && python audio/batch_tts.py
|
||||
"""
|
||||
import os, sys, json, torch, torchaudio
|
||||
|
||||
# 设置路径
|
||||
COSYVOICE_DIR = "/home/xsl/tools/CosyVoice"
|
||||
PROJECT_DIR = "/home/xsl/blind"
|
||||
sys.path.insert(0, COSYVOICE_DIR)
|
||||
sys.path.insert(0, f"{COSYVOICE_DIR}/third_party/Matcha-TTS")
|
||||
|
||||
from cosyvoice.cli.cosyvoice import CosyVoice2
|
||||
from cosyvoice.utils.file_utils import load_wav
|
||||
|
||||
# 加载模型
|
||||
print("正在加载 CosyVoice2 模型...")
|
||||
model = CosyVoice2(f"{COSYVOICE_DIR}/pretrained_models/CosyVoice2-0.5B")
|
||||
print(f"模型加载完成,采样率: {model.sample_rate}")
|
||||
|
||||
# ============================================================
|
||||
# 角色配置 — 按 SOP §4.2 配置卡填写
|
||||
# speed: 对应 SOP 中的 Speed 值
|
||||
# ref_wav: 参考音频路径
|
||||
# ref_text: 参考音频对应文字
|
||||
# ============================================================
|
||||
ROLES = {
|
||||
"mom": {
|
||||
"speed": 0.92,
|
||||
"ref_wav": f"{PROJECT_DIR}/audio/00_raw/tts/prompt_ref/mom_ref.wav",
|
||||
"ref_text": "今天天气不错,妈妈给你做了红烧排骨,等你回来吃饭。",
|
||||
},
|
||||
"azhe": {
|
||||
"speed": 1.05,
|
||||
"ref_wav": f"{PROJECT_DIR}/audio/00_raw/tts/prompt_ref/azhe_ref.wav",
|
||||
"ref_text": "好的,我知道了,那件事明天再说吧。",
|
||||
},
|
||||
"xiaomei": {
|
||||
"speed": 1.10,
|
||||
"ref_wav": f"{PROJECT_DIR}/audio/00_raw/tts/prompt_ref/xiaomei_ref.wav",
|
||||
"ref_text": "哎你猜怎么着,今天路上遇到一个超级搞笑的事!",
|
||||
},
|
||||
"zhounan": {
|
||||
"speed": 0.95,
|
||||
"ref_wav": f"{PROJECT_DIR}/audio/00_raw/tts/prompt_ref/zhounan_ref.wav",
|
||||
"ref_text": "嗯,其实我也不太确定,就是觉得应该跟你说一声。",
|
||||
},
|
||||
"hr": {
|
||||
"speed": 1.00,
|
||||
"ref_wav": f"{PROJECT_DIR}/audio/00_raw/tts/prompt_ref/hr_ref.wav",
|
||||
"ref_text": "好的,那我们下周三前把流程走完,有什么问题随时联系我。",
|
||||
},
|
||||
"anan": {
|
||||
"speed": 1.15,
|
||||
"ref_wav": f"{PROJECT_DIR}/audio/00_raw/tts/prompt_ref/anan_ref.wav",
|
||||
"ref_text": "天呐天呐你快来!这边超级好玩的!",
|
||||
},
|
||||
"delivery": {
|
||||
"speed": 1.20,
|
||||
"ref_wav": f"{PROJECT_DIR}/audio/00_raw/tts/prompt_ref/delivery_ref.wav",
|
||||
"ref_text": "你好你的外卖到了,放门口了啊,麻辣烫注意别洒了。",
|
||||
},
|
||||
# system 用预训练音色,不走 zero-shot
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 台词表 — 从林夏.md §3 / §5 抄写
|
||||
# 每条格式: (文件名前缀, 角色, 台词, speed_override=None)
|
||||
# ============================================================
|
||||
LINES = [
|
||||
# === 第 01 条 · 21:03 妈妈电话 ===
|
||||
("lv11_2103_mom_call_01", "mom",
|
||||
"今晚煮了你爱吃的排骨,给你拍张照啊。下周五回来一趟,你高中物理老师的儿子,挺好的。"),
|
||||
|
||||
# === 第 02 条 · 21:15 小美三连 ===
|
||||
("lv11_2115_xiaomei_voice_01", "xiaomei", "在吗"),
|
||||
("lv11_2115_xiaomei_voice_02", "xiaomei", "你被甩了我都听说了"),
|
||||
("lv11_2115_xiaomei_voice_03", "xiaomei", "明天晚上喝酒,海底捞旁边那家,不许放鸽子"),
|
||||
|
||||
# === 第 03 条 · 21:20 外卖小哥 ===
|
||||
("lv11_2120_delivery_call_01", "delivery",
|
||||
"你好你的麻辣烫到了,放门口可以吗?"),
|
||||
|
||||
# === 第 04 条 · 21:30 阿哲语音 ===
|
||||
("lv11_2130_azhe_voice_01", "azhe",
|
||||
"嗯……夏夏。我那个AirPods充电盒,好像落你抽屉里了。你方便的时候帮我寄一下吗,工位还要用。地址我等下发你。"),
|
||||
|
||||
# === 第 05 条 · 21:45 HR 王姐 ===
|
||||
("lv11_2145_hr_voice_01", "hr",
|
||||
"夏夏啊,离职流程你下周三之前办完哈,公积金那边记得跟进。辛苦啦,外面有合适的工作我帮你留意。"),
|
||||
|
||||
# === 第 06 条 · 22:00 安安 ===
|
||||
("lv11_2200_anan_voice_01", "anan",
|
||||
"夏夏!我在helens!要不要过来!我请客!"),
|
||||
|
||||
# === 第 10 条 · 23:00 妈妈文字 ===
|
||||
("lv11_2300_mom_text_01", "mom", "睡了吗?"),
|
||||
|
||||
# === 第 11 条 · 23:15 阿哲电话 ===
|
||||
("lv11_2315_azhe_call_01", "azhe",
|
||||
"我能过去拿吗?就5分钟"),
|
||||
|
||||
# === 第 12 条 · 23:30 周南 ===
|
||||
("lv11_2330_zhounan_voice_01", "zhounan",
|
||||
"林夏,是我,周南。你应该不记得我了吧,初三坐你后桌那个"),
|
||||
|
||||
# === 第 14 条 · 00:15 妈妈电话 ===
|
||||
("lv11_0015_mom_call_01", "mom",
|
||||
"夏夏,你不接电话我有点担心。妈妈知道你工作忙,你早点睡。"),
|
||||
|
||||
# ... 更多台词按需添加
|
||||
# 长戏(妈妈 4'17"、小美醉语音、周南 4 段)需分段处理,见 §3.3
|
||||
]
|
||||
|
||||
|
||||
def synthesize_line(filename, role, text, speed_override=None):
|
||||
"""合成单条台词"""
|
||||
cfg = ROLES[role]
|
||||
speed = speed_override or cfg["speed"]
|
||||
ref_wav = cfg["ref_wav"]
|
||||
ref_text = cfg["ref_text"]
|
||||
|
||||
if not os.path.exists(ref_wav):
|
||||
print(f" [跳过] 参考音频不存在: {ref_wav}")
|
||||
return
|
||||
|
||||
# 加载参考音频
|
||||
prompt_speech = load_wav(ref_wav, 16000)
|
||||
# 裁剪到合理长度
|
||||
if prompt_speech.shape[1] > 16000 * 30:
|
||||
prompt_speech = prompt_speech[:, :16000 * 30]
|
||||
|
||||
output_path = f"{PROJECT_DIR}/audio/00_raw/tts/{filename}_v1.wav"
|
||||
print(f" 合成中: {filename} [{role}] speed={speed}")
|
||||
print(f" 台词: {text[:50]}...")
|
||||
|
||||
speeches = []
|
||||
for chunk in model.inference_zero_shot(
|
||||
tts_text=text,
|
||||
prompt_text=ref_text,
|
||||
prompt_speech_16k=prompt_speech,
|
||||
stream=False,
|
||||
speed=speed,
|
||||
):
|
||||
speeches.append(chunk["tts_speech"])
|
||||
|
||||
if speeches:
|
||||
full_speech = torch.concat(speeches, dim=1)
|
||||
torchaudio.save(output_path, full_speech, model.sample_rate)
|
||||
duration = full_speech.shape[1] / model.sample_rate
|
||||
print(f" 已保存: {output_path} ({duration:.1f}s)")
|
||||
else:
|
||||
print(f" [失败] 未生成音频: {filename}")
|
||||
|
||||
|
||||
def main():
|
||||
print(f"\n{'='*60}")
|
||||
print(f" 《林夏》TTS 批量生产")
|
||||
print(f" 共 {len(LINES)} 条台词")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
for i, line in enumerate(LINES):
|
||||
filename = line[0]
|
||||
role = line[1]
|
||||
text = line[2]
|
||||
speed_override = line[3] if len(line) > 3 else None
|
||||
|
||||
print(f"\n[{i+1}/{len(LINES)}] {filename}")
|
||||
synthesize_line(filename, role, text, speed_override)
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(" 批量合成完成!请到 audio/00_raw/tts/ 检查结果")
|
||||
print(f"{'='*60}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
**角色音色目录**(与 `林夏.md` §7.3 一致):
|
||||
```
|
||||
voice/
|
||||
├── linxia/ # 林夏(speed 1.00)
|
||||
├── mom/ # 妈妈(speed 0.92)
|
||||
├── azhe/ # 阿哲(speed 1.05)
|
||||
├── xiaomei/ # 小美(speed 1.10,醉态 0.95)
|
||||
├── zhounan/ # 周南(speed 0.95)
|
||||
├── hr/ # HR 王姐(speed 1.00)
|
||||
├── anan/ # 安安(speed 1.15)
|
||||
├── dorm_a/ # 室友 A(speed 1.10)
|
||||
├── dorm_b/ # 室友 B(speed 1.00)
|
||||
├── dorm_c/ # 室友 C(speed 0.95)
|
||||
└── delivery/ # 外卖小哥(speed 1.20)
|
||||
```
|
||||
|
||||
### 3.2 用批量脚本生产(主力方式)
|
||||
|
||||
使用项目自带的 VoxCPM2 批量合成脚本:
|
||||
|
||||
```bash
|
||||
# 确保 VoxCPM2 服务已启动
|
||||
bash /home/xsl/AutoVideo/start-voxcpm.sh
|
||||
|
||||
# 批量合成所有台词
|
||||
python audio/batch_tts_voxcpm.py --source voice
|
||||
|
||||
# 只合成特定角色
|
||||
python audio/batch_tts_voxcpm.py --source voice --role linxia
|
||||
|
||||
# 干跑查看任务列表
|
||||
python audio/batch_tts_voxcpm.py --source voice --dry-run
|
||||
```
|
||||
|
||||
脚本读取 `voice/` 目录下的参考音频,按 `林夏.md` §7.3 角色配置自动注册 voice_id 并批量合成。输出到 `audio/00_raw/tts/`。
|
||||
|
||||
### 3.3 长戏分段处理
|
||||
|
||||
@@ -360,11 +191,11 @@ SOP §5.3 规定:**超过 30 秒的台词必须分段录制**。
|
||||
|
||||
### 3.4 系统 TTS
|
||||
|
||||
系统提示音(播报未读消息、念选项等)用 CosyVoice **预训练音色**模式:
|
||||
系统提示音(播报状态、念选项等)用 VoxCPM2 注册一个中性女声参考音频:
|
||||
|
||||
1. WebUI 选"预训练音色"
|
||||
2. 从下拉菜单选一个清晰的中性女声
|
||||
3. 合成所有系统语句
|
||||
1. 准备一段清晰的中性女声参考音频(如新闻播报片段),存入 `voice/system/`
|
||||
2. 通过 `POST /v1/voices` 注册为 system voice_id
|
||||
3. 用 `POST /v1/speech` 合成所有系统语句
|
||||
|
||||
系统语句示例:
|
||||
- "阿哲,发来1条语音。8秒。"
|
||||
@@ -663,13 +494,13 @@ done
|
||||
## 9. 执行顺序总结
|
||||
|
||||
```
|
||||
第 1 步 · 部署环境 (§1)
|
||||
第 1 步 · 启动 VoxCPM2 + 部署环境 (§1)
|
||||
↓ 约 30 分钟
|
||||
第 2 步 · 准备参考音频 (§2) ← 这一步最关键,音色质量取决于此
|
||||
第 2 步 · 准备参考音频到 voice/ (§2) ← 这一步最关键,音色质量取决于此
|
||||
↓ 约 1-3 天(需要找人录音或搜集素材)
|
||||
第 3 步 · 系统 TTS 先行 (§3.4) ← 最简单的先跑通流程
|
||||
第 3 步 · 系统 TTS 先行 (§3.4) ← 最简单的先跑通 VoxCPM2 流程
|
||||
↓ 约 1 小时
|
||||
第 4 步 · 短台词批量生产 (§3.1/3.2)
|
||||
第 4 步 · 短台词批量生产 (§3.2 batch_tts_voxcpm.py)
|
||||
↓ 约 3-4 小时
|
||||
第 5 步 · 长戏分段录制 (§3.3)
|
||||
↓ 约 2-3 小时
|
||||
@@ -692,22 +523,57 @@ done
|
||||
|
||||
## 附录 A · 常见问题
|
||||
|
||||
**Q: CosyVoice 生成的语音有电流声/杂音?**
|
||||
**Q: VoxCPM2 生成的语音有电流声/杂音?**
|
||||
A: 检查参考音频质量。参考音频必须干净无噪,采样率 ≥ 16kHz。
|
||||
|
||||
**Q: 语速不自然?**
|
||||
A: speed 参数范围 0.5-2.0。如果调速后音质下降,改为在合成文本中加标点控制节奏(句号=长停顿,逗号=短停顿)。
|
||||
A: 用 FFmpeg atempo 调速(范围 0.5-2.0)。如果调速后音质下降,改为在合成文本中加标点控制节奏(句号=长停顿,逗号=短停顿)。
|
||||
|
||||
**Q: 怎样让同一个音色听起来"醉了"?**
|
||||
A: CosyVoice 没有情绪控制参数。替代方案:
|
||||
A: TTS 通常没有情绪控制参数。替代方案:
|
||||
1. 在文本中插入省略号、重复字来模拟口齿不清
|
||||
2. 后期用 FFmpeg 轻微变速+加混响:
|
||||
```bash
|
||||
ffmpeg -i drunk.wav -af "atempo=0.95,aecho=0.8:0.7:40:0.3" -y drunk_fx.wav
|
||||
```
|
||||
|
||||
**Q: WebUI 启动报 CUDA 错误?**
|
||||
A: 确认 conda env 正确:`conda activate cosyvoice`。确认 GPU 可用:`nvidia-smi`。
|
||||
**Q: VoxCPM2 服务无法启动?**
|
||||
A: 确认 `bash /home/xsl/AutoVideo/start-voxcpm.sh` 正常。确认 GPU 可用:`nvidia-smi`。
|
||||
|
||||
**Q: 生成很慢?**
|
||||
A: RTX 5090 应该很快(远超实时)。如果慢,检查是否误用了 CPU。在 Python 中加 `print(torch.cuda.is_available())` 确认。
|
||||
A: RTX 5090 应该很快(远超实时)。如果慢,检查是否误用了 CPU。
|
||||
|
||||
---
|
||||
|
||||
## 附录 B · CosyVoice2 备用方案
|
||||
|
||||
> **仅在 VoxCPM2 表现不佳或不可用时使用。** 正常生产流程请走 §1-§3 的 VoxCPM2 主链路。
|
||||
|
||||
### B.1 环境验证
|
||||
|
||||
```bash
|
||||
conda activate cosyvoice
|
||||
cd /home/xsl/tools/CosyVoice
|
||||
python -c "
|
||||
import sys
|
||||
sys.path.append('third_party/Matcha-TTS')
|
||||
from cosyvoice.cli.cosyvoice import CosyVoice2
|
||||
model = CosyVoice2('pretrained_models/CosyVoice2-0.5B')
|
||||
print('CosyVoice2 加载成功,采样率:', model.sample_rate)
|
||||
"
|
||||
```
|
||||
|
||||
### B.2 WebUI 启动
|
||||
|
||||
```bash
|
||||
conda activate cosyvoice
|
||||
cd /home/xsl/tools/CosyVoice
|
||||
python webui.py --port 8001 # 注意:用 8001 避免与 VoxCPM2 的 8000 端口冲突
|
||||
```
|
||||
|
||||
模式选择:**3s极速复刻**(上传参考音频 + 对应文字 → 合成)。
|
||||
|
||||
### B.3 批量脚本
|
||||
|
||||
CosyVoice2 版批量脚本为 `audio/batch_tts.py`(区别于主力脚本 `audio/batch_tts_voxcpm.py`)。
|
||||
用法:`conda activate cosyvoice && python audio/batch_tts.py`
|
||||
|
||||
Reference in New Issue
Block a user