# -*- coding: utf-8 -*- from json import loads from os.path import join,basename from traceback import format_exc import oss2 import string,random,os import time from common.YmlConstant import minio_yml_path from minio import Minio from loguru import logger from exception.CustomerException import ServiceException from enums.ExceptionEnum import ExceptionType from util.RWUtils import getConfigs import filetype,cv2,io import numpy as np class MinioSdk: __slots__ = ('minioClient', '__request_id', '__config') def __init__(self, *args): base_dir, env, self.__request_id = args self.minioClient = None self.__config = getConfigs(join(base_dir, minio_yml_path % env)) self.get_minioClient() def get_minioClient(self): if self.minioClient is None: self.minioClient = Minio( endpoint=self.__config["endpoint"], access_key=self.__config["access_key"], secret_key=self.__config["secret_key"], secure=self.__config["secure"] ) def get_bucknetName_from_filename(self,localPath): if isinstance(localPath,np.ndarray): return self.__config["image_bucket"],'jpg' ret = filetype.guess(localPath) if 'video' in ret.mime: return self.__config["video_bucket"],ret.mime elif 'image' in ret.mime: return self.__config["image_bucket"],ret.mime else: logger.warning("上传文件到格式不是图片,或者视频, requestId:{}", self.__request_id) return self.__config["image_bucket"],'.oth' def create_bucknet(self,bucketName): if not self.minioClient.bucket_exists(bucketName): self.minioClient.make_bucket(bucketName) def put_object(self, localPath, remotePath): #localPath--本地文件路径,带有后缀---或者是字节流 #remotePath--远程文件的名字,不带文件夹,不带后缀(为了与原OSS保持一致) request_id = self.__request_id logger.info("开始上传文件到oss, requestId:{}", request_id) bucketName,mime = self.get_bucknetName_from_filename(localPath) self.create_bucknet(bucketName) if '/' not in remotePath: remoteUrl=join(request_id,remotePath ) else: remoteUrl = remotePath max_retries = 3 retry_count = 0 while True: try: self.get_minioClient() if isinstance(localPath,np.ndarray): image_bytes = io.BytesIO(localPath) #image_bytes = localPath.tobytes() # 上传图片数据流 ret = self.minioClient.put_object(bucketName, remoteUrl,image_bytes, len(localPath)) else: if 'video' in mime:# newLocalpath = os.path.join( os.path.dirname(localPath), ''.join(random.sample(string.ascii_letters ,32))+'.mp4' ) cmd1 = 'ffmpeg -i %s -vcodec libx264 -acodec copy %s'%(localPath, newLocalpath ) os.system(cmd1 ) cmd2 = 'mv %s %s'%(newLocalpath,localPath ) os.system(cmd2 ) ret = self.minioClient.fput_object(bucketName, remoteUrl,localPath,content_type=mime) #print('-----line72: mime:',mime) #outurl='http://'+self.__config["endpoint"]+'/'+bucketName+'/'+remoteUrl outurl=self.__config["domain"]+'/'+bucketName+'/'+remoteUrl logger.info("上传文件到minio成功! requestId:{},bucketName:{},objectName:{},remoteUrl:{}", request_id,ret.bucket_name,ret.object_name,outurl) return outurl except Exception as e: retry_count += 1 time.sleep(1) self.minioClient = None logger.info("上传文件到minio失败, 重试次数:{}, requestId:{}", retry_count, request_id) if retry_count > max_retries: logger.error("上传文件到oss重试失败:{}, requestId:{}", format_exc(), request_id) raise e if __name__ == "__main__": base_dir, env, request_id = '/home/th/WJ/test/tuoheng_alg','test','1122334455667788' #localPath = '/home/th/WJ/data/XunHe/ai_online.mp4' localPath = '/home/th/WJ/data/XunHe/ai_online_avc1.mp4' #localPath = '/home/th/WJ/DSP2/AIdemo2/images/cityRoad/DJI_0019_142.jpg' remotePath='or.mp4' minioSdk = MinioSdk(base_dir, env, request_id ) ##上传cv2编码后的图像np数组 #image_array = cv2.imread( localPath ) #_, localPath = cv2.imencode('.jpg', image_array) minioSdk.put_object(localPath, remotePath) #http://minio.t-aaron.com:9000/image/1122334455667788/or_.oth #http://minio.t-aaron.com:9000/image/messageId/t2.jpg #messageId/t2.jpg' # print(aa.get_play_info('6928821035b171ee9f3b6632b68f0102'))