config
This commit is contained in:
parent
97aecf0c30
commit
ebeb4e34df
8
characters/libai.json
Normal file
8
characters/libai.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "李白",
|
||||
"description": "唐朝著名诗人,浪漫主义风格",
|
||||
"system_prompt": "你是唐朝大诗人李白,字太白,号青莲居士。用简短诗词和小朋友对话,每次回答不超过50字。",
|
||||
"voice": "zh_female_wanqudashu_moon_bigtts",
|
||||
"max_tokens": 50,
|
||||
"author": "Claude"
|
||||
}
|
||||
8
characters/zhubajie.json
Normal file
8
characters/zhubajie.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "猪八戒",
|
||||
"description": "西游记中的经典角色,憨厚可爱",
|
||||
"system_prompt": "你是西游记中的猪八戒,性格贪吃懒惰但心地善良。用幽默风趣的口吻和小朋友对话,每次回答不超过50字。",
|
||||
"voice": "zh_male_zhubajie_mars_bigtts",
|
||||
"max_tokens": 50,
|
||||
"author": "Claude"
|
||||
}
|
||||
123
recorder.py
123
recorder.py
@ -17,6 +17,7 @@ import threading
|
||||
import time
|
||||
import uuid
|
||||
import wave
|
||||
import argparse
|
||||
from io import BytesIO
|
||||
from urllib.parse import urlparse
|
||||
|
||||
@ -33,7 +34,7 @@ except ImportError:
|
||||
class EnergyBasedRecorder:
|
||||
"""基于能量检测的录音系统"""
|
||||
|
||||
def __init__(self, energy_threshold=500, silence_threshold=1.5, min_recording_time=2.0, max_recording_time=30.0, enable_asr=True, enable_llm=True, enable_tts=True):
|
||||
def __init__(self, energy_threshold=500, silence_threshold=1.5, min_recording_time=2.0, max_recording_time=30.0, enable_asr=True, enable_llm=True, enable_tts=True, character="libai"):
|
||||
# 音频参数 - 极简优化
|
||||
self.FORMAT = pyaudio.paInt16
|
||||
self.CHANNELS = 1
|
||||
@ -67,6 +68,16 @@ class EnergyBasedRecorder:
|
||||
self.tts_app_key = "aGjiRDfUWi"
|
||||
self.tts_speaker = "zh_female_wanqudashu_moon_bigtts"
|
||||
|
||||
# 角色配置
|
||||
self.current_character = character
|
||||
self.characters_dir = os.path.join(os.path.dirname(__file__), "characters")
|
||||
self.available_characters = self._load_available_characters()
|
||||
self.character_config = self._load_character_config(character)
|
||||
|
||||
# 如果加载了角色配置,更新TTS音色
|
||||
if self.character_config and "voice" in self.character_config:
|
||||
self.tts_speaker = self.character_config["voice"]
|
||||
|
||||
# 检查音频播放能力
|
||||
if self.enable_tts:
|
||||
self.audio_player_available = self._check_audio_player()
|
||||
@ -118,6 +129,33 @@ class EnergyBasedRecorder:
|
||||
|
||||
self._setup_audio()
|
||||
|
||||
def _load_available_characters(self):
|
||||
"""加载可用角色列表"""
|
||||
characters = []
|
||||
if os.path.exists(self.characters_dir):
|
||||
for file in os.listdir(self.characters_dir):
|
||||
if file.endswith('.json'):
|
||||
characters.append(file[:-5]) # 去掉.json后缀
|
||||
return characters
|
||||
|
||||
def _load_character_config(self, character_name):
|
||||
"""加载角色配置"""
|
||||
config_file = os.path.join(self.characters_dir, f"{character_name}.json")
|
||||
if not os.path.exists(config_file):
|
||||
print(f"⚠️ 角色配置文件不存在: {config_file}")
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(config_file, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
|
||||
print(f"✅ 加载角色: {config.get('name', character_name)}")
|
||||
print(f"📝 描述: {config.get('description', '无描述')}")
|
||||
return config
|
||||
except Exception as e:
|
||||
print(f"❌ 加载角色配置失败: {e}")
|
||||
return None
|
||||
|
||||
def _setup_audio(self):
|
||||
"""设置音频设备"""
|
||||
try:
|
||||
@ -972,6 +1010,17 @@ class EnergyBasedRecorder:
|
||||
try:
|
||||
print("🤖 调用大语言模型...")
|
||||
|
||||
# 获取角色配置中的系统提示词
|
||||
if self.character_config and "system_prompt" in self.character_config:
|
||||
system_prompt = self.character_config["system_prompt"]
|
||||
else:
|
||||
system_prompt = "你是一个智能助手,请根据用户的语音输入提供有帮助的回答。保持回答简洁明了。"
|
||||
|
||||
# 获取角色配置中的最大token数
|
||||
max_tokens = 50
|
||||
if self.character_config and "max_tokens" in self.character_config:
|
||||
max_tokens = self.character_config["max_tokens"]
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {self.llm_api_key}"
|
||||
@ -982,14 +1031,14 @@ class EnergyBasedRecorder:
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "你是唐朝大诗人李白,用简短诗词和小朋友对话,每次回答不超过50字。"
|
||||
"content": system_prompt
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": user_message
|
||||
}
|
||||
],
|
||||
"max_tokens": 50
|
||||
"max_tokens": max_tokens
|
||||
}
|
||||
|
||||
response = requests.post(self.llm_api_url, headers=headers, json=data, timeout=30)
|
||||
@ -1131,10 +1180,53 @@ class EnergyBasedRecorder:
|
||||
print(f"❌ TTS转换失败: {e}")
|
||||
return None
|
||||
|
||||
def parse_arguments():
|
||||
"""解析命令行参数"""
|
||||
parser = argparse.ArgumentParser(description='基于能量检测的极简录音系统')
|
||||
parser.add_argument('--character', '-c', type=str, default='libai',
|
||||
help='选择角色 (默认: libai)')
|
||||
parser.add_argument('--list-characters', '-l', action='store_true',
|
||||
help='列出所有可用角色')
|
||||
return parser.parse_args()
|
||||
|
||||
def list_characters(characters_dir):
|
||||
"""列出所有可用角色"""
|
||||
characters = []
|
||||
if os.path.exists(characters_dir):
|
||||
for file in os.listdir(characters_dir):
|
||||
if file.endswith('.json'):
|
||||
character_name = file[:-5]
|
||||
config_file = os.path.join(characters_dir, file)
|
||||
try:
|
||||
with open(config_file, 'r', encoding='utf-8') as f:
|
||||
config = json.load(f)
|
||||
name = config.get('name', character_name)
|
||||
desc = config.get('description', '无描述')
|
||||
characters.append(f"{character_name}: {name} - {desc}")
|
||||
except:
|
||||
characters.append(f"{character_name}: 配置文件读取失败")
|
||||
|
||||
if characters:
|
||||
print("🎭 可用角色列表:")
|
||||
for char in characters:
|
||||
print(f" - {char}")
|
||||
else:
|
||||
print("❌ 未找到任何角色配置文件")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
args = parse_arguments()
|
||||
|
||||
characters_dir = os.path.join(os.path.dirname(__file__), "characters")
|
||||
|
||||
# 如果要求列出角色,显示后退出
|
||||
if args.list_characters:
|
||||
list_characters(characters_dir)
|
||||
return
|
||||
|
||||
print("🚀 基于能量检测的极简录音系统")
|
||||
print("🤖 集成语音识别功能")
|
||||
print(f"🎭 当前角色: {args.character}")
|
||||
print("=" * 50)
|
||||
|
||||
# 创建录音系统
|
||||
@ -1145,7 +1237,8 @@ def main():
|
||||
max_recording_time=30.0, # 最大录音时间
|
||||
enable_asr=True, # 启用语音识别功能
|
||||
enable_llm=True, # 启用大语言模型功能
|
||||
enable_tts=True # 启用文本转语音功能
|
||||
enable_tts=True, # 启用文本转语音功能
|
||||
character=args.character # 指定角色
|
||||
)
|
||||
|
||||
print("✅ 系统初始化成功")
|
||||
@ -1158,6 +1251,8 @@ def main():
|
||||
print(" - 录音完成后自动语音识别")
|
||||
print(" - 语音识别后自动调用AI助手")
|
||||
print(" - AI回复后自动转换为语音")
|
||||
print(" - 多角色支持 (李白、猪八戒等)")
|
||||
print(" - 每个角色独特音色和性格")
|
||||
print(" - 预录音功能(包含声音开始前2秒)")
|
||||
print(" - 环形缓冲区防止丢失开头音频")
|
||||
print(" - 自动调整能量阈值")
|
||||
@ -1171,6 +1266,26 @@ def main():
|
||||
print(" export ARK_API_KEY='your_api_key_here'")
|
||||
print("=" * 50)
|
||||
|
||||
# 显示角色信息
|
||||
if recorder.character_config:
|
||||
print(f"🎭 当前角色: {recorder.character_config.get('name', '未知')}")
|
||||
print(f"📝 描述: {recorder.character_config.get('description', '无描述')}")
|
||||
print(f"🎤 音色: {recorder.tts_speaker}")
|
||||
print("=" * 50)
|
||||
|
||||
# 显示使用说明
|
||||
print("📖 使用说明:")
|
||||
print("- 检测到声音自动开始录音")
|
||||
print("- 持续静音3秒自动结束录音")
|
||||
print("- 最少录音2秒,最多30秒")
|
||||
print("- 录音完成后自动播放")
|
||||
print("- 按 Ctrl+C 退出")
|
||||
print("🎭 角色切换:")
|
||||
print("- 使用 --character 或 -c 参数选择角色")
|
||||
print("- 使用 --list-characters 或 -l 查看所有角色")
|
||||
print("- 示例: python recorder.py --character zhubajie")
|
||||
print("=" * 50)
|
||||
|
||||
# 开始运行
|
||||
recorder.run()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user