feat: 为 FishAudio TTS 添加可选的 reference_id 直接指定功能 (#2513)
* 移除TTS提供商:FishAudio TTS的角色名称查询机制,改为直接使用参考模型ID /// 修改内容 /// - 移除复杂的角色查询逻辑 删除了 get_reference_id_by_character 方法 移除了通过角色名称搜索模型ID的API调用逻辑 - 简化配置字段 将 fishaudio-tts-character 字段替换为 fishaudio-tts-reference-id 设置默认值为可莉的模型ID:626bb6d3f3364c9cbc3aa6a67300a664 - 优化代码结构 直接在初始化时获取reference_id 简化请求生成逻辑,直接使用配置的模型ID /// 修改原因 /// 避免同名冲突:不同模型可能使用相同的角色名称,导致获取错误的模型 提高性能:移除了额外的API查询步骤,减少延迟 增强可靠性:用户直接指定准确的模型ID,避免搜索失败的情况 简化维护:减少了代码复杂度,降低维护成本 /// 新的使用方式 /// 用户需要从 FishAudio 模型的详情页面/URL 中获取具体的模型ID(如 626bb6d3f3364c9cbc3aa6a67300a664),并在配置中直接填入 fishaudio-tts-reference-id 字段。 这个修改使得FishAudio TTS的配置更加直观和可靠,同时提升了系统的整体性能。 * Refactor: 添加FishAudio TTS reference_id格式验证 添加ID格式验证逻辑,防止无效的reference_id调用API失败。 验证32位十六进制格式并提供详细错误提示。 * Feat: 添加FishAudio TTS可选reference_id配置实现向前兼容 新增可选的reference_id字段,优先使用直接ID,未配置时回退到角色名称查询。 保持完全向前兼容,现有配置无需修改。
This commit is contained in:
@@ -971,6 +971,7 @@ CONFIG_METADATA_2 = {
|
||||
"api_key": "",
|
||||
"api_base": "https://api.fish.audio/v1",
|
||||
"fishaudio-tts-character": "可莉",
|
||||
"fishaudio-tts-reference-id": "",
|
||||
"timeout": "20",
|
||||
},
|
||||
"阿里云百炼 TTS(API)": {
|
||||
@@ -1564,6 +1565,11 @@ CONFIG_METADATA_2 = {
|
||||
"type": "string",
|
||||
"hint": "fishaudio TTS 的角色。默认为可莉。更多角色请访问:https://fish.audio/zh-CN/discovery",
|
||||
},
|
||||
"fishaudio-tts-reference-id": {
|
||||
"description": "reference_id",
|
||||
"type": "string",
|
||||
"hint": "fishaudio TTS 的参考模型ID(可选)。如果填入此字段,将直接使用模型ID而不通过角色名称查询。例如:626bb6d3f3364c9cbc3aa6a67300a664。更多模型请访问:https://fish.audio/zh-CN/discovery,进入模型详情界面后可复制模型ID",
|
||||
},
|
||||
"whisper_hint": {
|
||||
"description": "本地部署 Whisper 模型须知",
|
||||
"type": "string",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import uuid
|
||||
import re
|
||||
import ormsgpack
|
||||
from pydantic import BaseModel, conint
|
||||
from httpx import AsyncClient
|
||||
@@ -24,8 +25,8 @@ class ServeTTSRequest(BaseModel):
|
||||
# 参考音频
|
||||
references: list[ServeReferenceAudio] = []
|
||||
# 参考模型 ID
|
||||
# 例如 https://fish.audio/m/7f92f8afb8ec43bf81429cc1c9199cb1/
|
||||
# 其中reference_id为 7f92f8afb8ec43bf81429cc1c9199cb1
|
||||
# 例如 https://fish.audio/m/626bb6d3f3364c9cbc3aa6a67300a664/
|
||||
# 其中reference_id为 626bb6d3f3364c9cbc3aa6a67300a664
|
||||
reference_id: str | None = None
|
||||
# 对中英文文本进行标准化,这可以提高数字的稳定性
|
||||
normalize: bool = True
|
||||
@@ -44,6 +45,7 @@ class ProviderFishAudioTTSAPI(TTSProvider):
|
||||
) -> None:
|
||||
super().__init__(provider_config, provider_settings)
|
||||
self.chosen_api_key: str = provider_config.get("api_key", "")
|
||||
self.reference_id: str = provider_config.get("fishaudio-tts-reference-id", "")
|
||||
self.character: str = provider_config.get("fishaudio-tts-character", "可莉")
|
||||
self.api_base: str = provider_config.get(
|
||||
"api_base", "https://api.fish-audio.cn/v1"
|
||||
@@ -81,11 +83,43 @@ class ProviderFishAudioTTSAPI(TTSProvider):
|
||||
return item["_id"]
|
||||
return None
|
||||
|
||||
def _validate_reference_id(self, reference_id: str) -> bool:
|
||||
"""
|
||||
验证reference_id格式是否有效
|
||||
|
||||
Args:
|
||||
reference_id: 参考模型ID
|
||||
|
||||
Returns:
|
||||
bool: ID是否有效
|
||||
"""
|
||||
if not reference_id or not reference_id.strip():
|
||||
return False
|
||||
|
||||
# FishAudio的reference_id通常是32位十六进制字符串
|
||||
# 例如: 626bb6d3f3364c9cbc3aa6a67300a664
|
||||
pattern = r'^[a-fA-F0-9]{32}$'
|
||||
return bool(re.match(pattern, reference_id.strip()))
|
||||
|
||||
async def _generate_request(self, text: str) -> dict:
|
||||
# 向前兼容逻辑:优先使用reference_id,如果没有则使用角色名称查询
|
||||
if self.reference_id and self.reference_id.strip():
|
||||
# 验证reference_id格式
|
||||
if not self._validate_reference_id(self.reference_id):
|
||||
raise ValueError(
|
||||
f"无效的FishAudio参考模型ID: '{self.reference_id}'. "
|
||||
f"请确保ID是32位十六进制字符串(例如: 626bb6d3f3364c9cbc3aa6a67300a664)。"
|
||||
f"您可以从 https://fish.audio/zh-CN/discovery 获取有效的模型ID。"
|
||||
)
|
||||
reference_id = self.reference_id.strip()
|
||||
else:
|
||||
# 回退到原来的角色名称查询逻辑
|
||||
reference_id = await self._get_reference_id_by_character(self.character)
|
||||
|
||||
return ServeTTSRequest(
|
||||
text=text,
|
||||
format="wav",
|
||||
reference_id=await self._get_reference_id_by_character(self.character),
|
||||
reference_id=reference_id,
|
||||
)
|
||||
|
||||
async def get_audio(self, text: str) -> str:
|
||||
|
||||
Reference in New Issue
Block a user