diff --git a/main/manager-api/src/main/resources/db/changelog/202505151450.sql b/main/manager-api/src/main/resources/db/changelog/202505151450.sql new file mode 100644 index 00000000..0cdbcc8d --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202505151450.sql @@ -0,0 +1,18 @@ +-- 修改自定义TTS接口请求定义 +update `ai_model_provider` set `fields` = +'[{"key":"url","label":"服务地址","type":"string"},{"key":"method","label":"请求方式","type":"string"},{"key":"params","label":"请求参数","type":"dict","dict_name":"params"},{"key":"headers","label":"请求头","type":"dict","dict_name":"headers"},{"key":"format","label":"音频格式","type":"string"},{"key":"output_dir","label":"输出目录","type":"string"}]' +where `id` = 'SYSTEM_TTS_custom'; + +-- 修改自定义TTS配置说明 +UPDATE `ai_model_config` SET +`doc_link` = NULL, +`remark` = '自定义TTS配置说明: +1. 支持自定义TTS接口服务 +2. 使用GET/POST方式请求 +3. 需要网络连接 +4. 输出文件保存在tmp/目录 +配置说明: +1. 在params中配置请求参数,使用JSON格式 + 例如:{"text": "{prompt_text}", "voice": "{voice}", "speed": "{speed}"} +2. 在headers中配置请求头 +3. 设置返回音频格式' WHERE `id` = 'TTS_CustomTTS'; \ No newline at end of file diff --git a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml index 22cef133..add92bc5 100755 --- a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml @@ -155,4 +155,11 @@ databaseChangeLog: changes: - sqlFile: encoding: utf8 - path: classpath:db/changelog/202505201744.sql \ No newline at end of file + path: classpath:db/changelog/202505201744.sql + - changeSet: + id: 202505151450 + author: hsoftxl + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202505151450.sql \ No newline at end of file diff --git a/main/xiaozhi-server/core/providers/tts/custom.py b/main/xiaozhi-server/core/providers/tts/custom.py index 5b8669da..a5300a3e 100644 --- a/main/xiaozhi-server/core/providers/tts/custom.py +++ b/main/xiaozhi-server/core/providers/tts/custom.py @@ -1,4 +1,5 @@ import os +import json import uuid import requests from config.logger import setup_logging @@ -12,11 +13,21 @@ class TTSProvider(TTSProviderBase): def __init__(self, config, delete_audio_file): super().__init__(config, delete_audio_file) self.url = config.get("url") + self.method = config.get("method", "GET") self.headers = config.get("headers", {}) - self.params = config.get("params") self.format = config.get("format", "wav") self.output_file = config.get("output_dir", "tmp/") + self.params = config.get("params") + + if isinstance(self.params, str): + try: + self.params = json.loads(self.params) + except json.JSONDecodeError: + raise ValueError("Custom TTS配置参数出错,无法将字符串解析为对象") + elif not isinstance(self.params, dict): + raise TypeError("Custom TTS配置参数出错, 请参考配置说明") + def generate_filename(self): return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}.{self.format}") @@ -27,7 +38,10 @@ class TTSProvider(TTSProviderBase): v = v.replace("{prompt_text}", text) request_params[k] = v - resp = requests.get(self.url, params=request_params, headers=self.headers) + if self.method.upper() == "POST": + resp = requests.post(self.url, json=request_params, headers=self.headers) + else: + resp = requests.get(self.url, params=request_params, headers=self.headers) if resp.status_code == 200: with open(output_file, "wb") as file: file.write(resp.content)