import logging import tomllib import os import requests from wcferry import WxMsg, Wcf from robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager class BotVideo: def __init__(self, wcf: Wcf, gbm: GroupBotManager): self.LOG = logging.getLogger(__name__) self.wcf = wcf # 假设 wcf 对象在此类中初始化 self.gbm = gbm # 权限功能 with open("group_video/config.toml", "rb") as f: plugin_config = tomllib.load(f) config = plugin_config["Video"] self.enable = config["enable"] self.command = config["command"] self.LOG.info(f"[点视频] 组件初始化完成,指令: {self.command}") def download_stream(self, url, save_path): """ 从指定URL读取视频流并保存到本地 :param url: 视频流的URL :param save_path: 本地保存路径(包含文件名,例如 "video.mp4") """ try: # 发送GET请求,启用流式传输 response = requests.get(url, stream=True) # 检查请求是否成功 response.raise_for_status() # 如果状态码不是200,将抛出异常 # 确保保存路径的目录存在 os.makedirs(os.path.dirname(save_path) or ".", exist_ok=True) # 检查是否是视频流(可选,根据Content-Type判断) content_type = response.headers.get("Content-Type", "").lower() if "video" not in content_type and "application/octet-stream" not in content_type: print(f"警告: 返回的可能不是视频流,Content-Type: {content_type}") print("响应内容预览:", response.text[:100]) # 打印前100字符查看 return # 以二进制写入模式保存流数据 with open(save_path, "wb") as file: for chunk in response.iter_content(chunk_size=1024): # 分块读取,每块1KB if chunk: # 过滤空块 file.write(chunk) print(f"视频已下载到: {save_path}") return os.path.abspath(save_path) except requests.RequestException as e: print(f"请求失败: {e}") except IOError as e: print(f"文件写入失败: {e}") except Exception as e: print(f"发生未知错误: {e}") def get_video(self, message: WxMsg): if not self.enable: return content = str(message.content).strip() command = content.split(" ") if command[0] not in self.command: return # 如果触发了指令,但是没有权限,则返回权限不足 if self.gbm.get_group_permission(message.roomid, Feature.VIDEO) == PermissionStatus.DISABLED: return try: file_abspath = self.download_stream("https://api.guiguiya.com/api/hook/heisis", "down_load_dir/video.mp4") except requests.RequestException as e: self.wcf.send_text(f"-----Bot-----\n❌请求出错:{e}", (message.roomid if message.from_group() else message.sender), message.sender) return if file_abspath.endswith("mp4"): self.wcf.send_file(file_abspath, (message.roomid if message.from_group() else message.sender)) return