169 lines
5.9 KiB
Python
169 lines
5.9 KiB
Python
import os
|
||
import threading
|
||
from colorama import Fore, Style
|
||
|
||
|
||
class Liugin:
|
||
"""音频播放插件"""
|
||
|
||
def __init__(self):
|
||
self.usage = """音频播放工具使用方法:
|
||
audio_player play - 播放音频文件
|
||
例如:
|
||
- audio_player play - 播放Ciallo~(∠・ω- )⌒-.mp3音频文件
|
||
|
||
使用工具的JSON格式示例:
|
||
{"action": "use_tool", "tool": "audio_player", "args": "play"} - 播放音频文件
|
||
|
||
直接命令:
|
||
- /ciallo - 播放音频文件
|
||
"""
|
||
self.cli = None # CLI实例引用
|
||
self.audio_file = None # 音频文件路径将在set_cli中设置
|
||
|
||
def set_cli(self, cli):
|
||
"""设置CLI实例引用"""
|
||
self.cli = cli
|
||
# 获取主程序目录路径,通过CLI实例
|
||
import os
|
||
# 使用CLI实例中的项目目录信息
|
||
self.audio_file = os.path.join(os.path.dirname(cli.chat_history_dir), "Ciallo~(∠・ω- )⌒-.mp3")
|
||
# 注册插件命令
|
||
self.cli.register_liugin_command('ciallo', self.play_command_handler)
|
||
|
||
def get_tool_info(self):
|
||
return {
|
||
"name": "audio_player",
|
||
"description": "音频播放工具,播放指定的音频文件",
|
||
"keywords": ["音频", "播放", "audio", "play", "音乐", "声音"],
|
||
"usage": """audio_player 工具使用说明:
|
||
JSON格式示例:
|
||
{"action": "use_tool", "tool": "audio_player", "args": "play"} - 播放音频文件
|
||
直接命令:/ciallo - 播放音频文件"""
|
||
}
|
||
|
||
def get_mcp_definition(self):
|
||
return {
|
||
"name": "audio_player",
|
||
"description": "音频播放工具",
|
||
"inputSchema": {
|
||
"type": "object",
|
||
"properties": {
|
||
"file": {
|
||
"type": "string",
|
||
"description": "音频文件路径(可选)"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
def convert_mcp_args(self, arguments):
|
||
return arguments.get("file", "")
|
||
|
||
def handle(self, args):
|
||
"""处理音频播放请求"""
|
||
try:
|
||
# 解析参数
|
||
parts = args.strip().split()
|
||
if len(parts) < 1:
|
||
return "错误:请提供操作类型。支持的操作:play"
|
||
|
||
operation = parts[0].lower()
|
||
|
||
if operation == "play":
|
||
return self._play_audio()
|
||
else:
|
||
return f"错误:不支持的操作 '{operation}'。支持的操作:play"
|
||
|
||
except Exception as e:
|
||
return f"音频播放错误: {str(e)}"
|
||
|
||
def play_command_handler(self, args):
|
||
"""处理 /ciallo 命令"""
|
||
# 在新线程中播放音频,避免阻塞主程序
|
||
thread = threading.Thread(target=self._play_audio_internal)
|
||
thread.daemon = True
|
||
thread.start()
|
||
return f"正在播放音频文件: {self.audio_file}"
|
||
|
||
def _play_audio(self):
|
||
"""播放音频文件"""
|
||
try:
|
||
# 检查音频文件是否存在
|
||
if not os.path.exists(self.audio_file):
|
||
return f"错误:音频文件 '{self.audio_file}' 不存在。"
|
||
|
||
# 使用多种方式尝试播放音频
|
||
success = self._try_play_audio()
|
||
|
||
if success:
|
||
return f"音频文件 '{self.audio_file}' 播放成功!"
|
||
else:
|
||
return f"音频播放失败。请确保已安装相应的音频播放库。"
|
||
|
||
except Exception as e:
|
||
return f"播放音频时发生错误: {str(e)}"
|
||
|
||
def _play_audio_internal(self):
|
||
"""在新线程中播放音频"""
|
||
try:
|
||
# 检查音频文件是否存在
|
||
if not os.path.exists(self.audio_file):
|
||
print(f"{Fore.RED}错误:音频文件 '{self.audio_file}' 不存在。{Style.RESET_ALL}")
|
||
return
|
||
|
||
# 使用多种方式尝试播放音频
|
||
self._try_play_audio()
|
||
|
||
except Exception as e:
|
||
print(f"{Fore.RED}播放音频时发生错误: {str(e)}{Style.RESET_ALL}")
|
||
|
||
def _try_play_audio(self):
|
||
"""尝试多种方式播放音频"""
|
||
# 首先尝试使用pygame(如果已安装)
|
||
try:
|
||
import pygame
|
||
pygame.mixer.init()
|
||
pygame.mixer.music.load(self.audio_file)
|
||
pygame.mixer.music.play()
|
||
|
||
# 等待音频播放完成
|
||
while pygame.mixer.music.get_busy():
|
||
pygame.time.Clock().tick(10)
|
||
|
||
pygame.mixer.quit()
|
||
return True
|
||
except ImportError:
|
||
pass # pygame未安装,尝试其他方式
|
||
except Exception:
|
||
pass # 其他pygame相关错误,尝试其他方式
|
||
|
||
# 尝试使用playsound库(如果已安装)
|
||
try:
|
||
from playsound import playsound
|
||
playsound(self.audio_file)
|
||
return True
|
||
except ImportError:
|
||
pass # playsound未安装,尝试其他方式
|
||
except Exception:
|
||
pass # 其他playsound相关错误,尝试其他方式
|
||
|
||
# 尝试使用winsound(仅Windows)
|
||
try:
|
||
import winsound
|
||
# 对于MP3文件,先尝试使用高级API
|
||
import subprocess
|
||
subprocess.run(["start", "", self.audio_file], shell=True)
|
||
return True
|
||
except Exception:
|
||
pass # winsound相关错误,尝试其他方式
|
||
|
||
# 尝试使用os.startfile(仅Windows)
|
||
try:
|
||
os.startfile(self.audio_file) # 这会使用默认程序打开文件
|
||
return True
|
||
except Exception:
|
||
pass # os.startfile相关错误
|
||
|
||
# 如果所有方式都失败,返回False
|
||
return False |