import oss2 import time from exception.CustomerException import ServiceException from enums.ExceptionEnum import ExceptionType import json from aliyunsdkcore.client import AcsClient from aliyunsdkvod.request.v20170321 import GetPlayInfoRequest from voduploadsdk.AliyunVodUtils import * from voduploadsdk.AliyunVodUploader import AliyunVodUploader from voduploadsdk.UploadVideoRequest import UploadVideoRequest class AliyunOssSdk(): def __init__(self, content, logger, requestId): self.content = content self.bucket = None self.logger = logger self.requestId = requestId def get_oss_bucket(self): if self.bucket is None: self.logger.info("初始化oss桶, requestId:{}", self.requestId) auth = oss2.Auth(self.content["aliyun"]["access_key"], self.content["aliyun"]["access_secret"]) self.bucket = oss2.Bucket(auth, self.content["aliyun"]["oss"]["endpoint"], self.content["aliyun"]["oss"]["bucket"], connect_timeout=self.content["aliyun"]["oss"]["connect_timeout"]) async def put_object(self, updatePath, fileByte): self.bucket.put_object(updatePath, fileByte) async def upload_file(self, updatePath, fileByte): self.logger.info("开始上传文件到oss, requestId:{}", self.requestId) self.get_oss_bucket() MAX_RETRIES = 3 retry_count = 0 while True: try: await self.put_object(updatePath, fileByte) self.logger.info("上传文件到oss成功! requestId:{}", self.requestId) break except Exception as e: retry_count += 1 time.sleep(1) self.logger.info("上传文件到oss失败, 重试次数:{}, requestId:{}", retry_count, self.requestId) if retry_count > MAX_RETRIES: self.logger.exception("上传文件到oss重试失败:{}, requestId:{}", e, self.requestId) raise e class ThAliyunVodSdk(): def __init__(self, content, logger, requestId): self.content = content self.logger = logger self.requestId = requestId def init_vod_client(self, accessKeyId, accessKeySecret): regionId = self.content["aliyun"]["vod"]["ecsRegionId"] return AcsClient(accessKeyId, accessKeySecret, regionId, auto_retry=True, max_retry_time=3, timeout=5) def get_play_info(self, videoId): self.logger.info("开始获取视频地址,videoId:{}, requestId:{}", videoId, self.requestId) start = time.time() while True: try: clt = self.init_vod_client(self.content["aliyun"]["access_key"], self.content["aliyun"]["access_secret"]) request = GetPlayInfoRequest.GetPlayInfoRequest() request.set_accept_format('JSON') request.set_VideoId(videoId) request.set_AuthTimeout(3600 * 5) response = json.loads(clt.do_action_with_exception(request)) play_url = response["PlayInfoList"]["PlayInfo"][0]["PlayURL"] self.logger.info("获取视频地址成功,视频地址: {}, requestId: {}", play_url, self.requestId) return play_url except Exception as e: self.logger.error("获取视频地址失败,5秒后重试, requestId: {}", self.requestId) time.sleep(5) current_time = time.time() if "HTTP Status: 403" not in str(e): self.logger.exception("获取视频地址失败: {}, requestId: {}", e, self.requestId) raise ServiceException(ExceptionType.GET_VIDEO_URL_EXCEPTION.value[0], ExceptionType.GET_VIDEO_URL_EXCEPTION.value[1]) if "HTTP Status: 403" in str(e) and ("UploadFail" in str(e) or "TranscodeFail" in str(e)): self.logger.exception("获取视频地址失败: {}, requestId: {}", e, self.requestId) raise ServiceException(ExceptionType.GET_VIDEO_URL_EXCEPTION.value[0], ExceptionType.GET_VIDEO_URL_EXCEPTION.value[1]) diff_time = current_time - start if diff_time > 60 * 60 * 2: self.logger.exception("获取视频地址失败超时异常: {},超时时间:{}, requestId: {}", e, diff_time, self.requestId) raise ServiceException(ExceptionType.GET_VIDEO_URL_TIMEOUT_EXCEPTION.value[0], ExceptionType.GET_VIDEO_URL_TIMEOUT_EXCEPTION.value[1]) def upload_local_video(self, filePath, file_title, storageLocation=None): self.logger.info("开始执行vod视频上传, filePath: {}, requestId: {}", filePath, self.requestId) uploader = AliyunVodUploader(self.content["aliyun"]["access_key"], self.content["aliyun"]["access_secret"]) uploadVideoRequest = UploadVideoRequest(filePath, file_title) self.logger.info("视频分类:{}", self.content["aliyun"]["vod"][self.content["dsp"]["active"]]["CateId"]) uploadVideoRequest.setCateId(self.content["aliyun"]["vod"][self.content["dsp"]["active"]]["CateId"]) # 可以设置视频封面,如果是本地或网络图片可使用UploadImageRequest上传图片到视频点播,获取到ImageURL # ImageURL示例:https://example.com/sample-****.jpg # uploadVideoRequest.setCoverURL('') # 标签 # uploadVideoRequest.setTags('tag1,tag2') if storageLocation: uploadVideoRequest.setStorageLocation(storageLocation) MAX_RETRIES = 3 retry_count = 0 while True: try: result = uploader.uploadLocalVideo(uploadVideoRequest) self.logger.info("vod视频上传成功, videoId:{}, requestId:{}", result.get("VideoId"), self.requestId) return result.get("VideoId") except AliyunVodException as e: retry_count += 1 time.sleep(3) self.logger.error("vod视频上传失败,重试次数:{}, requestId:{}", retry_count, self.requestId) if retry_count >= MAX_RETRIES: self.logger.exception("vod视频上传重试失败: {}, requestId:{}", e, self.requestId) raise ServiceException(ExceptionType.VIDEO_UPDATE_EXCEPTION.value[0], ExceptionType.VIDEO_UPDATE_EXCEPTION.value[1]) def get_play_url(args): thAliyunVodSdk = ThAliyunVodSdk(args[2], args[3], args[4]) videoId = thAliyunVodSdk.upload_local_video(args[0], args[1]) if videoId is None or len(videoId) == 0: return None return thAliyunVodSdk.get_play_info(videoId)