ChenfengDX
ChenfengDX
发布于 2026-01-26 / 5 阅读
0
0

手把手教程:将自定义 API 从静态参考转为动态参考

概述

本教程教你如何将 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 中,为函数添加 numbertask_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

关键代码说明

  1. 动态路径构建

    ref_audio_path = current_dir / f"output/audio/refers/{number}.wav"
    
    • 使用 f-string 动态拼接路径
    • number 来自调用时传入的片段序号
  2. 三层容错机制

    # 第一层:尝试使用 {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()
    
  3. 路径转换

    DEFAULT_SPK = str(ref_audio_path)
    
    • Path 对象转换为字符串,供 API 调用

步骤 3:更新调用方代码

目标

修改 tts_main.py 中调用 custom_tts 的地方,传递 numbertask_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

解决方法

  1. 检查 output/audio/refers/ 目录是否存在
  2. 运行 extract_refer_audio_main() 提取参考音频
  3. 手动复制参考音频文件到指定目录

问题 3:所有片段声音还是一样

可能原因

  • 实际使用的还是同一个参考音频文件(如都回退到 1.wav

排查方法

  1. 检查日志,确认是否触发了回退机制
  2. 验证 {number}.wav 文件是否真实存在
  3. 查看 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 - 参考实现(类似逻辑)

总结

通过本教程,你完成了以下工作:

  1. ✅ 修改了 custom_tts 函数签名,添加 numbertask_df 参数
  2. ✅ 实现了根据片段序号动态选择参考音频的逻辑
  3. ✅ 添加了三层容错机制,提高鲁棒性
  4. ✅ 更新了调用方代码,传递正确的参数
  5. ✅ 验证了功能正常运行

现在,你的自定义 TTS API 已经支持动态参考音频,每个翻译片段都可以使用对应的参考音频,生成更自然、多变的声音效果!


评论