mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-29 18:23:59 +08:00
Merge branch 'main' into webserver
This commit is contained in:
+130
-84
@@ -1,92 +1,138 @@
|
|||||||
|
# 服务器基础配置(Basic server configuration)
|
||||||
|
server:
|
||||||
|
# 服务器监听地址和端口(Server listening address and port)
|
||||||
|
ip: 0.0.0.0
|
||||||
|
port: 8000
|
||||||
|
# 认证配置
|
||||||
|
auth:
|
||||||
|
# 是否启用认证
|
||||||
|
enabled: false
|
||||||
|
# 设备的token,可以在编译固件的环节,写入你自己定义的token
|
||||||
|
# 固件上的token和以下的token如果能对应,才能连接本服务端
|
||||||
|
tokens:
|
||||||
|
- token: "your-token1" # 设备1的token
|
||||||
|
name: "your-device-name1" # 设备1标识
|
||||||
|
- token: "your-token2" # 设备2的token
|
||||||
|
name: "your-device-name2" # 设备2标识
|
||||||
|
# 可选:设备白名单,如果设置了白名单,那么白名单的机器无论是什么token都可以连接。
|
||||||
|
#allowed_devices:
|
||||||
|
# - "24:0A:C4:1D:3B:F0" # MAC地址列表
|
||||||
|
http:
|
||||||
|
enabled: false
|
||||||
|
ip: 0.0.0.0
|
||||||
|
port: 8001
|
||||||
|
token: password
|
||||||
|
|
||||||
|
xiaozhi:
|
||||||
|
type: hello
|
||||||
|
version: 1
|
||||||
|
transport: websocket
|
||||||
|
audio_params:
|
||||||
|
format: opus
|
||||||
|
sample_rate: 16000
|
||||||
|
channels: 1
|
||||||
|
frame_duration: 60
|
||||||
|
prompt: |
|
||||||
|
你是一个叫小智/小志的台湾女孩,说话机车,声音好听,习惯简短表达,爱用网络梗。
|
||||||
|
请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。
|
||||||
|
当前时间是:{date_time},现在我正在和你进行语音聊天,我们开始吧。
|
||||||
|
如果用户希望结束对话,请在最后说“拜拜”或“再见”。
|
||||||
|
# 使用完声音文件后删除文件(Delete the sound file when you are done using it)
|
||||||
|
delete_audio: true
|
||||||
|
|
||||||
|
CMD_exit:
|
||||||
|
- "退出"
|
||||||
|
- "关闭"
|
||||||
|
|
||||||
|
# 具体处理时选择的模块(The module selected for specific processing)
|
||||||
|
selected_module:
|
||||||
|
ASR: FunASR
|
||||||
|
VAD: SileroVAD
|
||||||
|
# 将根据配置名称对应的type调用实际的LLM适配器
|
||||||
|
LLM: ChatGLMLLM
|
||||||
|
# TTS将根据配置名称对应的type调用实际的TTS适配器
|
||||||
|
TTS: EdgeTTS
|
||||||
|
|
||||||
ASR:
|
ASR:
|
||||||
FunASR:
|
FunASR:
|
||||||
model_dir: models/SenseVoiceSmall
|
model_dir: models/SenseVoiceSmall
|
||||||
output_dir: tmp/
|
output_dir: tmp/
|
||||||
CMD_exit:
|
|
||||||
- 退出
|
|
||||||
- 关闭
|
|
||||||
LLM:
|
|
||||||
AliLLM:
|
|
||||||
api_key: 你的deepseek api key
|
|
||||||
base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
||||||
model_name: qwen-turbo
|
|
||||||
type: openai
|
|
||||||
ChatGLMLLM:
|
|
||||||
api_key: 47ab8569b25f4c3d8ea25830a33a64ca.4cF037cViBB1df5o
|
|
||||||
model_name: glm-4-flash
|
|
||||||
type: openai
|
|
||||||
url: https://open.bigmodel.cn/api/paas/v4/
|
|
||||||
DeepSeekLLM:
|
|
||||||
api_key: 你的deepseek api key
|
|
||||||
model_name: deepseek-chat
|
|
||||||
type: openai
|
|
||||||
url: https://api.deepseek.com
|
|
||||||
DifyLLM:
|
|
||||||
api_key: 你的DifyLLM api key
|
|
||||||
base_url: https://api.dify.cn/v1
|
|
||||||
type: dify
|
|
||||||
GeminiLLM:
|
|
||||||
api_key: AIzaSyAvzvu06vT19MO6T6RpHPpuk_Mwhp-yXAw
|
|
||||||
model_name: gemini-1.5-pro
|
|
||||||
type: gemini
|
|
||||||
OllamaLLM:
|
|
||||||
base_url: http://localhost:11434
|
|
||||||
model_name: qwen2.5
|
|
||||||
type: ollama
|
|
||||||
TTS:
|
|
||||||
DoubaoTTS:
|
|
||||||
access_token: 你的火山引擎语音合成服务access_token
|
|
||||||
appid: 你的火山引擎语音合成服务appid
|
|
||||||
cluster: volcano_tts
|
|
||||||
output_file: tmp/
|
|
||||||
type: doubao
|
|
||||||
voice: BV001_streaming
|
|
||||||
EdgeTTS:
|
|
||||||
output_file: tmp/
|
|
||||||
type: edge
|
|
||||||
voice: zh-CN-XiaoxiaoNeural
|
|
||||||
VAD:
|
VAD:
|
||||||
SileroVAD:
|
SileroVAD:
|
||||||
min_silence_duration_ms: 700
|
|
||||||
model_dir: models/snakers4_silero-vad
|
|
||||||
threshold: 0.5
|
threshold: 0.5
|
||||||
delete_audio: true
|
model_dir: models/snakers4_silero-vad
|
||||||
prompt: '你是一个叫大白的台湾女孩,说话温柔,声音好听,习惯温柔体贴表达。
|
min_silence_duration_ms: 700 # 如果说话停顿比较长,可以把这个值设置大一些
|
||||||
|
|
||||||
请注意要像一个人一样说话请不要回复表情符号、代码、和xml标签。
|
LLM:
|
||||||
|
# 当前支持的type为openai、dify、ollama,可自行适配
|
||||||
当前时间是:{date_time},现在我正在和你进行语音聊天,我们开始吧。
|
AliLLM:
|
||||||
|
# 定义LLM API类型
|
||||||
如果用户希望结束对话请在最后说拜拜或再见。
|
type: openai
|
||||||
|
# 可在这里找到你的 api_key https://bailian.console.aliyun.com/?apiKey=1#/api-key
|
||||||
'
|
base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||||
selected_module:
|
model_name: qwen-turbo
|
||||||
ASR: FunASR
|
api_key: 你的deepseek api key
|
||||||
LLM: GeminiLLM
|
DeepSeekLLM:
|
||||||
TTS: EdgeTTS
|
# 定义LLM API类型
|
||||||
VAD: SileroVAD
|
type: openai
|
||||||
server:
|
# 可在这里找到你的api key https://platform.deepseek.com/
|
||||||
auth:
|
model_name: deepseek-chat
|
||||||
enabled: false
|
url: https://api.deepseek.com
|
||||||
tokens:
|
api_key: 你的deepseek api key
|
||||||
- name: your-device-name1
|
ChatGLMLLM:
|
||||||
token: your-token1
|
# 定义LLM API类型
|
||||||
- name: your-device-name2
|
type: openai
|
||||||
token: your-token2
|
# glm-4-flash 是免费的,但是还是需要注册填写api_key的
|
||||||
http:
|
# 可在这里找到你的api key https://bigmodel.cn/usercenter/proj-mgmt/apikeys
|
||||||
enabled: true
|
model_name: glm-4-flash
|
||||||
ip: 0.0.0.0
|
url: https://open.bigmodel.cn/api/paas/v4/
|
||||||
port: 8001
|
api_key: 你的chat-glm api key
|
||||||
token: password
|
OllamaLLM:
|
||||||
ip: 0.0.0.0
|
# 定义LLM API类型
|
||||||
port: 8000
|
type: ollama
|
||||||
xiaozhi:
|
model_name: qwen2.5 # 使用的模型名称,需要预先使用ollama pull下载
|
||||||
audio_params:
|
base_url: http://localhost:11434 # Ollama服务地址
|
||||||
channels: 1
|
DifyLLM:
|
||||||
format: opus
|
# 定义LLM API类型
|
||||||
frame_duration: 60
|
type: dify
|
||||||
sample_rate: 16000
|
# 建议使用本地部署的dify接口,国内部分区域访问dify公有云接口可能会受限
|
||||||
session_id: bdfb9a40-eb97-4e59-b52c-9b54accd2c98
|
# 如果使用DifyLLM,配置文件里prompt(提示词)是无效的,需要在dify控制台设置提示词
|
||||||
transport: websocket
|
base_url: https://api.dify.cn/v1
|
||||||
type: hello
|
api_key: 你的DifyLLM api key
|
||||||
version: 1
|
GeminiLLM:
|
||||||
|
type: gemini
|
||||||
|
# 谷歌Gemini API,需要先在Google Cloud控制台创建API密钥并获取api_key
|
||||||
|
# 若在中国境内使用,请遵守《生成式人工智能服务管理暂行办法》
|
||||||
|
# token申请地址: https://aistudio.google.com/apikey
|
||||||
|
# 若部署地无法访问接口,需要开启科学上网
|
||||||
|
api_key: 你的gemini api key
|
||||||
|
model_name: "gemini-1.5-pro" # gemini-1.5-pro 是免费的
|
||||||
|
TTS:
|
||||||
|
# 当前支持的type为edge、doubao,可自行适配
|
||||||
|
EdgeTTS:
|
||||||
|
# 定义TTS API类型
|
||||||
|
type: edge
|
||||||
|
voice: zh-CN-XiaoxiaoNeural
|
||||||
|
output_file: tmp/
|
||||||
|
DoubaoTTS:
|
||||||
|
# 定义TTS API类型
|
||||||
|
type: doubao
|
||||||
|
# 火山引擎语音合成服务,需要先在火山引擎控制台创建应用并获取appid和access_token
|
||||||
|
# 山引擎语音一定要购买花钱,起步价30元,就有100并发了。如果用免费的只有2个并发,会经常报tts错误
|
||||||
|
# 购买服务后,购买免费的音色后,可能要等半小时左右,才能使用。
|
||||||
|
# 地址:https://console.volcengine.com/speech/service/8
|
||||||
|
voice: BV001_streaming
|
||||||
|
output_file: tmp/
|
||||||
|
appid: 你的火山引擎语音合成服务appid
|
||||||
|
access_token: 你的火山引擎语音合成服务access_token
|
||||||
|
cluster: volcano_tts
|
||||||
|
CosyVoiceSiliconflow:
|
||||||
|
type: siliconflow
|
||||||
|
# 硅基流动TTS
|
||||||
|
# token申请地址 https://cloud.siliconflow.cn/account/ak
|
||||||
|
model: FunAudioLLM/CosyVoice2-0.5B
|
||||||
|
voice: FunAudioLLM/CosyVoice2-0.5B:alex
|
||||||
|
output_file: tmp/
|
||||||
|
access_token: 你的硅基流动API密钥
|
||||||
|
response_format: wav
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import os
|
||||||
|
import uuid
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import requests
|
||||||
|
from datetime import datetime
|
||||||
|
from core.providers.tts.base import TTSProviderBase
|
||||||
|
|
||||||
|
|
||||||
|
class TTSProvider(TTSProviderBase):
|
||||||
|
def __init__(self, config, delete_audio_file):
|
||||||
|
super().__init__(config, delete_audio_file)
|
||||||
|
self.model = config.get("model")
|
||||||
|
self.access_token = config.get("access_token")
|
||||||
|
self.voice = config.get("voice")
|
||||||
|
self.response_format = config.get("response_format")
|
||||||
|
self.sample_rate = config.get("sample_rate")
|
||||||
|
self.speed = config.get("speed")
|
||||||
|
self.gain = config.get("gain")
|
||||||
|
|
||||||
|
self.host = "api.siliconflow.cn"
|
||||||
|
self.api_url = f"https://{self.host}/v1/audio/speech"
|
||||||
|
|
||||||
|
def generate_filename(self, extension=".wav"):
|
||||||
|
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
|
||||||
|
|
||||||
|
async def text_to_speak(self, text, output_file):
|
||||||
|
request_json = {
|
||||||
|
"model": self.model,
|
||||||
|
"input": text,
|
||||||
|
"voice": self.voice,
|
||||||
|
"response_format": self.response_format,
|
||||||
|
}
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {self.access_token}",
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
response = requests.request("POST", self.api_url, json=request_json, headers=headers)
|
||||||
|
data = response.content
|
||||||
|
file_to_save = open(output_file, "wb")
|
||||||
|
file_to_save.write(data)
|
||||||
@@ -1,15 +1,11 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import openai
|
|
||||||
import requests
|
|
||||||
import importlib
|
import importlib
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from core.utils.util import is_segment
|
from core.utils.util import is_segment
|
||||||
from core.utils.util import get_string_no_punctuation_or_emoji
|
from core.utils.util import get_string_no_punctuation_or_emoji
|
||||||
from core.utils.util import read_config, get_project_dir
|
from core.utils.util import read_config, get_project_dir
|
||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user