肌肉功能,异步下载,解决阻塞问题

This commit is contained in:
liuwei
2025-05-28 09:52:07 +08:00
parent 25e7b444fe
commit c186f3ef49

View File

@@ -2,6 +2,7 @@ import os
import time
from typing import Dict, Any, List, Optional, Tuple
import aiohttp
import cv2
import requests
from loguru import logger
@@ -104,7 +105,7 @@ class VideoManPlugin(MessagePluginInterface):
try:
# 下载视频
file_abspath, first_frame = self._download_video("https://api.guiguiya.com/api/video/fuji?type=json")
file_abspath, first_frame = await self._download_video("https://api.guiguiya.com/api/video/fuji?type=json")
# FIXME 需要换成web容器地址。否则无法获取。
if not file_abspath:
await self.bot.send_text_message((roomid if roomid else sender), f"\n❌视频下载失败,请稍后再试",
@@ -121,11 +122,11 @@ class VideoManPlugin(MessagePluginInterface):
self.LOG.error(f"处理视频请求出错: {e}")
return False, f"处理出错: {e}"
def _download_video(self, api_url):
async def _download_video(self, api_url):
"""
从API获取视频URL并下载到本地
从API异步获取视频URL并下载到本地
:param api_url: API的URL
:return: 下载后的视频文件绝对路径
:return: 下载后的视频文件绝对路径和首帧路径,或 None
"""
# 确保下载目录存在
if not os.path.exists(self.download_dir):
@@ -134,29 +135,30 @@ class VideoManPlugin(MessagePluginInterface):
save_path = os.path.join(self.download_dir, "video.mp4")
try:
# 获取视频URL
response = requests.get(api_url)
if response.status_code != 200:
self.LOG.error(f"API请求失败HTTP状态码: {response.status_code}")
return None
# 使用 aiohttp 异步获取视频URL
async with aiohttp.ClientSession() as session:
async with session.get(api_url, timeout=20) as response:
if response.status != 200:
self.LOG.error(f"API请求失败HTTP状态码: {response.status}")
return None
data = response.json()
video_url = data.get("url")
if not video_url:
self.LOG.error("API响应中没有找到视频URL")
return None
data = await response.json()
video_url = data.get("url")
if not video_url:
self.LOG.error("API响应中没有找到视频URL")
return None
# 下载视频
video_response = requests.get(video_url, stream=True)
if video_response.status_code != 200:
self.LOG.error(f"无法下载视频HTTP状态码: {video_response.status_code}")
return None
# 异步下载视频
async with session.get(video_url, timeout=20) as video_response:
if video_response.status != 200:
self.LOG.error(f"无法下载视频HTTP状态码: {video_response.status}")
return None
# 保存视频
with open(save_path, "wb") as file:
for chunk in video_response.iter_content(chunk_size=1024):
if chunk: # 过滤空块
file.write(chunk)
# 保存视频
with open(save_path, "wb") as file:
async for chunk in video_response.content.iter_chunked(1024):
if chunk: # 过滤空块
file.write(chunk)
abs_path = os.path.abspath(save_path)
self.LOG.info(f"视频已下载至: {abs_path}")
@@ -166,7 +168,7 @@ class VideoManPlugin(MessagePluginInterface):
return abs_path, first_frame
except requests.RequestException as e:
except aiohttp.ClientError as e:
self.LOG.error(f"请求失败: {e}")
except IOError as e:
self.LOG.error(f"文件写入失败: {e}")