概述
本教程教你如何将 VideoLingo 项目中的自定义 TTS API 从静态参考音频(所有片段使用同一个参考音频)升级为动态参考音频(每个音频片段使用对应的参考音频)。
为什么需要动态参考音频?
- 静态参考:所有翻译片段使用同一个参考音频(如
1.wav),声音风格单一 - 动态参考:每个翻译片段使用对应的参考音频(如片段1用
1.wav,片段2用2.wav),声音更自然、多变
前提条件
- 已有 VideoLingo 项目
- 项目中有
core/tts_backend/custom_tts.py文件 - 已配置参考音频目录:
output/audio/refers/ - 了解 Python 基础语法
步骤 1:修改 custom_tts 函数签名
目标
在 custom_tts.py 中,为函数添加 number 和 task_df 参数。
操作
文件路径:core/tts_backend/custom_tts.py
1.1 修改函数定义
修改前:
def custom_tts(text, save_path):
修改后:
def custom_tts(text, save_path, number, task_df):
1.2 添加必要的导入
在文件顶部添加 Path 的导入(如果没有的话):
from pathlib import Path
步骤 2:实现动态参考音频选择逻辑
目标
根据片段序号 number 动态选择对应的参考音频文件,并添加容错机制。
操作
文件路径:core/tts_backend/custom_tts.py
在函数定义后,替换原有的硬编码参考音频逻辑:
def custom_tts(text, save_path, number, task_df):
API_URL = "http://127.0.0.1:9999/tts"
# 动态选择参考音频路径
current_dir = Path.cwd()
ref_audio_path = current_dir / f"output/audio/refers/{number}.wav"
# 容错机制:如果对应参考音频不存在,使用第一个作为备选
if not ref_audio_path.exists():
ref_audio_path = current_dir / "output/audio/refers/1.wav"
if not ref_audio_path.exists():
# 自动提取参考音频
from core._9_refer_audio import extract_refer_audio_main
print(f"参考音频文件不存在,尝试提取: {ref_audio_path}")
extract_refer_audio_main()
DEFAULT_SPK = str(ref_audio_path)
payload = {
"text": text,
"spk_audio_path": DEFAULT_SPK,
"output_path": os.path.abspath(save_path),
}
try:
print(f"[Client] 正在发送请求...")
# 核心:proxies={"http": None, "https": None} 确保不走 Clash 代理
response = requests.post(
API_URL,
json=payload,
timeout=600,
proxies={"http": None, "https": None}
)
if response.status_code == 200:
print(f"[Client] 成功生成配音!")
else:
print(f"[Client] API 报错: {response.status_code} - {response.text}")
raise Exception(f"API 错误: {response.text}")
except Exception as e:
print(f"[Client] 调用失败: {e}")
raise e
关键代码说明
-
动态路径构建:
ref_audio_path = current_dir / f"output/audio/refers/{number}.wav"- 使用
f-string动态拼接路径 number来自调用时传入的片段序号
- 使用
-
三层容错机制:
# 第一层:尝试使用 {number}.wav if not ref_audio_path.exists(): # 第二层:回退到 1.wav ref_audio_path = current_dir / "output/audio/refers/1.wav" if not ref_audio_path.exists(): # 第三层:自动提取参考音频 extract_refer_audio_main() -
路径转换:
DEFAULT_SPK = str(ref_audio_path)- 将
Path对象转换为字符串,供 API 调用
- 将
步骤 3:更新调用方代码
目标
修改 tts_main.py 中调用 custom_tts 的地方,传递 number 和 task_df 参数。
操作
文件路径:core/tts_backend/tts_main.py
找到第 61-62 行(大约位置):
修改前:
elif TTS_METHOD == 'custom_tts':
custom_tts(text, save_as)
修改后:
elif TTS_METHOD == 'custom_tts':
custom_tts(text, save_as, number, task_df)
参数说明
| 参数 | 来源 | 用途 |
|---|---|---|
text | 函数参数 | 待合成的文本 |
save_as | 函数参数 | 输出音频文件路径 |
number | 函数参数 | 当前片段序号(从外部传入) |
task_df | 函数参数 | 任务数据框(包含所有片段信息) |
步骤 4:验证功能
4.1 检查参考音频目录
确保 output/audio/refers/ 目录下有对应的参考音频文件:
ls -la output/audio/refers/
预期输出:
1.wav
2.wav
3.wav
...
4.2 运行 TTS 生成
使用 custom_tts 方法运行音频生成任务:
python main.py
或者在 Web 界面中选择 TTS 方法为 custom_tts。
4.3 验证动态选择效果
查看日志输出,确认每个片段使用了正确的参考音频:
[Client] 正在发送请求...
[Client] 成功生成配音!
检查生成的音频文件,确认使用了不同的参考音频。
常见问题排查
问题 1:提示缺少参数
错误信息:
TypeError: custom_tts() missing 2 required positional arguments: 'number' and 'task_df'
解决方法:
检查 tts_main.py 中的调用是否已更新为:
custom_tts(text, save_as, number, task_df)
问题 2:参考音频文件不存在
错误信息:
参考音频文件不存在,尝试提取: /root/VideoLingo/output/audio/refers/1.wav
解决方法:
- 检查
output/audio/refers/目录是否存在 - 运行
extract_refer_audio_main()提取参考音频 - 手动复制参考音频文件到指定目录
问题 3:所有片段声音还是一样
可能原因:
- 实际使用的还是同一个参考音频文件(如都回退到
1.wav)
排查方法:
- 检查日志,确认是否触发了回退机制
- 验证
{number}.wav文件是否真实存在 - 查看 API 请求的
spk_audio_path参数
技术原理
工作流程
1. tts_main 调用 custom_tts(text, save_as, number, task_df)
↓
2. custom_tts 根据 number 构建路径:output/audio/refers/{number}.wav
↓
3. 检查文件是否存在?
├─ 是 → 使用该文件
└─ 否 → 回退到 1.wav → 不存在则自动提取
↓
4. 发送 API 请求(携带参考音频路径)
↓
5. API 返回 200 → 音频生成成功
核心改进点
| 特性 | 静态参考(修改前) | 动态参考(修改后) |
|---|---|---|
| 参考音频选择 | 固定 1.wav | 根据 number 选择 {number}.wav |
| 声音多样性 | 单一 | 多样 |
| 容错性 | 无(文件不存在则失败) | 三层回退机制 |
| 函数参数 | 2 个 | 4 个 |
相关文件
core/tts_backend/custom_tts.py- 自定义 TTS 实现(需修改)core/tts_backend/tts_main.py- TTS 主入口(需修改)core/_9_refer_audio.py- 参考音频提取工具(自动调用)core/tts_backend/sf_cosyvoice2.py- 参考实现(类似逻辑)
总结
通过本教程,你完成了以下工作:
- ✅ 修改了
custom_tts函数签名,添加number和task_df参数 - ✅ 实现了根据片段序号动态选择参考音频的逻辑
- ✅ 添加了三层容错机制,提高鲁棒性
- ✅ 更新了调用方代码,传递正确的参数
- ✅ 验证了功能正常运行
现在,你的自定义 TTS API 已经支持动态参考音频,每个翻译片段都可以使用对应的参考音频,生成更自然、多变的声音效果!