mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-23 07:33:53 +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:
|
||||
FunASR:
|
||||
model_dir: models/SenseVoiceSmall
|
||||
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:
|
||||
SileroVAD:
|
||||
min_silence_duration_ms: 700
|
||||
model_dir: models/snakers4_silero-vad
|
||||
threshold: 0.5
|
||||
delete_audio: true
|
||||
prompt: '你是一个叫大白的台湾女孩,说话温柔,声音好听,习惯温柔体贴表达。
|
||||
model_dir: models/snakers4_silero-vad
|
||||
min_silence_duration_ms: 700 # 如果说话停顿比较长,可以把这个值设置大一些
|
||||
|
||||
请注意要像一个人一样说话请不要回复表情符号、代码、和xml标签。
|
||||
|
||||
当前时间是:{date_time},现在我正在和你进行语音聊天,我们开始吧。
|
||||
|
||||
如果用户希望结束对话请在最后说拜拜或再见。
|
||||
|
||||
'
|
||||
selected_module:
|
||||
ASR: FunASR
|
||||
LLM: GeminiLLM
|
||||
TTS: EdgeTTS
|
||||
VAD: SileroVAD
|
||||
server:
|
||||
auth:
|
||||
enabled: false
|
||||
tokens:
|
||||
- name: your-device-name1
|
||||
token: your-token1
|
||||
- name: your-device-name2
|
||||
token: your-token2
|
||||
http:
|
||||
enabled: true
|
||||
ip: 0.0.0.0
|
||||
port: 8001
|
||||
token: password
|
||||
ip: 0.0.0.0
|
||||
port: 8000
|
||||
xiaozhi:
|
||||
audio_params:
|
||||
channels: 1
|
||||
format: opus
|
||||
frame_duration: 60
|
||||
sample_rate: 16000
|
||||
session_id: bdfb9a40-eb97-4e59-b52c-9b54accd2c98
|
||||
transport: websocket
|
||||
type: hello
|
||||
version: 1
|
||||
LLM:
|
||||
# 当前支持的type为openai、dify、ollama,可自行适配
|
||||
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
|
||||
model_name: qwen-turbo
|
||||
api_key: 你的deepseek api key
|
||||
DeepSeekLLM:
|
||||
# 定义LLM API类型
|
||||
type: openai
|
||||
# 可在这里找到你的api key https://platform.deepseek.com/
|
||||
model_name: deepseek-chat
|
||||
url: https://api.deepseek.com
|
||||
api_key: 你的deepseek api key
|
||||
ChatGLMLLM:
|
||||
# 定义LLM API类型
|
||||
type: openai
|
||||
# glm-4-flash 是免费的,但是还是需要注册填写api_key的
|
||||
# 可在这里找到你的api key https://bigmodel.cn/usercenter/proj-mgmt/apikeys
|
||||
model_name: glm-4-flash
|
||||
url: https://open.bigmodel.cn/api/paas/v4/
|
||||
api_key: 你的chat-glm api key
|
||||
OllamaLLM:
|
||||
# 定义LLM API类型
|
||||
type: ollama
|
||||
model_name: qwen2.5 # 使用的模型名称,需要预先使用ollama pull下载
|
||||
base_url: http://localhost:11434 # Ollama服务地址
|
||||
DifyLLM:
|
||||
# 定义LLM API类型
|
||||
type: dify
|
||||
# 建议使用本地部署的dify接口,国内部分区域访问dify公有云接口可能会受限
|
||||
# 如果使用DifyLLM,配置文件里prompt(提示词)是无效的,需要在dify控制台设置提示词
|
||||
base_url: https://api.dify.cn/v1
|
||||
api_key: 你的DifyLLM api key
|
||||
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 sys
|
||||
import json
|
||||
import logging
|
||||
import openai
|
||||
import requests
|
||||
import importlib
|
||||
from datetime import datetime
|
||||
from core.utils.util import is_segment
|
||||
from core.utils.util import get_string_no_punctuation_or_emoji
|
||||
from core.utils.util import read_config, get_project_dir
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user