#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 多进程音频录音系统 基于进程隔离的音频处理架构 """ import os import sys import argparse import json import time from typing import Dict, Any def check_dependencies(): """检查系统依赖""" missing_deps = [] try: import pyaudio except ImportError: missing_deps.append("pyaudio") try: import numpy except ImportError: missing_deps.append("numpy") try: import requests except ImportError: missing_deps.append("requests") try: import websockets except ImportError: missing_deps.append("websockets") if missing_deps: print("❌ 缺少以下依赖库:") for dep in missing_deps: print(f" - {dep}") print("\n请运行以下命令安装:") print(f"pip install {' '.join(missing_deps)}") return False return True def check_environment(): """检查运行环境""" print("🔍 检查运行环境...") # 检查Python版本 python_version = sys.version_info if python_version.major < 3 or (python_version.major == 3 and python_version.minor < 7): print(f"❌ Python版本过低: {python_version.major}.{python_version.minor}") print("需要Python 3.7或更高版本") return False print(f"✅ Python版本: {python_version.major}.{python_version.minor}.{python_version.micro}") # 检查操作系统 import platform system = platform.system().lower() print(f"✅ 操作系统: {system}") # 检查音频设备 try: import pyaudio audio = pyaudio.PyAudio() device_count = audio.get_device_count() print(f"✅ 音频设备数量: {device_count}") if device_count == 0: print("❌ 未检测到音频设备") return False audio.terminate() except Exception as e: print(f"❌ 音频设备检查失败: {e}") return False # 检查网络连接 try: import requests response = requests.get("https://www.baidu.com", timeout=5) print("✅ 网络连接正常") except: print("⚠️ 网络连接可能有问题,会影响在线AI功能") # 检查API密钥 api_key = os.environ.get("ARK_API_KEY") if api_key: print("✅ ARK_API_KEY 已设置") else: print("⚠️ ARK_API_KEY 未设置,大语言模型功能将被禁用") print(" 请运行: export ARK_API_KEY='your_api_key_here'") return True def list_characters(): """列出可用角色""" characters_dir = os.path.join(os.path.dirname(__file__), "characters") if not os.path.exists(characters_dir): print("❌ 角色目录不存在") return characters = [] 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 create_sample_config(): """创建示例配置文件""" config = { "system": { "max_queue_size": 1000, "process_timeout": 30, "heartbeat_interval": 1.0, "log_level": "INFO" }, "audio": { "sample_rate": 16000, "channels": 1, "chunk_size": 1024, "format": "paInt16" }, "recording": { "min_duration": 2.0, "max_duration": 30.0, "silence_threshold": 3.0, "pre_record_duration": 2.0 }, "processing": { "enable_asr": True, "enable_llm": True, "enable_tts": True, "character": "libai", "max_tokens": 50 }, "detection": { "zcr_min": 2400, "zcr_max": 12000, "consecutive_silence_count": 30, "max_zcr_history": 30 }, "playback": { "buffer_size": 1000, "show_progress": True, "progress_interval": 100, "chunk_size": 512 } } config_file = "config.json" try: with open(config_file, 'w', encoding='utf-8') as f: json.dump(config, f, indent=2, ensure_ascii=False) print(f"✅ 示例配置文件已创建: {config_file}") except Exception as e: print(f"❌ 创建配置文件失败: {e}") def main(): """主函数""" parser = argparse.ArgumentParser( description='多进程音频录音系统', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" 使用示例: python multiprocess_recorder.py # 使用默认角色 python multiprocess_recorder.py -c zhubajie # 指定角色 python multiprocess_recorder.py -l # 列出角色 python multiprocess_recorder.py --create-config # 创建配置文件 """ ) parser.add_argument('--character', '-c', type=str, default='libai', help='选择角色 (默认: libai)') parser.add_argument('--list-characters', '-l', action='store_true', help='列出所有可用角色') parser.add_argument('--config', type=str, help='配置文件路径') parser.add_argument('--create-config', action='store_true', help='创建示例配置文件') parser.add_argument('--check-env', action='store_true', help='检查运行环境') parser.add_argument('--verbose', '-v', action='store_true', help='详细输出') args = parser.parse_args() # 显示欢迎信息 print("🚀 多进程音频录音系统") print("=" * 60) # 检查依赖 if not check_dependencies(): sys.exit(1) # 创建配置文件 if args.create_config: create_sample_config() return # 检查环境 if args.check_env: check_environment() return # 列出角色 if args.list_characters: list_characters() return # 检查characters目录 characters_dir = os.path.join(os.path.dirname(__file__), "characters") if not os.path.exists(characters_dir): print(f"⚠️ 角色目录不存在: {characters_dir}") print("请确保characters目录存在并包含角色配置文件") # 检查指定角色 character_file = os.path.join(characters_dir, f"{args.character}.json") if not os.path.exists(character_file): print(f"⚠️ 角色文件不存在: {character_file}") print(f"可用角色:") list_characters() return print(f"🎭 当前角色: {args.character}") print("🎯 系统特点:") print(" - 多进程架构:输入输出完全隔离") print(" - 零切换延迟:无需音频设备重置") print(" - 实时响应:并行处理录音和播放") print(" - 智能检测:基于ZCR的语音识别") print(" - 流式TTS:实时音频生成和播放") print(" - 角色扮演:支持多种AI角色") print("=" * 60) # 显示使用说明 print("📖 使用说明:") print(" - 检测到语音自动开始录音") print(" - 持续静音3秒自动结束录音") print(" - 录音完成后自动处理和播放") print(" - 按 Ctrl+C 退出") print("=" * 60) # 加载配置 config = None if args.config: try: with open(args.config, 'r', encoding='utf-8') as f: config = json.load(f) print(f"📋 加载配置文件: {args.config}") except Exception as e: print(f"⚠️ 配置文件加载失败: {e}") print("使用默认配置") try: # 导入控制系统 from control_system import ControlSystem # 创建控制系统 control_system = ControlSystem(config) # 设置角色 control_system.config['processing']['character'] = args.character # 设置日志级别 if args.verbose: control_system.config['system']['log_level'] = "DEBUG" # 启动系统(自动校准和监听) print("🚀 启动系统(包含自动校准和监听)...") control_system.start(auto_calibration=True, auto_monitoring=True) except KeyboardInterrupt: print("\n👋 用户中断") except Exception as e: print(f"❌ 系统启动失败: {e}") if args.verbose: import traceback traceback.print_exc() finally: print("👋 系统退出") if __name__ == "__main__": main()