From a971ae21686736540628861dace7840b183ac41b Mon Sep 17 00:00:00 2001 From: XL Date: Thu, 15 May 2025 10:23:40 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89tts=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=8F=82=E6=95=B0=E8=BD=ACdict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/providers/tts/custom.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/xiaozhi-server/core/providers/tts/custom.py b/main/xiaozhi-server/core/providers/tts/custom.py index 5b8669da..1efd7d7f 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 @@ -13,7 +14,7 @@ class TTSProvider(TTSProviderBase): super().__init__(config, delete_audio_file) self.url = config.get("url") self.headers = config.get("headers", {}) - self.params = config.get("params") + self.params = json.loads(config.get("params")) self.format = config.get("format", "wav") self.output_file = config.get("output_dir", "tmp/") From 1a0a0777a34bcd0970f2631394d3f1e451ef6fda Mon Sep 17 00:00:00 2001 From: XL Date: Thu, 15 May 2025 15:35:45 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89tts=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=8F=82=E6=95=B0=E8=BD=ACdict=20=E6=94=AF=E6=8C=81po?= =?UTF-8?q?st=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/changelog/202505151450.sql | 4 ++++ .../main/resources/db/changelog/db.changelog-master.yaml | 7 +++++++ main/xiaozhi-server/core/providers/tts/custom.py | 6 +++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 main/manager-api/src/main/resources/db/changelog/202505151450.sql 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..16c6a79b --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202505151450.sql @@ -0,0 +1,4 @@ +-- 修改自定义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'; \ 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 2dfd9831..ec9354bb 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 @@ -128,3 +128,10 @@ databaseChangeLog: - sqlFile: encoding: utf8 path: classpath:db/changelog/202505111914.sql + - changeSet: + id: 202505151450 + author: hrz + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202505151450.sql diff --git a/main/xiaozhi-server/core/providers/tts/custom.py b/main/xiaozhi-server/core/providers/tts/custom.py index 1efd7d7f..0b7dd04b 100644 --- a/main/xiaozhi-server/core/providers/tts/custom.py +++ b/main/xiaozhi-server/core/providers/tts/custom.py @@ -13,6 +13,7 @@ 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 = json.loads(config.get("params")) self.format = config.get("format", "wav") @@ -28,7 +29,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) From 073b69f94a2780f4cc1a73c56e6f7934e95ffd6a Mon Sep 17 00:00:00 2001 From: XL Date: Thu, 15 May 2025 10:23:40 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89tts=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=8F=82=E6=95=B0=E8=BD=ACdict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/providers/tts/custom.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/xiaozhi-server/core/providers/tts/custom.py b/main/xiaozhi-server/core/providers/tts/custom.py index 5b8669da..1efd7d7f 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 @@ -13,7 +14,7 @@ class TTSProvider(TTSProviderBase): super().__init__(config, delete_audio_file) self.url = config.get("url") self.headers = config.get("headers", {}) - self.params = config.get("params") + self.params = json.loads(config.get("params")) self.format = config.get("format", "wav") self.output_file = config.get("output_dir", "tmp/") From 6dd66dbae99bc4fd01d0453c0473044f1b89ad1d Mon Sep 17 00:00:00 2001 From: XL Date: Thu, 15 May 2025 15:35:45 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89tts=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=8F=82=E6=95=B0=E8=BD=ACdict=20=E6=94=AF=E6=8C=81po?= =?UTF-8?q?st=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/changelog/202505151450.sql | 4 ++++ .../main/resources/db/changelog/db.changelog-master.yaml | 7 +++++++ main/xiaozhi-server/core/providers/tts/custom.py | 6 +++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 main/manager-api/src/main/resources/db/changelog/202505151450.sql 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..16c6a79b --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202505151450.sql @@ -0,0 +1,4 @@ +-- 修改自定义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'; \ 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 ae81fd14..a350b76a 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 @@ -142,3 +142,10 @@ databaseChangeLog: - sqlFile: encoding: utf8 path: classpath:db/changelog/202505142037.sql + - changeSet: + id: 202505151450 + author: hrz + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202505151450.sql diff --git a/main/xiaozhi-server/core/providers/tts/custom.py b/main/xiaozhi-server/core/providers/tts/custom.py index 1efd7d7f..0b7dd04b 100644 --- a/main/xiaozhi-server/core/providers/tts/custom.py +++ b/main/xiaozhi-server/core/providers/tts/custom.py @@ -13,6 +13,7 @@ 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 = json.loads(config.get("params")) self.format = config.get("format", "wav") @@ -28,7 +29,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) From eadb69bdc0e42fbacba5104d92e97a5694e7e0cd Mon Sep 17 00:00:00 2001 From: XL Date: Thu, 15 May 2025 15:46:41 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/resources/db/changelog/202505151450.sql | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/main/manager-api/src/main/resources/db/changelog/202505151450.sql b/main/manager-api/src/main/resources/db/changelog/202505151450.sql index 16c6a79b..0cdbcc8d 100644 --- a/main/manager-api/src/main/resources/db/changelog/202505151450.sql +++ b/main/manager-api/src/main/resources/db/changelog/202505151450.sql @@ -1,4 +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'; \ No newline at end of file +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 From d0694a0e7012877a9a602b61ab09a3ec85e80c38 Mon Sep 17 00:00:00 2001 From: XL Date: Fri, 16 May 2025 11:56:54 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=85=BC=E5=AE=B9yaml=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=92=8C=E7=AE=A1=E7=90=86=E7=AB=AF=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/core/providers/tts/custom.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/main/xiaozhi-server/core/providers/tts/custom.py b/main/xiaozhi-server/core/providers/tts/custom.py index 0b7dd04b..a5300a3e 100644 --- a/main/xiaozhi-server/core/providers/tts/custom.py +++ b/main/xiaozhi-server/core/providers/tts/custom.py @@ -15,10 +15,19 @@ class TTSProvider(TTSProviderBase): self.url = config.get("url") self.method = config.get("method", "GET") self.headers = config.get("headers", {}) - self.params = json.loads(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}") From 46a15082d6085003ba469774f041105c0a37337e Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Thu, 22 May 2025 10:41:56 +0800 Subject: [PATCH 7/9] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-web/src/components/DeviceItem.vue | 2 +- main/manager-web/src/components/HeaderBar.vue | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/main/manager-web/src/components/DeviceItem.vue b/main/manager-web/src/components/DeviceItem.vue index 0ecbcefa..eeab90a1 100644 --- a/main/manager-web/src/components/DeviceItem.vue +++ b/main/manager-web/src/components/DeviceItem.vue @@ -28,7 +28,7 @@
- + 聊天记录 聊天记录 diff --git a/main/manager-web/src/components/HeaderBar.vue b/main/manager-web/src/components/HeaderBar.vue index bb5baca5..70b64f61 100644 --- a/main/manager-web/src/components/HeaderBar.vue +++ b/main/manager-web/src/components/HeaderBar.vue @@ -35,10 +35,11 @@ OTA管理
+ :class="{ 'active-tab': $route.path === '/dict-management' || $route.path === '/params-management' || $route.path === '/provider-management' || $route.path === '/server-side-management' }" + @visible-change="handleParamDropdownVisibleChange"> + :style="{ filter: $route.path === '/dict-management' || $route.path === '/params-management' || $route.path === '/provider-management' || $route.path === '/server-side-management' ? 'brightness(0) invert(1)' : 'None' }" /> 参数字典 From 1ad8aeeaa711058d7658297a001a759172105943 Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Thu, 22 May 2025 11:22:16 +0800 Subject: [PATCH 8/9] =?UTF-8?q?add=EF=BC=9ACustomTTS=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/config.yaml | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index 05756cd7..44845df8 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -675,17 +675,24 @@ TTS: speed: 1 output_dir: tmp/ CustomTTS: - # 自定义的TTS接口服务,请求参数可自定义 - # 要求接口使用GET方式请求,并返回音频文件 + # 自定义的TTS接口服务,请求参数可自定义,可接入众多TTS服务 + # 以本地部署的KokoroTTS为例 + # 如果只有cpu运行:docker run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu:latest + # 如果只有gpu运行:docker run --gpus all -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-gpu:latest + # 要求接口使用POST方式请求,并返回音频文件 type: custom - url: "http://127.0.0.1:9880/tts" + method: POST + url: "http://127.0.0.1:8880/v1/audio/speech" params: # 自定义请求参数 - # text: "{prompt_text}" # {prompt_text}会被替换为实际的提示词内容 - # speaker: jok老师 - # speed: 1 - # foo: bar - # testabc: 123456 + input: "{prompt_text}" + response_format: "mp3" + download_format: "mp3" + voice: "zf_xiaoxiao" + lang_code: "z" + return_download_link: true + speed: 1 + stream: false headers: # 自定义请求头 # Authorization: Bearer xxxx - format: wav # 接口返回的音频格式 + format: mp3 # 接口返回的音频格式 output_dir: tmp/ \ No newline at end of file From 2ecce6485cad764d7ed10fbcf4bd6230794ed65b Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Thu, 22 May 2025 11:26:00 +0800 Subject: [PATCH 9/9] =?UTF-8?q?update:=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E7=9A=84TTS=E6=8E=A5=E5=8F=A3=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E4=BD=BF=E7=94=A8=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../changelog/{202505151450.sql => 202505151451.sql} | 10 +++++----- .../resources/db/changelog/db.changelog-master.yaml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) rename main/manager-api/src/main/resources/db/changelog/{202505151450.sql => 202505151451.sql} (60%) diff --git a/main/manager-api/src/main/resources/db/changelog/202505151450.sql b/main/manager-api/src/main/resources/db/changelog/202505151451.sql similarity index 60% rename from main/manager-api/src/main/resources/db/changelog/202505151450.sql rename to main/manager-api/src/main/resources/db/changelog/202505151451.sql index 0cdbcc8d..601de457 100644 --- a/main/manager-api/src/main/resources/db/changelog/202505151450.sql +++ b/main/manager-api/src/main/resources/db/changelog/202505151451.sql @@ -7,12 +7,12 @@ where `id` = 'SYSTEM_TTS_custom'; UPDATE `ai_model_config` SET `doc_link` = NULL, `remark` = '自定义TTS配置说明: -1. 支持自定义TTS接口服务 -2. 使用GET/POST方式请求 -3. 需要网络连接 -4. 输出文件保存在tmp/目录 +1. 自定义的TTS接口服务,请求参数可自定义,可接入众多TTS服务 +2. 以本地部署的KokoroTTS为例 +3. 如果只有cpu运行:docker run -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-cpu:latest +4. 如果只有gpu运行:docker run --gpus all -p 8880:8880 ghcr.io/remsky/kokoro-fastapi-gpu:latest 配置说明: 1. 在params中配置请求参数,使用JSON格式 - 例如:{"text": "{prompt_text}", "voice": "{voice}", "speed": "{speed}"} + 例如KokoroTTS:{ "input": "{prompt_text}", "speed": 1, "voice": "zm_yunxi", "stream": true, "download_format": "mp3", "response_format": "mp3", "return_download_link": true } 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 add92bc5..9d3808da 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 @@ -157,9 +157,9 @@ databaseChangeLog: encoding: utf8 path: classpath:db/changelog/202505201744.sql - changeSet: - id: 202505151450 + id: 202505151451 author: hsoftxl changes: - sqlFile: encoding: utf8 - path: classpath:db/changelog/202505151450.sql \ No newline at end of file + path: classpath:db/changelog/202505151451.sql \ No newline at end of file