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

修改vl菜单需要的四步

在Streamlit界面在tts方法的下拉框加一个选项,为什么需要修改这四个位置,它们各自扮演什么角色。

数据流向图

┌─────────────────────────────────────────────────────────────────┐
│                      用户操作流程                                  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
        ┌──────────────────────────────────────────────┐
        │ 1. Streamlit界面                             │
        │    - 显示下拉框选项                           │
        │    - 收集用户输入(API密钥等)                 │
        │    - 调用 update_key() 保存配置               │
        └──────────────────────────────────────────────┘
                              │
                              ▼
        ┌──────────────────────────────────────────────┐
        │ 2. config.yaml                               │
        │    - 持久化存储配置                           │
        │    - 提供默认值                               │
        └──────────────────────────────────────────────┘
                              │
                              ▼
        ┌──────────────────────────────────────────────┐
        │ 3. tts_main.py (调度层)                      │
        │    - 读取 TTS_METHOD 配置                    │
        │    - 根据 TTS_METHOD 路由到具体函数           │
        └──────────────────────────────────────────────┘
                              │
                              ▼
        ┌──────────────────────────────────────────────┐
        │ 4. 新TTS实现文件 (业务层)                     │
        │    - 调用具体TTS API                         │
        │    - 生成音频文件                             │
        └──────────────────────────────────────────────┘

四个位置的职责分工

用代码和架构来解释这四个位置的职责:

1. Streamlit界面层 - core/st_utils/sidebar_setting.py

这是用户看到的界面,负责:

  • 显示下拉框选项
  • 收集用户输入的配置参数
  • 保存配置到配置文件
tts_methods = ["azure_tts", "openai_tts", "fish_tts", "sf_fish_tts", "edge_tts", "gpt_sovits", "custom_tts", "sf_cosyvoice2", "f5tts"]
select_tts = st.selectbox(t("TTS Method"), options=tts_methods, index=tts_methods.index(load_key("tts_method")))
if select_tts != load_key("tts_method"):
    update_key("tts_method", select_tts)
    st.rerun()

为什么需要修改这里?

  • 如果不在下拉列表中添加新选项,用户根本无法选择你的新TTS方法
  • 如果不添加配置界面,用户无法输入API密钥等参数

2. 配置文件层 - config.yaml

这是数据持久化层,负责:

  • 存储所有TTS方法的配置参数
  • 提供默认值
# TTS 选择 [sf_fish_tts, openai_tts, gpt_sovits, azure_tts, fish_tts, edge_tts, custom_tts]
tts_method: 'custom_tts'
# SiliconFlow FishTTS
sf_fish_tts:
  api_key: 'sk-vlohcdhgvtjfydgbmcwwnkselafzigqmqjxlnatmobruzbqu'
  voice: 'anna'

为什么需要修改这里?

  • 程序启动时需要从这里读取配置
  • 用户在界面输入的参数会保存到这里
  • 如果没有配置项,代码会报错或使用空值

3. 业务逻辑实现层 - core/tts_backend/新文件.py

这是核心功能实现,负责:

  • 实现具体的TTS调用逻辑
  • 处理API请求、音频生成等

举个例子,看看现有的TTS实现:

import requests
from core.utils import load_key

def fish_tts(text, save_as):
    """Fish TTS 实现 - 简单的API调用"""
    api_key = load_key("fish_tts.api_key")
    character = load_key("fish_tts.character")
    character_id = load_key("fish_tts.character_id_dict")[character]
    
    url = "https://api.fish.audio/v1/tts"
    headers = {"Authorization": f"Bearer {api_key}"}
    data = {"text": text, "voice": character_id}
    
    response = requests.post(url, json=data, headers=headers)
    with open(save_as, "wb") as f:
        f.write(response.content)

为什么需要修改这里?

  • 这是实际干活的地方,没有它,选择新TTS方法后没有任何效果
  • 需要调用具体的TTS API或模型

4. 调度路由层 - core/tts_backend/tts_main.py

这是路由分发层,负责:

  • 根据配置调用不同的TTS方法
  • 统一的错误处理和重试逻辑
TTS_METHOD = load_key("tts_method")

# ... 重试逻辑 ...

if TTS_METHOD == 'openai_tts':
    openai_tts(text, save_as)
elif TTS_METHOD == 'gpt_sovits':
    gpt_sovits_tts_for_videolingo(text, save_as, number, task_df)
elif TTS_METHOD == 'fish_tts':
    fish_tts(text, save_as)
# ... 更多分支 ...
elif TTS_METHOD == 'f5tts':
    f5_tts_for_videolingo(text, save_as, number, task_df)

为什么需要修改这里?

  • 这是路由器,决定调用哪个TTS函数
  • 如果不在这里添加分支,即使你实现了新TTS方法,程序也找不到它

如果只修改部分位置会发生什么?

只修改1(界面),不修改其他三个:

  • ✅ 下拉框能看到新选项
  • ❌ 选择后程序报错 KeyError: 'my_new_tts.api_key'(配置不存在)
  • ❌ 无法调用TTS功能

只修改1和2(界面+配置),不修改3和4:

  • ✅ 界面显示新选项
  • ✅ 配置可以保存
  • ❌ 选择后运行到调度层时,找不到对应的函数,报错 NameError: name 'my_new_tts' is not defined
  • ❌ 无法生成音频

只修改1、2、4,不修改3(业务实现):

  • ✅ 界面正常
  • ✅ 配置正常
  • ✅ 调度层能找到函数
  • ❌ 但函数不存在或未实现,报错 ModuleNotFoundErrorAttributeError
  • ❌ 无法生成音频

只有四个都修改,才能正常工作:

  • ✅ 界面显示选项
  • ✅ 配置能保存和读取
  • ✅ 调度层能路由到正确函数
  • ✅ 业务逻辑能实际生成音频

类比理解

这就像开一家新餐厅:

  1. 界面层 = 菜单 - 需要在菜单上添加新菜品名称
  2. 配置层 = 食材库 - 需要储备这道菜的食材
  3. 业务层 = 厨师 - 需要厨师会做这道菜
  4. 调度层 = 服务员 - 需要服务员知道这道菜叫哪个厨师做

缺一不可!只有菜单上写了(1),但没有食材(2)、厨师不会做(3)、服务员不知道安排谁(4),这道菜永远上不了桌。

总结

这四个位置各司其职,形成完整的数据流:

界面展示 → 配置存储 → 路由分发 → 功能执行
  (1)        (2)        (4)         (3)

任何一环缺失都会导致功能无法正常工作。这是典型的分层架构设计,每个层都有自己的职责,通过接口连接,确保系统的可扩展性和可维护性。


评论