diff --git a/__init__.py b/__init__.py index b116d8e..00393fd 100644 --- a/__init__.py +++ b/__init__.py @@ -289,6 +289,103 @@ async def get_hello(request): return web.json_response("hello") + + +# 腾讯云 VOD + +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile +from tencentcloud.common import credential +from tencentcloud.vod.v20180717 import vod_client, models +import requests +from pathlib import Path +import tempfile + +class VodToLocalNode: + + def __init__(self): + self.secret_id = "AKIDsrihIyjZOBsjimt8TsN8yvv1AMh5dB44" + self.secret_key = "CPZcxdk6W39Jd4cGY95wvupoyMd0YFqW" + self.vod_client = self.init_vod_client() + + def init_vod_client(self): + """初始化VOD客户端""" + try: + http_profile = HttpProfile(endpoint="vod.tencentcloudapi.com") + client_profile = ClientProfile(httpProfile=http_profile) + cred = credential.Credential(self.secret_id, self.secret_key) + return vod_client.VodClient(cred, "ap-shanghai", client_profile) + except Exception as e: + raise RuntimeError(f"VOD client initialization failed: {e}") + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "file_id": ("STRING", {"default": ""}), + "sub_app_id": ("INT", {"default": 0}), + } + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("local_path",) + FUNCTION = "execute" + CATEGORY = "video" + + def execute(self, file_id, sub_app_id): + # 调用下载逻辑 + local_path = self.download_vod(file_id, sub_app_id) + return (local_path,) + + def _get_download_url(self, file_id, sub_app_id): + """获取媒体文件下载地址""" + try: + req = models.DescribeMediaInfosRequest() + req.FileIds = [file_id] + req.SubAppId = sub_app_id + + resp = self.vod_client.DescribeMediaInfos(req) + if not resp.MediaInfoSet: + raise ValueError("File not found") + + media_info = resp.MediaInfoSet[0] + if not media_info.BasicInfo.MediaUrl: + raise ValueError("No download URL available") + + return media_info.BasicInfo.MediaUrl + except Exception as e: + raise RuntimeError(f"Tencent API error: {e}") + + def download_vod(self, file_id, sub_app_id): + """ + 需要补充腾讯云VOD SDK调用逻辑 + 返回本地文件路径 + """ + media_url = self._get_download_url(file_id=file_id, sub_app_id=sub_app_id) + # 生成一个临时目录路径名并创建该目录 + output_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "download", f"{file_id}.mp4" ) + return self._download_file(url=media_url, output_dir=output_dir, file_id=file_id, timeout=60 * 10) + + def _download_file(self, url, output_dir, file_id, timeout=30): + """下载文件到本地""" + try: + # 生成安全文件名 + file_extension = os.path.splitext(url)[1] or ".mp4" + filename = f"{file_id}{file_extension}" + save_path = Path(output_dir) / filename + + with requests.get(url, stream=True, timeout=timeout) as response: + response.raise_for_status() + + with open(save_path, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + if chunk: + f.write(chunk) + + return str(save_path.resolve()) + except Exception as e: + raise RuntimeError(f"Download error: {e}") + # A dictionary that contains all nodes you want to export with their names # NOTE: names should be globally unique NODE_CLASS_MAPPINGS = { diff --git a/requirements.txt b/requirements.txt index 9ec11c9..cfb96b9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,9 @@ +--index-url=https://pypi.tuna.tsinghua.edu.cn/simple ffmpy torch torchvision Pillow opencv-python ultralytics -cos-python-sdk-v5 \ No newline at end of file +cos-python-sdk-v5 +tencentcloud-sdk-python \ No newline at end of file