diff --git a/astrbot/core/platform/sources/gewechat/client.py b/astrbot/core/platform/sources/gewechat/client.py index f0e64e69..bce637d7 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 7668663f..b43c0663 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