From 9b57615d94e2290f357936b7a8f87ddd2f921297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E8=8B=B1=E6=9D=B0?= <806895158@qq.com> Date: Fri, 14 Mar 2025 16:19:41 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=20=E6=96=B0=E5=A2=9E=E4=BA=86=E5=85=B3?= =?UTF-8?q?=E4=BA=8Egewe=E5=8F=91=E9=80=81=E8=A7=86=E9=A2=91=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/platform/sources/gewechat/client.py | 17 +++++++ .../sources/gewechat/gewechat_event.py | 44 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/astrbot/core/platform/sources/gewechat/client.py b/astrbot/core/platform/sources/gewechat/client.py index f0e64e698..bce637d7e 100644 --- a/astrbot/core/platform/sources/gewechat/client.py +++ b/astrbot/core/platform/sources/gewechat/client.py @@ -490,6 +490,23 @@ class SimpleGewechatClient: json_blob = await resp.json() logger.debug(f"发送图片结果: {json_blob}") + async def post_video( + self, to_wxid, video_url: str, thumb_url: str, video_duration: int + ): + payload = { + "appId": self.appid, + "toWxid": to_wxid, + "videoUrl": video_url, + "thumbUrl": thumb_url, + "videoDuration": video_duration, + } + async with aiohttp.ClientSession() as session: + async with session.post( + f"{self.base_url}/message/postVideo", headers=self.headers, json=payload + ) as resp: + json_blob = await resp.json() + logger.debug(f"发送视频结果: {json_blob}") + async def post_voice(self, to_wxid, voice_url: str, voice_duration: int): payload = { "appId": self.appid, diff --git a/astrbot/core/platform/sources/gewechat/gewechat_event.py b/astrbot/core/platform/sources/gewechat/gewechat_event.py index 7668663fb..b43c06631 100644 --- a/astrbot/core/platform/sources/gewechat/gewechat_event.py +++ b/astrbot/core/platform/sources/gewechat/gewechat_event.py @@ -2,6 +2,8 @@ import wave import uuid import traceback import os + +from astrbot.core.message.components import Video from astrbot.core.utils.io import save_temp_img, download_image_by_url, download_file from astrbot.core.utils.tencent_record_helper import wav_to_tencent_silk from astrbot.api import logger @@ -90,6 +92,48 @@ class GewechatPlatformEvent(AstrMessageEvent): img_url = f"{client.file_server_url}/{file_id}" logger.debug(f"gewe callback img url: {img_url}") await client.post_image(to_wxid, img_url) + elif isinstance(comp, Video): + from pyffmpeg import FFmpeg + + video_url = comp.file + # 根据 url 下载视频 + video_filename = f"{uuid.uuid4()}.mp4" + video_path = f"data/temp/{video_filename}" + await download_file(video_url, video_path) + + # 获取视频第一帧 + thumb_path = f"data/temp/{uuid.uuid4()}.jpg" + try: + ff = FFmpeg() + command = f'-i "{video_path}" -ss 0 -vframes 1 "{thumb_path}"' + ff.options(command) + thumb_file_id = os.path.basename(thumb_path) + thumb_url = f"{client.file_server_url}/{thumb_file_id}" + except Exception as e: + logger.error(f"获取视频第一帧失败: {e}") + # 获取视频时长 + try: + from pyffmpeg import FFprobe + + # 创建 FFprobe 实例 + ffprobe = FFprobe(video_url) + # 获取时长字符串 + duration_str = ffprobe.duration + # 处理时长字符串 + video_duration = float(duration_str.replace(":", "")) + except Exception as e: + logger.error(f"获取时长失败: {e}") + video_duration = 10 + + file_id = os.path.basename(video_path) + video_url = f"{client.file_server_url}/{file_id}" + await client.post_video(to_wxid, video_url, thumb_url, video_duration) + + # 删除临时视频和缩略图文件 + if os.path.exists(video_path): + os.remove(video_path) + if os.path.exists(thumb_path): + os.remove(thumb_path) elif isinstance(comp, Record): # 默认已经存在 data/temp 中 record_url = comp.file From 02dee2d664bee083da1be7b0e28e8d8fa8b9bb39 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Fri, 21 Mar 2025 16:51:23 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=8E=88=20perf:=20add=20error=20handli?= =?UTF-8?q?ng=20for=20missing=20pyffmpeg=20library=20in=20video=20sending?= =?UTF-8?q?=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/platform/sources/gewechat/gewechat_event.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/astrbot/core/platform/sources/gewechat/gewechat_event.py b/astrbot/core/platform/sources/gewechat/gewechat_event.py index 160b7c8a3..5b74a63eb 100644 --- a/astrbot/core/platform/sources/gewechat/gewechat_event.py +++ b/astrbot/core/platform/sources/gewechat/gewechat_event.py @@ -84,7 +84,15 @@ class GewechatPlatformEvent(AstrMessageEvent): logger.debug(f"gewe callback img url: {img_url}") await client.post_image(to_wxid, img_url) elif isinstance(comp, Video): - from pyffmpeg import FFmpeg + try: + from pyffmpeg import FFmpeg + except (ImportError, ModuleNotFoundError): + logger.error( + "需要安装 pyffmpeg 库才能发送视频: pip install pyffmpeg" + ) + raise ModuleNotFoundError( + "需要安装 pyffmpeg 库才能发送视频: pip install pyffmpeg" + ) video_url = comp.file # 根据 url 下载视频 From 89d51d2afc8ca565d12abdcdcd9c3c5993102e32 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Mon, 24 Mar 2025 11:36:34 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=8E=88=20perf:=20config=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/shared/AstrBotConfig.vue | 500 +++++++++++++----- 1 file changed, 359 insertions(+), 141 deletions(-) diff --git a/dashboard/src/components/shared/AstrBotConfig.vue b/dashboard/src/components/shared/AstrBotConfig.vue index 2796f95da..2e24af80a 100644 --- a/dashboard/src/components/shared/AstrBotConfig.vue +++ b/dashboard/src/components/shared/AstrBotConfig.vue @@ -1,156 +1,374 @@ \ No newline at end of file + + + \ No newline at end of file