From da806e904e984ecd0425782bcf299115762c4c2a Mon Sep 17 00:00:00 2001 From: DBJD-CR <3405689090@qq.com> Date: Thu, 25 Dec 2025 19:17:48 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20FishAudio=20?= =?UTF-8?q?=E6=BA=90=E7=9A=84=E9=85=8D=E7=BD=AE=E5=8A=A0=E8=BD=BD=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=B9=B6=E5=A2=9E=E5=BC=BA=E8=AF=B7=E6=B1=82=E9=B2=81?= =?UTF-8?q?=E6=A3=92=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix `KeyError: 'model'``: 适配新版配置结构。 - Add `timeout` support: 防止长文本生成时超时。 - Improve response handling: 使用更标准的 Header 检查方式。 --- .../provider/sources/fishaudio_tts_api_source.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/astrbot/core/provider/sources/fishaudio_tts_api_source.py b/astrbot/core/provider/sources/fishaudio_tts_api_source.py index 8362ce1b4..4e4f9bd82 100644 --- a/astrbot/core/provider/sources/fishaudio_tts_api_source.py +++ b/astrbot/core/provider/sources/fishaudio_tts_api_source.py @@ -56,10 +56,11 @@ def __init__( "api_base", "https://api.fish-audio.cn/v1", ) + self.timeout: int = int(provider_config.get("timeout", 20)) self.headers = { "Authorization": f"Bearer {self.chosen_api_key}", } - self.set_model(provider_config["model"]) + self.set_model(provider_config.get("model", None)) async def _get_reference_id_by_character(self, character: str) -> str | None: """获取角色的reference_id @@ -135,17 +136,20 @@ async def get_audio(self, text: str) -> str: path = os.path.join(temp_dir, f"fishaudio_tts_api_{uuid.uuid4()}.wav") self.headers["content-type"] = "application/msgpack" request = await self._generate_request(text) - async with AsyncClient(base_url=self.api_base).stream( + async with AsyncClient(base_url=self.api_base, timeout=self.timeout).stream( "POST", "/tts", headers=self.headers, content=ormsgpack.packb(request, option=ormsgpack.OPT_SERIALIZE_PYDANTIC), ) as response: - if response.headers["content-type"] == "audio/wav": + if response.status_code == 200 and response.headers.get( + "content-type", "" + ).startswith("audio/"): with open(path, "wb") as f: async for chunk in response.aiter_bytes(): f.write(chunk) return path - body = await response.aread() - text = body.decode("utf-8", errors="replace") - raise Exception(f"Fish Audio API请求失败: {text}") + error_text = await response.aread() + raise Exception( + f"Fish Audio API请求失败: 状态码 {response.status_code}, 响应内容: {error_text}" + ) From 1044d92498f78afc507fa9a83617adc7e461d2b9 Mon Sep 17 00:00:00 2001 From: DBJD-CR <3405689090@qq.com> Date: Fri, 26 Dec 2025 12:41:38 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E6=9B=B4?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E7=9A=84=E7=B1=BB=E5=9E=8B=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E9=94=99=E8=AF=AF=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- astrbot/core/provider/sources/fishaudio_tts_api_source.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/astrbot/core/provider/sources/fishaudio_tts_api_source.py b/astrbot/core/provider/sources/fishaudio_tts_api_source.py index 4e4f9bd82..e246e00ed 100644 --- a/astrbot/core/provider/sources/fishaudio_tts_api_source.py +++ b/astrbot/core/provider/sources/fishaudio_tts_api_source.py @@ -56,7 +56,10 @@ def __init__( "api_base", "https://api.fish-audio.cn/v1", ) - self.timeout: int = int(provider_config.get("timeout", 20)) + try: + self.timeout: int = int(provider_config.get("timeout", 20)) + except ValueError: + self.timeout = 20 self.headers = { "Authorization": f"Bearer {self.chosen_api_key}", } @@ -149,7 +152,8 @@ async def get_audio(self, text: str) -> str: async for chunk in response.aiter_bytes(): f.write(chunk) return path - error_text = await response.aread() + error_bytes = await response.aread() + error_text = error_bytes.decode("utf-8", errors="replace")[:1024] raise Exception( f"Fish Audio API请求失败: 状态码 {response.status_code}, 响应内容: {error_text}" )