Skip to content

Commit 660f7ac

Browse files
committedDec 7, 2024
✨ feat: 添加在线API检查功能,更新配置项以支持最大音频长度和流式传输
1 parent 0b2b237 commit 660f7ac

File tree

6 files changed

+53
-17
lines changed

6 files changed

+53
-17
lines changed
 

‎README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ _⭐文本生成语音`tts`插件⭐_
3232

3333
> 或者使用官方在线api -> [fish-audio](https://fish.audio/zh-CN/)即可享受快速云端的语音生成。
3434
35-
> [!WARNING]
36-
> 由于目前国内无法正常访问fish-audio,需要配置[代理](#️-配置)或者使用离线fish-speech生成语音。
37-
3835
## 📜 免责声明
3936

4037
> [!CAUTION]
@@ -91,6 +88,7 @@ git clone https://github.com/Cvandia/nonebot-plugin-fishspeech-tts
9188
| :--------------: | :-----: | :----: | :---------------: | :---------------------------------------------------------: |
9289
| tts_is_online | bool || True | 是否使用云端api |
9390
| tts_chunk_length | literal || "normal" | 请求时音频分片长度,默认为normal,可选:short, normal, long |
91+
| tts_max_new_tokens | int || 800 | 最大音频长度,默认为800(大概6秒) |
9492
| tts_audio_path | str || "./data/参考音频" | 语音素材路径,默认为"./data/参考音频" |
9593
| tts_prefix | str || None | 触发前缀,默认为None |
9694

@@ -107,6 +105,7 @@ ___
107105

108106
| 配置项 | 类型 | 必填项 | 默认值 | 说明 |
109107
| :------------------: | :---: | :----: | :-----: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
108+
| online_api_url | str || "https://api.fish-audio.cn"| 官网api地址 |
110109
| online_authorization | str || "xxxxx" | 官网api鉴权秘钥,详见[链接](https://fish.audio/zh-CN/go-api/api-keys/) |
111110
| online_model_first | bool || True | 如果你想调用官方模型,通过自己的参考音频,定制角色音色,将此项设为`False`。当然,如果你没有准备参考音频,也会调用官网已经有的音色,具体详见[链接](https://fish.audio/zh-CN/) |
112111
| online_api_proxy | str || None | 代理地址,如:http://127.0.0.1:7890 |

‎nonebot_plugin_fishspeech_tts/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require("nonebot_plugin_alconna")
88

99
from . import matcher as _match # noqa
10+
from . import on_start_up # noqa
1011

1112

1213
usage: str = """

‎nonebot_plugin_fishspeech_tts/config.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@ class Config(BaseModel):
88
# 基础配置
99
tts_is_online: bool = True
1010
tts_chunk_length: Literal["normal", "short", "long"] = "normal"
11+
tts_max_new_tokens: int = 800 # 大约6秒
1112
tts_audio_path: str = "./data/参考音频"
1213
tts_prefix: Optional[str] = None
14+
tts_is_stream: bool = False # 是否流式传输
1315

1416
# 区分配置
17+
online_api_url: str = "https://api.fish-audio.cn"
1518
online_authorization: Optional[str] = "xxxxx"
1619
online_model_first: bool = True
1720
# 设置代理地址
1821
online_api_proxy: Optional[str] = None
1922

20-
offline_api_url: str = "http://127.0.0.1:8080"
23+
offline_api_url: str = "http://127.0.0.1:8000"
2124

2225

2326
config = get_plugin_config(Config)

‎nonebot_plugin_fishspeech_tts/fish_audio_api.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
from .request_params import ChunkLength, ServeReferenceAudio, ServeTTSRequest
2626

2727
is_reference_id_first = config.online_model_first
28-
online_api_proxy = config.online_api_proxy
28+
API_URL = config.online_api_url
29+
API_PROXY = config.online_api_proxy
30+
IS_STREAM = config.tts_is_stream
31+
MAX_NEW_TOKENS = config.tts_max_new_tokens
2932

3033

3134
class FishAudioAPI:
@@ -34,9 +37,9 @@ class FishAudioAPI:
3437
"""
3538

3639
def __init__(self):
37-
self.url: str = "https://api.fish.audio/v1/tts"
40+
self.api_url: str = API_URL
3841
self.path_audio: Path = Path(config.tts_audio_path)
39-
self.proxy = online_api_proxy
42+
self.proxy = API_PROXY
4043

4144
# 如果在线授权码为空, 且使用在线api, 则抛出异常
4245
if not config.online_authorization and config.tts_is_online:
@@ -65,7 +68,7 @@ async def _get_reference_id_by_speaker(self, speaker: str) -> str:
6568
exception:
6669
APIException: 获取语音角色列表为空
6770
"""
68-
request_api = "https://api.fish.audio/model"
71+
request_api = self.api_url + "/model"
6972
sort_options = ["score", "task_count", "created_at"]
7073
async with AsyncClient(proxy=self.proxy) as client:
7174
for sort_by in sort_options:
@@ -128,6 +131,8 @@ async def generate_servettsrequest(
128131
opus_bitrate=24,
129132
normalize=True,
130133
chunk_length=chunk_length.value,
134+
max_new_tokens=MAX_NEW_TOKENS,
135+
streaming=IS_STREAM,
131136
references=references,
132137
)
133138

@@ -148,7 +153,7 @@ async def generate_tts(self, request: ServeTTSRequest) -> bytes:
148153
AsyncClient(proxy=self.proxy) as client,
149154
client.stream(
150155
"POST",
151-
self.url,
156+
self.api_url + "/v1/tts",
152157
headers=self.headers,
153158
content=ormsgpack.packb(
154159
request.dict(),
@@ -170,7 +175,7 @@ async def generate_tts(self, request: ServeTTSRequest) -> bytes:
170175
try:
171176
async with AsyncClient(proxy=self.proxy) as client:
172177
response = await client.post(
173-
self.url,
178+
self.api_url + "/v1/tts",
174179
headers=self.headers,
175180
json=request.dict(),
176181
timeout=60,
@@ -191,7 +196,7 @@ async def get_balance(self) -> float:
191196
"""
192197
获取账户余额
193198
"""
194-
balance_url = "https://api.fish.audio/wallet/self/api-credit"
199+
balance_url = self.api_url + "/wallet/self/api-credit"
195200
async with AsyncClient(proxy=self.proxy) as client:
196201
response = await client.get(balance_url, headers=self.headers)
197202
try:
@@ -204,7 +209,7 @@ def get_speaker_list(self) -> list[str]:
204209
获取语音角色列表
205210
"""
206211
return_list = ["请查看官网了解更多: https://fish.audio/zh-CN/"]
207-
if is_reference_id_first:
212+
if not is_reference_id_first:
208213
try:
209214
return_list.extend(get_path_speaker_list(self.path_audio))
210215
except FileHandleException:

‎nonebot_plugin_fishspeech_tts/fish_speech_api.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@
1717
)
1818
from .request_params import ChunkLength, ServeReferenceAudio, ServeTTSRequest
1919

20+
API_URL = config.offline_api_url + "/v1/tts"
21+
PATH_AUDIO = Path(config.tts_audio_path)
22+
MAX_NEW_TOKENS = config.tts_max_new_tokens
23+
IS_STREAM = config.tts_is_stream
24+
2025

2126
class FishSpeechAPI:
2227
def __init__(self):
23-
self.api_url: str = config.offline_api_url + "/v1/tts"
24-
self.path_audio: Path = Path(config.tts_audio_path)
28+
self.api_url: str = API_URL
29+
self.path_audio: Path = PATH_AUDIO
2530
self.headers = {
2631
"content-type": "application/msgpack",
2732
}
@@ -66,11 +71,11 @@ async def generate_servettsrequest(
6671
normalize=True,
6772
opus_bitrate=64,
6873
latency="normal",
69-
max_new_tokens=800,
74+
max_new_tokens=MAX_NEW_TOKENS,
7075
top_p=0.7,
7176
repetition_penalty=1.2,
7277
temperature=0.7,
73-
streaming=False,
78+
streaming=IS_STREAM,
7479
mp3_bitrate=64,
7580
)
7681

@@ -99,7 +104,9 @@ async def generate_tts(self, request: ServeTTSRequest) -> bytes:
99104
RequestError,
100105
) as e:
101106
logger.error(f"获取TTS音频失败: {e}")
102-
raise HTTPException("获取TTS音频超时, 你的接口配置错误或者文本过长") from e
107+
raise HTTPException(
108+
f"{e}\n获取TTS音频超时, 你的接口配置错误或者文本过长"
109+
) from e
103110
except Exception as e:
104111
raise APIException(f"{e}\n获取TTS音频失败, 检查API后端") from e
105112

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from httpx import AsyncClient, HTTPStatusError
2+
from nonebot import get_driver
3+
from nonebot.log import logger
4+
5+
from .config import config
6+
7+
IS_ONLINE = config.tts_is_online
8+
API = config.online_api_url
9+
10+
driver = get_driver()
11+
if IS_ONLINE:
12+
13+
@driver.on_startup
14+
async def check_online_api():
15+
"""检查在线API是否可用"""
16+
async with AsyncClient() as client:
17+
try:
18+
response = await client.get(API)
19+
response.raise_for_status()
20+
except HTTPStatusError as e:
21+
logger.warning(f"在线API不可用: {e}\n请尝试更换API地址或配置代理")

0 commit comments

Comments
 (0)
Failed to load comments.