package com.tzld.piaoquan.api.util; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.aliyun.opensearch.sdk.dependencies.org.apache.commons.codec.binary.Base64; import com.aliyun.oss.*; import com.aliyun.oss.common.utils.BinaryUtil; import com.aliyun.oss.model.*; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.http.MethodType; import com.aliyuncs.http.ProtocolType; import com.aliyuncs.mts.model.v20140618.SubmitJobsRequest; import com.aliyuncs.mts.model.v20140618.SubmitJobsResponse; import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobRequest; import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobResponse; import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobResponse.MediaInfoJob.Properties; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest; import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse; import com.stuuudy.commons.external.filestorage.alibaba.OSSFileDO; import com.stuuudy.commons.external.filestorage.enums.*; import com.stuuudy.commons.util.BlankUtil; import com.stuuudy.commons.util.CompressImage; import com.stuuudy.commons.util.MD5.Md5Util; import com.stuuudy.commons.util.exception.CommonsException; import com.stuuudy.commons.util.exception.EnumErrorException; import com.tzld.piaoquan.api.common.enums.EnumUploadFileType; import com.tzld.piaoquan.api.config.AliOssConfig; import com.tzld.piaoquan.api.model.vo.SignatureVO; import com.tzld.piaoquan.api.model.vo.StsTokenVO; import com.tzld.piaoquan.growth.common.utils.DateUtils; import com.tzld.piaoquan.growth.common.utils.RandomUtil; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import javax.imageio.ImageIO; import javax.xml.crypto.dsig.SignatureMethod; import java.awt.image.BufferedImage; import java.io.*; import java.net.URL; import java.net.URLEncoder; import java.security.DigestInputStream; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; /** * (阿里对象存储工具类)
* AliOssFileTool
* 创建人:陈海
* 时间:2016年7月18日-下午12:47:52
* * @version 1.0.0 */ @Component public class AliOssFileTool extends AliOssConfig { private static Logger logger = Logger.getLogger(AliOssFileTool.class); private static final String ENCODE_TYPE = "UTF-8"; private static final String ALGORITHM = "HmacSHA1"; private static final String HTTP_METHOD = "GET"; private static final String SEPARATOR = "&"; private static final String EQUAL = "="; public static String saveInPublicWithPress(InputStream inputStream, EnumPublicBuckets bucket, String key, EnumFileType type, EnumFileSuffix fileSuffix) throws OSSException, ClientException { inputStream = compressImg(inputStream, fileSuffix, type); return saveInPublicNoPress(inputStream, bucket, key, type); } public static String saveInPublicReturnHost(InputStream inputStream, EnumPublicBuckets bucket, String fullKey, EnumFileType type) { String path = saveInPublic(inputStream, bucket, fullKey, type); // 保存路径 return CdnUtil.getCdnUrlHost(type) + path; } public static String saveInPublic(InputStream inputStream, EnumPublicBuckets bucket, String fullKey, EnumFileType type) { String bucketName = getBucket(bucket.getBucketName()); if (EnumFileType.VOICE.equals(type)) { ObjectMetadata om = new ObjectMetadata(); om.setContentType("audio/mpeg"); getOssClient().putObject(bucketName, fullKey, inputStream, om); } else { getOssClient().putObject(bucketName, fullKey, inputStream); } return fullKey; } public static String moveFile(EnumPublicBuckets sourceBucket, String sourceKey, EnumPublicBuckets targetBucket, String targetKey) { getOssClient().copyObject(getBucket(sourceBucket.getBucketName()), sourceKey, getBucket(targetBucket.getBucketName()), targetKey); if (!StringUtils.equals(sourceKey, targetKey)) { getOssClient().deleteObject(getBucket(sourceBucket.getBucketName()), sourceKey); } return targetKey; } public static void deleteFile(EnumPublicBuckets bucket, String key) { getOssClient().deleteObject(getBucket(bucket.getBucketName()), key); } public static String saveInPublicNoPress(InputStream inputStream, EnumPublicBuckets bucket, String key, EnumFileType type) throws OSSException, ClientException { String fullKey = getProjectName() + "/" + type.getLocation() + key; saveInPublic(inputStream, bucket, fullKey, type); return fullKey; } /** * (网络资源上传) 方法名saveURLInPublicNoPress * * @param url 资源地址 * @param key * @param type * @param fileSuffix * @return * @throws OSSException * @throws ClientException * @throws IOException String * @throws @version 1.0 * @author 创建人:何振斌 * @time 创建日期:2018年3月12日 下午7:10:00 */ public static String saveURLInPublicNoPress(String url, String bucketName, String key, EnumFileType type, EnumFileSuffix fileSuffix) throws OSSException, ClientException, IOException { String fullKey = getProjectName() + "/" + type.getLocation() + key; InputStream inputStream = null; if (!BlankUtil.isBlank(url)) { inputStream = new URL(url).openStream(); } if (EnumFileType.VOICE.equals(type)) { ObjectMetadata om = new ObjectMetadata(); om.setContentType("audio/mpeg"); getOssClient().putObject(bucketName, fullKey, inputStream, om); } else { getOssClient().putObject(bucketName, fullKey, inputStream); } return getProjectName() + "/" + type.getLocation() + key; } /** * (根据名称和类型保存文件,返回是否成功)
* 方法名:saveWiteKeyAndType
* 创建人:陈海
* 时间:2016年7月18日-下午1:02:10
* * @param inputStream 文件流 * @param bucket 空间名称 * @param key 文件保存在服务器上的另存名 * @param type 枚举文件类型,声音或图片等 * @return boolean
* @throws IOException * @throws ClientException * @throws OSSException * @throws
* @since 1.0.0 */ public static boolean saveInPrivate(InputStream inputStream, EnumPrivateBuckets bucket, String key, EnumFileType type, EnumFileSuffix suffix) throws OSSException, ClientException, IOException { inputStream = compressImg(inputStream, suffix, type); String bucketName = getBucket(bucket.getBucketName()); String fullKey = getProjectName() + "/" + type.getLocation() + key; getOssClient().putObject(bucketName, fullKey, inputStream); return true; } /** * (获取前缀为prefix的全部文件)
* 方法名:listFileInFolder
* 创建人:陈海
* 时间:2017年1月20日-下午4:59:25
* * @param bucket * @param prefix * @return List
* @throws
* @since 1.0.0 */ public static List listFileInFolder(EnumPublicBuckets bucket, String prefix) { final int maxKeys = 200; String nextMarker = null; ObjectListing objectListing; List sums = new ArrayList(); // 递归列出fun目录下的所有文件 do { ListObjectsRequest listObjectsRequest = new ListObjectsRequest(getBucket(bucket.getBucketName())); listObjectsRequest.setPrefix(prefix); listObjectsRequest.withMarker(nextMarker).withMaxKeys(maxKeys); objectListing = getOssClient().listObjects(listObjectsRequest); List temp = objectListing.getObjectSummaries(); if (temp != null) { sums.addAll(temp); } nextMarker = objectListing.getNextMarker(); } while (objectListing.isTruncated()); return sums; } /** * (判断是否存在文件)
* 方法名:isExist
* 创建人:陈海
* 时间:2016年11月21日-下午3:54:36
* * @param bucket * @param key * @param type * @return boolean
* @throws
* @since 1.0.0 */ public static boolean isExist(EnumPrivateBuckets bucket, String key, EnumFileType type) { String fullKey = getProjectName() + "/" + type.getLocation() + key; return getOssClient().doesObjectExist(getBucket(bucket.getBucketName()), fullKey); } public static final String REGION_CN_HANGZHOU = "cn-hangzhou"; public static final String STS_API_VERSION = "2015-04-01"; public static AssumeRoleResponse getTempUserToken(long durationSeconds, Integer uid) throws com.aliyuncs.exceptions.ClientException { // 只有 RAM用户(子账号)才能调用 AssumeRole 接口 // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求 // 请首先在RAM控制台创建一个RAM用户,并为这个用户创建AccessKeys String accessKeyId = "LTAIQLkVvDFXRO7j"; String accessKeySecret = "aOnxO0xyoa0lDmTxTI1cNmVLNotF15"; // RoleArn 需要在 RAM 控制台上获取 String roleArn = "acs:ram::1894469520484605:role/aliyunosstokengeneratorrole"; String policy = JSONObject.toJSONString(AliOssFileTool.getPolicyDetail()); // RoleSessionName 是临时Token的会话名称,自己指定用于标识你的用户,主要用于审计,或者用于区分Token颁发给谁 // 但是注意RoleSessionName的长度和规则,不要有空格,只能有'-' '_' 字母和数字等字符 // 具体规则请参考API文档中的格式要求 String roleSessionName = "uid_" + uid; // 此处必须为 HTTPS ProtocolType protocolType = ProtocolType.HTTPS; try { final AssumeRoleResponse stsResponse = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy, protocolType, durationSeconds); return stsResponse; /* * Map respMap = new LinkedHashMap(); * respMap.put("status", "200"); respMap.put("AccessKeyId", * stsResponse.getCredentials().getAccessKeyId()); * respMap.put("AccessKeySecret", * stsResponse.getCredentials().getAccessKeySecret()); * respMap.put("SecurityToken", * stsResponse.getCredentials().getSecurityToken()); respMap.put("Expiration", * stsResponse.getCredentials().getExpiration()); */ } catch (ClientException e) { throw e; } } protected static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn, String roleSessionName, String policy, ProtocolType protocolType, long durationSeconds) throws com.aliyuncs.exceptions.ClientException { try { // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求 IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret); DefaultAcsClient client = new DefaultAcsClient(profile); // 创建一个 AssumeRoleRequest 并设置请求参数 final AssumeRoleRequest request = new AssumeRoleRequest(); request.setVersion(STS_API_VERSION); request.setMethod(MethodType.POST); request.setProtocol(protocolType); request.setRoleArn(roleArn); request.setRoleSessionName(roleSessionName); request.setPolicy(policy); request.setDurationSeconds(durationSeconds); // 发起请求,并得到response final AssumeRoleResponse response = client.getAcsResponse(request); return response; } catch (com.aliyuncs.exceptions.ClientException e) { throw e; } } /** * (判断是否存在文件)
* 方法名:isExist
* 创建人:陈海
* 时间:2016年11月21日-下午3:54:36
* * @param bucket * @param key * @param type * @return boolean
* @throws
* @since 1.0.0 */ @Deprecated public boolean isExist(EnumPublicBuckets bucket, String key, EnumFileType type) { String fullKey = getProjectName() + "/" + type.getLocation() + key; return getOssClient().doesObjectExist(getBucket(bucket.getBucketName()), fullKey); } /** * (用bucket名称和完整key 判断文件是否存在)
* 方法名:isExist
* 创建人:陈海
* 时间:2017年5月12日-下午6:38:49
* * @param bucket * @param fullKey * @return boolean
* @throws
* @since 1.0.0 */ public static boolean isExist(String bucket, String fullKey) { return getOssClient().doesObjectExist(bucket, fullKey); } /** * 文件是否存在 内网 * * @param bucket * @param fullKey * @return */ public static boolean isExistOfInternal(String bucket, String fullKey) { return getInternalOssClient().doesObjectExist(bucket, fullKey); } /** * (删除oss文件)
* 方法名:delFile
* 创建人:陈海
* 时间:2016年7月20日-上午10:44:52
* * @param bucket 存储空间名称 * @param key 文件保存在服务器上的另存名 * @param type 枚举文件类型,声音或图片等 * @return boolean
* @throws
* @since 1.0.0 */ public static boolean delFile(EnumAllBuckets bucket, String key, EnumFileType type) { getOssClient().deleteObject(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key); return true; } public static boolean deleteObject(String bucketName, String objectKey) { getInternalOssClient().deleteObject(bucketName, objectKey); return true; } public static boolean deleteObjects(String bucketName, List objectKeys) { if (objectKeys == null || objectKeys.size() == 0) { return false; } DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName); deleteObjectsRequest.setKeys(objectKeys); deleteObjectsRequest.setQuiet(true); getInternalOssClient().deleteObjects(deleteObjectsRequest); return true; } /** * (获取经处理的图片签名url)
* 方法名:getPicUrlWithSign
* 创建人:陈海
* 时间:2016年7月18日-下午1:07:23
* * @param bucket 空间名称 * @param key 文件保存在服务器上的名称 * @param type 枚举文件类型,声音或图片等 * @return String
* @throws
* @since 1.0.0 */ public static String getPicUrl(EnumPrivateBuckets bucket, String key, EnumFileType type, Long expiresSec) { if (expiresSec == null) { expiresSec = getExpiration(); } Date expires = new Date(new Date().getTime() + getExpiration() * 1000); String picUrl = getPriClient().generatePresignedUrl(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key, expires).toString(); return picUrl; } /** * (获取文件对象的签名url)
* 方法名:getUrlWithSign
* 创建人:陈海
* 时间:2016年7月18日-下午1:05:50
* * @param bucket 空间名称 * @param key 文件保存在服务器上的名称 * @param type 枚举文件类型,声音或图片等 * @return String
* @throws
* @since 1.0.0 */ public static String getUrl(EnumPrivateBuckets bucket, String key, EnumFileType type, Long expiresSec) { if (expiresSec == null) { expiresSec = getExpiration(); } Date expires = new Date(new Date().getTime() + expiresSec * 1000); String url = ""; if (type.equals(EnumFileType.VIDEO)) { url = getVideoClient().generatePresignedUrl(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key, expires).toString(); } else { url = getPriClient().generatePresignedUrl(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key, expires).toString(); } return url; } public static String getUrlWithOssEndPoint(EnumPrivateBuckets bucket, String key, EnumFileType type, Long expiresSec) { if (expiresSec == null) { expiresSec = getExpiration(); } Date expires = new Date(new Date().getTime() + expiresSec * 1000); return getOssClient().generatePresignedUrl(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key, expires).toString(); } /** * (获取object)
* 方法名:getObject
* 创建人:陈海
* 时间:2016年12月28日-上午10:55:43
* * @param bucket * @param key * @param type * @return OSSObject
* @throws
* @since 1.0.0 */ public static OSSObject getObject(EnumPrivateBuckets bucket, String key, EnumFileType type) { OSSObject ossObject = getOssClient().getObject(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key); return ossObject; } public static OSSObject getPubObject(EnumAllBuckets bucket, String key, EnumFileType type) { OSSObject ossObject = getOssClient().getObject(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key); return ossObject; } public static OSSObject getPubObject(String bucketName, String fullKey) { OSSObject ossObject = getOssClient().getObject(bucketName, fullKey); return ossObject; } public static OSSObject getInternalPubObject(String bucketName, String fullKey) { OSSObject ossObject = getInternalOssClient().getObject(bucketName, fullKey); return ossObject; } public static ObjectMetadata getPubObjectMedeta(EnumAllBuckets bucket, String key, EnumFileType type) { ObjectMetadata ossObjectMeta = getOssClient().getObjectMetadata(getBucket(bucket.getBucketName()), getProjectName() + "/" + type.getLocation() + key); return ossObjectMeta; } public static String calcFileMD5(String bucketName, String objectKey) { try { OSSObject ossObj = getOssClient().getObject(bucketName, objectKey); MessageDigest md = MessageDigest.getInstance("MD5"); try (DigestInputStream digestInputStream = new DigestInputStream(ossObj.getObjectContent(), md)) { // 读取数据流并更新 MD5 byte[] buffer = new byte[8192]; while (digestInputStream.read(buffer) != -1) { // DigestInputStream 会自动更新 MessageDigest } } catch (Exception e) { logger.info("读取oss文件异常: ", e); return ""; } // 获取最终的 MD5 值 byte[] md5Bytes = md.digest(); // 转换为十六进制字符串 StringBuilder sb = new StringBuilder(); for (byte b : md5Bytes) { sb.append(String.format("%02x", b)); } String md5 = sb.toString(); logger.info(String.format("buketName: %s, objectKey: %s, MD5: %s", bucketName, objectKey, md5)); return md5; } catch (Exception e) { logger.error("计算文件MD5异常: ", e); } return ""; } /** * (重命名文件,实现是先拷贝文件,再删掉旧的文件)
* 方法名:renameFile
* 创建人:陈海
* 时间:2016年8月1日-下午4:03:09
* * @param srcBucket * @param srckey * @param destkey * @return boolean
* @throws
* @since 1.0.0 */ @Deprecated public boolean renameFile(EnumAllBuckets srcBucket, String srckey, String destkey, EnumFileType srcType, EnumFileType destType) { // 拷贝Object getOssClient().copyObject(getBucket(srcBucket.getBucketName()), getProjectName() + "/" + srcType.getLocation() + srckey, getBucket(srcBucket.getBucketName()), getProjectName() + "/" + destType.getLocation() + destkey); delFile(srcBucket, srckey, srcType); return true; } /** * (将oss srckey 命名为 destkey)
* 方法名:renameFileWithFullKey
* 创建人:陈海
* 时间:2017年9月16日-下午5:24:39
* * @param srcBucket * @param srckey * @param destkey * @return boolean
* @throws
* @since 1.0.0 */ public static boolean renameFileWithFullKey(EnumAllBuckets srcBucket, String srckey, String destkey) { // 拷贝Object getOssClient().copyObject(getBucket(srcBucket.getBucketName()), srckey, getBucket(srcBucket.getBucketName()), destkey); getOssClient().deleteObject(getBucket(srcBucket.getBucketName()), srckey); return true; } public static boolean renameFileWithFullKeyFromInternal(EnumAllBuckets srcBucket, String srckey, String destkey, long size) { // 拷贝Object if (size < 1024 * 1024 * 1024) { getInternalOssClient().copyObject(getBucket(srcBucket.getBucketName()), srckey, getBucket(srcBucket.getBucketName()), destkey); } else { multipartCopyObjectFromInternal(getBucket(srcBucket.getBucketName()), srckey, getBucket(srcBucket.getBucketName()), destkey); } getInternalOssClient().deleteObject(getBucket(srcBucket.getBucketName()), srckey); return true; } // 分片拷贝object,大于1G的文件需要分片拷贝 public static void multipartCopyObjectFromInternal(String sourceBucketName, String sourceObjectName, String destinationBucketName, String destinationObjectName) { OSSClient ossClient = getInternalOssClient(); ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName); // 获取被拷贝文件的大小。 long contentLength = objectMetadata.getContentLength(); // 设置分片大小为10MB。 long partSize = 1024 * 1024 * 10; // 计算分片总数。 int partCount = (int) (contentLength / partSize); if (contentLength % partSize != 0) { partCount++; } logger.info("oss 分片拷贝开始,sourceObjectName:" + sourceObjectName + ",size:" + contentLength + ",partCount:" + partCount); // 初始化拷贝任务。可以通过InitiateMultipartUploadRequest指定目标文件元信息。 InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest( destinationBucketName, destinationObjectName); InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient .initiateMultipartUpload(initiateMultipartUploadRequest); String uploadId = initiateMultipartUploadResult.getUploadId(); // 分片拷贝。 List partETags = new ArrayList(); for (int i = 0; i < partCount; i++) { // 计算每个分片的大小。 long skipBytes = partSize * i; long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes; // 创建UploadPartCopyRequest。可以通过UploadPartCopyRequest指定限定条件。 UploadPartCopyRequest uploadPartCopyRequest = new UploadPartCopyRequest(sourceBucketName, sourceObjectName, destinationBucketName, destinationObjectName); uploadPartCopyRequest.setUploadId(uploadId); uploadPartCopyRequest.setPartSize(size); uploadPartCopyRequest.setBeginIndex(skipBytes); uploadPartCopyRequest.setPartNumber(i + 1); UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest); // 将返回的分片ETag保存到partETags中。 partETags.add(uploadPartCopyResult.getPartETag()); } // 提交分片拷贝任务。 CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest( destinationBucketName, destinationObjectName, uploadId, partETags); ossClient.completeMultipartUpload(completeMultipartUploadRequest); logger.info("oss 分片拷贝结束,sourceObjectName:" + sourceObjectName + ",size:" + contentLength + ",partCount:" + partCount); } public static void copyObject(String srcBucketName, String srcObjectKey, String destBucketName, String destObjectKey) { getOssClient().copyObject(srcBucketName, srcObjectKey, destBucketName, destObjectKey); } public static void copyObjectFromInternal(String srcBucketName, String srcObjectKey, String destBucketName, String destObjectKey) { getInternalOssClient().copyObject(srcBucketName, srcObjectKey, destBucketName, destObjectKey); } private static InputStream compressImg(InputStream stream, EnumFileSuffix suffix, EnumFileType fileType) { if (!getNeedPress()) { return stream; } if (suffix == EnumFileSuffix.JPG || suffix == EnumFileSuffix.PNG || suffix == EnumFileSuffix.JPEG || suffix == EnumFileSuffix.BMP) { try { byte[] file = CompressImage.compress(stream, 1080); if (file != null) { stream = new ByteArrayInputStream(file); } else { logger.warn("图片上传有误"); return null; } } catch (Exception e) { logger.error("图片压缩失败", e); if (null != stream) { try { stream.close(); } catch (IOException e1) { } } throw new CommonsException(EnumErrorException.PIC_FORMAT_ERROR); } } return stream; } public static String submitPubTranscodeJob(EnumPublicBuckets inputBucket, EnumAllBuckets outputBucket, String fullKey, String outPutKey, String templateId) { OSSFileDO inputFile = new OSSFileDO(OSS_REGION, getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName()), fullKey); JSONArray outputs = new JSONArray(); JSONObject outPutConfig = new JSONObject(); outPutConfig.put("OutputObject", outPutKey); outPutConfig.put("TemplateId", templateId); outputs.add(outPutConfig); SubmitJobsRequest request = new SubmitJobsRequest(); request.setInput(inputFile.toJsonString()); request.setOutputs(outputs.toJSONString()); request.setPipelineId(PIPELINEID); request.setOutputBucket(getBucket(outputBucket.getBucketName())); request.setOutputLocation(OSS_REGION); Integer outputJobCount = 1; SubmitJobsResponse response = null; try { response = getDefaultAcsClient().getAcsResponse(request); if (response.getJobResultList().size() != outputJobCount) { throw new RuntimeException("SubmitJobsRequest Size failed"); } return response.getJobResultList().get(0).getJob().getJobId(); } catch (ServerException e) { logger.error("submitTranscodeJob Server failed", e); throw new CommonsException(EnumErrorException.TRANS_CODE_SERVER_ERROR); } catch (com.aliyuncs.exceptions.ClientException e) { logger.error("submitTranscodeJob Client failed", e); throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR); } } public static String getPubPicAverageColor(EnumAllBuckets bucket, String key) { String style = "image/average-hue"; try { GetObjectRequest request = new GetObjectRequest(getBucket(bucket.getBucketName()), key); request.setProcess(style); OSSObject obj = getOssClient().getObject(request); if (obj != null) { String a = IOUtils.toString(obj.getObjectContent()); JSONObject jo = (JSONObject) JSONObject.parse(a); String rgb = jo.getString("RGB"); if (rgb != null) { rgb = rgb.replace("0x", "#"); } return rgb; } } catch (Exception e) { throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR); } return null; } public static Properties getPubObjMediaInfoData(String bucketName, String fullKey) { DefaultAcsClient client = getDefaultAcsClient(); SubmitMediaInfoJobRequest request = new SubmitMediaInfoJobRequest(); request.setReadTimeout(Integer.MAX_VALUE); SubmitMediaInfoJobResponse response = new SubmitMediaInfoJobResponse(); JSONObject json = new JSONObject(); json.put("Location", "oss-cn-hangzhou"); json.put("Bucket", bucketName); json.put("Object", fullKey); request.setInput(json.toJSONString()); try { response = client.getAcsResponse(request); // String width = response.getMediaInfoJob().getProperties().getWidth(); // String height = response.getMediaInfoJob().getProperties().getHeight(); return response.getMediaInfoJob().getProperties(); } catch (Exception e) { throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR, e); } } public static SignatureVO getUploadPolicy(Integer fileType) throws Exception { // 后台随机生成唯一文件名 String env = PropertiesUtils.getProjectEnv(); if (StringUtils.isEmpty(env)) { env = "qa"; } String fileName = RandomUtil.generate18String(); String contentType = ""; if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) { fileName = "/video/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName; } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) { fileName = "/voice/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName; } else { fileName = "/pic/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName; } long expireTime = 60 * 60 * 4; long expireEndTime = System.currentTimeMillis() + expireTime * 1000; Date expiration = new Date(expireEndTime); PolicyConditions policyConds = new PolicyConditions(); //4.95G 上限是5个G policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 5261334938l); policyConds.addConditionItem(MatchMode.Exact, PolicyConditions.COND_KEY, AliOssConfig.getProjectName() + fileName); if (!StringUtils.isEmpty(contentType)) { policyConds.addConditionItem(PolicyConditions.COND_CONTENT_TYPE, contentType); } String postPolicy = AliOssConfig.getOssClient().generatePostPolicy(expiration, policyConds); byte[] binaryData = postPolicy.getBytes("utf-8"); String encodedPolicy = BinaryUtil.toBase64String(binaryData); String postSignature = AliOssConfig.getOssClient().calculatePostSignature(postPolicy); SignatureVO signatureVO = new SignatureVO(); signatureVO.setAccessId(AliOssConfig.getAccessKeyId()); signatureVO.setPolicy(encodedPolicy); signatureVO.setSignature(postSignature); signatureVO.setFileName(AliOssConfig.getProjectName() + fileName); signatureVO.setHost(AliOssConfig.getUploadDomain()); signatureVO.setExpire(String.valueOf(expireEndTime / 1000)); return signatureVO; } public static String getSignaturedUrl(String fileName, Boolean isPrivate) { if (StringUtils.isBlank(fileName)) { return fileName; } if (StringUtils.startsWith(fileName, "https")) { return fileName; } String host = AliOssConfig.getVideoDomain(); fileName = host + fileName; return fileName; } public static String getSignaturedInternalUrl(String fileName, Boolean isPrivate) throws Exception { if (StringUtils.isBlank(fileName)) { return fileName; } if (StringUtils.startsWith(fileName, "https")) { return fileName; } String bucket = getBucket(isPrivate); String host = "http://" + bucket + "." + AliOssConfig.getInternalEndPoint(); fileName = host + "/" + fileName; return fileName; } public static String saveVideoCoverImagFromInternal(File file, Integer fileType, Boolean isPrivate, Long videoId) throws Exception { Date begin = new Date(); logger.info(String.format("开始往阿里云OSS上传封面图片,当前时间为:%s", begin.getTime())); String bucketName = getBucket(isPrivate); String fullKey = getVideoCoverImagPath(fileType, isPrivate, videoId.toString(), null); AliOssConfig.getInternalOssClient().putObject(bucketName, fullKey, file); Date end = new Date(); logger.info(String.format("阿里云OSS上传封面图片完成,总耗时为 %s 毫秒。图片地址为:%s, 正在执行下一步。。", end.getTime() - begin.getTime(), fullKey)); return fullKey; } public static String saveVideoCoverImagFromInternal(InputStream input, Integer fileType, Boolean isPrivate, String filePrex, String dic) throws Exception { Date begin = new Date(); logger.info(String.format("开始往阿里云OSS上传图片,当前时间为:%s", begin.getTime())); String bucketName = getBucket(isPrivate); String fullKey = getVideoCoverImagPath(fileType, isPrivate, filePrex, dic); // AliOssConfig.getOssClient().putObject(bucketName, fullKey, file); AliOssConfig.getInternalOssClient().putObject(bucketName, fullKey, input); Date end = new Date(); logger.info( String.format("阿里云OSS上传图片完成,总耗时为 %s 毫秒。图片地址为:%s, 正在执行下一步。。", end.getTime() - begin.getTime(), fullKey)); return fullKey; } public static String getVideoCoverImagPath(Integer fileType, Boolean isPrivate, String filePrex, String dic) throws Exception { String fileName = UUID.randomUUID().toString().replaceAll("-", "") + Calendar.getInstance().getTimeInMillis() + "_" + filePrex; if (StringUtils.isNotBlank(dic)) { fileName = (dic + "/" + fileName); } if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) { fileName = "/video/" + fileName; } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) { fileName = "/voice/" + fileName; } else { fileName = "/pic/" + fileName; } String fullKey = AliOssConfig.getProjectName() + fileName; return fullKey; } public static String getBucket(boolean isPrivate) { if (isPrivate) { return AliOssFileTool.getBucket(EnumAllBuckets.PRIVIDEOBUCKET.getBucketName()); } else { return AliOssFileTool.getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName()); } } public static ObjectMetadata getObjectMetadata(String fileName) throws Exception { // Endpoint以杭州为例,其它Region请按实际情况填写。 // 创建OSSClient实例。 OSSClient ossClient = new OSSClient(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(), AliOssConfig.getAccessKeySecret()); // // 获取文件的部分元信息。 // SimplifiedObjectMeta objectMeta = ossClient.getSimplifiedObjectMeta( // getBucket(false), fileName); // logger.info( "SimplifiedObjectMeta==="+ JSON.toJSONString(objectMeta)); // 获取文件的全部元信息。 ObjectMetadata metadata = ossClient.getObjectMetadata(getBucket(false), fileName); // logger.info( "metadata==="+ JSON.toJSONString(metadata)); return metadata; } /** * 获取部分元信息 * * @param bucketName * @param fileName * @return * @throws Exception */ public static SimplifiedObjectMeta getSimpleObjectMetadata(String bucketName, String fileName) throws Exception { OSS ossClient = new OSSClientBuilder().build(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(), AliOssConfig.getAccessKeySecret()); SimplifiedObjectMeta metadata = ossClient.getSimplifiedObjectMeta(bucketName, fileName); ossClient.shutdown(); return metadata; } /** * 获取全部元信息 * * @param bucketName * @param fileName * @return * @throws Exception */ public static ObjectMetadata getObjectMetadata(String bucketName, String fileName) throws Exception { // OSS ossClient = new OSSClientBuilder().build(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(), // AliOssConfig.getAccessKeySecret()); // // 获取文件的全部元信息 // ObjectMetadata metadata = ossClient.getObjectMetadata(bucketName, fileName); // ossClient.shutdown(); // return metadata; ObjectMetadata metadata = getInternalOssClient().getObjectMetadata(bucketName, fileName); return metadata; } // public static void main(String[] args) throws Exception { //// String a = JSONObject.toJSONString(AliOssFileTool.getDefaultAcsClient()); //// System.out.println(a); // } public static Map buildCommonParameters() { Map parameterMap = new HashMap<>(); // 请求公共参数 parameterMap.put("Version", "2014-06-18"); parameterMap.put("AccessKeyId", AliOssConfig.getAccessKeyId()); // 此处请替换成您自己的AccessKeyId // parameterMap.put("Timestamp", // "2018-07-27T13:03:45Z");//此处将时间戳固定只是测试需要,这样此示例中生成的签名值就不会变,方便您对比验证,可变时间戳的生成需要用下边这句替换 parameterMap.put("Timestamp", DateUtils.formatIso8601Date(new Date())); parameterMap.put("SignatureMethod", "HMAC-SHA1"); parameterMap.put("SignatureVersion", "1.0"); // parameterMap.put("SignatureNonce", "4902260a-516a-4b6a-a455-45b653cf6150"); // //此处将唯一随机数固定只是测试需要,这样此示例中生成的签名值就不会变,方便您对比验证,可变唯一随机数的生成需要用下边这句替换 parameterMap.put("SignatureNonce", UUID.randomUUID().toString()); parameterMap.put("Format", "JSON"); // 另外支持JSON格式 return parameterMap; } /** * @Title: sendAsyncSnapshotJob @Description: 获取发送视频批量截图的任务的URL,此接口为异步任务 @param * fileName 要截图的视频的路径,如 longvideo/video/XXXXX,其中XXXXX为视频名称 @param * snapshotPath 截图后的图片输出路径,如 * longvideo/snapshot/XXXXX,截图时会自动在文件名后面加序号,输出路径为空时,自动指定为longvideo/snapshot/XXXXX @param * startMillseconds 截图时间,单位毫秒 @param interval * 截图间隔时间,若指定则表示异步模式序列截图,Interval必须大于等于0,默认10,单位秒。其中Interval=0表示根据视频时长平均截图。 @param * snapshotNumber * 截图数量,若指定则表示异步模式序列截图,且必须大于0,当Time+Interval*Num的截取点超过视频时长时,后续截图自动失效,截图完成时返回实际截取的个数;当Num=1,忽略Interval参数,表示异步单张截图 @return @throws * Exception @author 王树杞 @date 2018年7月27日 下午5:17:31 @version 2.0 @throws */ public static String sendAsyncSnapshotJob(String fileName, String snapshotPath, Integer startMillseconds, Integer interval, Integer snapshotNumber) throws Exception { // 首先获取公众参数 Map parameterMap = buildCommonParameters(); parameterMap.put("Action", "SubmitSnapshotJob"); Map inputParamsMap = new HashMap<>(); inputParamsMap.put("Bucket", AliOssFileTool.getBucket(false)); inputParamsMap.put("Location", AliOssFileTool.getSnapshotLocation()); inputParamsMap.put("Object", URLEncoder.encode(fileName, "UTF-8")); parameterMap.put("Input", JSON.toJSONString(inputParamsMap)); Map snapshotConfig = new HashMap<>(); Map outPutFile = new HashMap<>(); outPutFile.put("Bucket", AliOssFileTool.getBucket(false)); outPutFile.put("Location", AliOssFileTool.getSnapshotLocation()); if (StringUtils.isBlank(snapshotPath)) { snapshotPath = fileName.replace("/video/", "/snapshot/"); } outPutFile.put("Object", URLEncoder.encode(snapshotPath + "_{Count}", "UTF-8")); snapshotConfig.put("Interval", interval.toString()); snapshotConfig.put("Num", snapshotNumber.toString()); parameterMap.put("PipelineId", "abe6a0b9b9334858913eb416974485d2"); snapshotConfig.put("OutputFile", JSON.toJSONString(outPutFile)); parameterMap.put("SnapshotConfig", JSON.toJSONString(snapshotConfig)); String canonicalizedQueryString = buildCanonicalizedQueryString(parameterMap); String stringToSign = buildStringToSign(canonicalizedQueryString); String signature = buildSignature(AliOssConfig.getAccessKeySecret(), stringToSign); return buildRequestURL(signature, parameterMap); } /** * @Title: sendSyncSnapshotJob @Description: 获取发送某个视频的同步截图的任务URL地址 @param * fileName 视频路径 @param snapshotPath 输出的截图路径 @param startMillseconds * 截图的时间戳 @return 某个视频的同步截图的任务URL地址 @throws Exception @author 王树杞 @date * 2018年7月27日 下午8:07:47 @version 2.0 @throws */ public static String sendSyncSnapshotJob(String fileName, String snapshotPath, Integer startMillseconds) throws Exception { // 首先获取公众参数 Map parameterMap = buildCommonParameters(); parameterMap.put("Action", "SubmitSnapshotJob"); Map inputParamsMap = new HashMap<>(); inputParamsMap.put("Bucket", AliOssFileTool.getBucket(false)); inputParamsMap.put("Location", AliOssFileTool.getSnapshotLocation()); inputParamsMap.put("Object", URLEncoder.encode(fileName, "UTF-8")); parameterMap.put("Input", JSON.toJSONString(inputParamsMap)); Map snapshotConfig = new HashMap<>(); Map outPutFile = new HashMap<>(); outPutFile.put("Bucket", AliOssFileTool.getBucket(false)); outPutFile.put("Location", AliOssFileTool.getSnapshotLocation()); if (StringUtils.isBlank(snapshotPath)) { snapshotPath = fileName.replace("/video/", "/snapshot/"); } outPutFile.put("Object", URLEncoder.encode(snapshotPath, "UTF-8")); snapshotConfig.put("Time", startMillseconds.toString()); snapshotConfig.put("OutputFile", JSON.toJSONString(outPutFile)); parameterMap.put("SnapshotConfig", JSON.toJSONString(snapshotConfig)); String canonicalizedQueryString = buildCanonicalizedQueryString(parameterMap); String stringToSign = buildStringToSign(canonicalizedQueryString); String signature = buildSignature(AliOssConfig.getAccessKeySecret(), stringToSign); return buildRequestURL(signature, parameterMap); } private static String percentEncode(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, ENCODE_TYPE).replace("+", "%20").replace("*", "%2A").replace("%7E", "~"); } private static String buildCanonicalizedQueryString(Map parameterMap) throws UnsupportedEncodingException { // 对参数进行排序 List sortedKeys = new ArrayList(parameterMap.keySet()); Collections.sort(sortedKeys); StringBuilder temp = new StringBuilder(); for (String key : sortedKeys) { // 此处需要对key和value进行编码 String value = parameterMap.get(key); temp.append(SEPARATOR).append(percentEncode(key)).append(EQUAL).append(percentEncode(value)); } return temp.toString().substring(1); } private static String buildStringToSign(String canonicalizedQueryString) throws UnsupportedEncodingException { // 生成stringToSign字符 StringBuilder temp = new StringBuilder(); temp.append(HTTP_METHOD).append(SEPARATOR); temp.append(percentEncode("/")).append(SEPARATOR); // 此处需要对canonicalizedQueryString进行编码 temp.append(percentEncode(canonicalizedQueryString)); return temp.toString(); } private static String buildSignature(String keySecret, String stringToSign) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException { SecretKey key = new SecretKeySpec((keySecret + SEPARATOR).getBytes(ENCODE_TYPE), SignatureMethod.HMAC_SHA1); Mac mac = Mac.getInstance(ALGORITHM); mac.init(key); byte[] hashBytes = mac.doFinal(stringToSign.toString().getBytes(ENCODE_TYPE)); byte[] base64Bytes = new Base64().encode(hashBytes); String base64UTF8String = new String(base64Bytes, "utf-8"); return URLEncoder.encode(base64UTF8String, ENCODE_TYPE); } private static String buildRequestURL(String signature, Map parameterMap) throws UnsupportedEncodingException { // 生成请求URL StringBuilder temp = new StringBuilder("http://mts.cn-hangzhou.aliyuncs.com?"); temp.append(URLEncoder.encode("Signature", ENCODE_TYPE)).append("=").append(signature); for (Map.Entry e : parameterMap.entrySet()) { temp.append("&").append(percentEncode(e.getKey())).append("=").append(percentEncode(e.getValue())); } return temp.toString(); } public static String saveInputStreamPic(InputStream inputStream, String bucket, String project, String dir, String key) throws OSSException, ClientException, IOException { String fullKey = project + "/" + dir + "/" + key; ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType("image/jpg"); getOssClient().putObject(bucket, fullKey, inputStream, objectMetadata); return fullKey; } public static String sendImageToAliOss(BufferedImage image) throws Exception { ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", os); InputStream is = new ByteArrayInputStream(os.toByteArray()); // 将生成的图片往OSS里面上传 String random = UUID.randomUUID().toString().replaceAll("-", "") + new Random().nextLong(); String key = Md5Util.encoderByMd5(random); String coverImgPath = AliOssFileTool.saveVideoCoverImagFromInternal(is, key); return coverImgPath; } public static String saveVideoCoverImagFromInternal(InputStream inputStream, String key) throws OSSException, ClientException, IOException { String bucketName = AliOssConfig.getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName()); String fullKey = getProjectName() + "/pic/video/cover/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + key; ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType("image/jpg"); getInternalOssClient().putObject(bucketName, fullKey, inputStream, objectMetadata); return fullKey; } /** * @param duration 时长,如果是图片则传0,视频则传视频时长 * @param isInternal 是否内网访问 * @return * @return String * @Title: generatePresignedUrl * @Description:得到对象的临时访问URL * @author 王树杞 * @date 2019年2月25日 上午11:04:22 * @version 2.0 */ public static String generatePresignedUrl(String filePath, Integer duration, boolean isInternal) { if (StringUtils.isEmpty(filePath)) { return null; } if (filePath.startsWith("http")) { filePath = filePath.replace(PropertiesUtils.getDownloadDomain(), ""); filePath = filePath.replace("https://weappupload.piaoquantv.com/", ""); filePath = filePath.replace("https://testweappupload.yishihui.com/", ""); filePath = filePath.replace("https://lvupload.piaoquantv.com/", ""); } if (filePath.contains("Signature") && filePath.contains("OSSAccessKeyId")) { return filePath; } if (duration == null) { duration = 0; } // 设置URL过期时间为视频时长+3天。 // 单位为秒; Date expiration = new Date(new Date().getTime() + (duration + (3 * 24 * 60 * 60)) * 1000); // //一分钟 // Date expiration = new Date(new Date().getTime() +( 60) * 1000); // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。 URL url = getOssReadOnlyClient().generatePresignedUrl(BasePropertiesUtils.getVideoBucket(), filePath, expiration, HttpMethod.GET); String path = url.getFile(); if (StringUtils.startsWith(path, "/")) { return StringUtils.substring(path, 1); } return path; } public static String saveObjectFromInternal(InputStream inputStream, String fullKey) throws OSSException, ClientException, IOException { String bucketName = BasePropertiesUtils.getVideoBucket(); getInternalOssClient().putObject(bucketName, fullKey, inputStream); return fullKey; } public static String saveObjectFromInternal(String bucketName, String url, String fullKey) throws Exception { InputStream inputStream = new URL(url).openStream(); getInternalOssClient().putObject(bucketName, fullKey, inputStream); if (inputStream != null) { inputStream.close(); } return fullKey; } public static boolean checkObjectExistFromInternal(String bucketName, String fullKey) { return getInternalOssClient().doesObjectExist(bucketName, fullKey); } public static String uploadShangHaiVideo(InputStream inputStream, String key, String bucketName) { ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentType("video/mp4"); getShangHaiInternalOssClient().putObject(bucketName, key, inputStream, objectMetadata); return key; } public static boolean isShangHaiExist(String bucket, String fullKey) { return getShangHaiInternalOssClient().doesObjectExist(bucket, fullKey); } public static Boolean isStorageClassArchive(String bucket, String key) throws OSSException, ClientException { ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key); StorageClass storageClass = objectMetadata.getObjectStorageClass(); return storageClass == StorageClass.Archive; } public static boolean isStorageClassColdArchive(String bucket, String key) throws OSSException, ClientException { ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key); StorageClass storageClass = objectMetadata.getObjectStorageClass(); return storageClass == StorageClass.ColdArchive; } public static void setStorageClassToArchive(String bucket, String key) throws OSSException, ClientException { // 创建CopyObjectRequest对象。 CopyObjectRequest request = new CopyObjectRequest(bucket, key, bucket, key); // 创建ObjectMetadata对象。 ObjectMetadata objectMetadata = new ObjectMetadata(); // 封装header,此处以设置存储类型为归档类型为例。 objectMetadata.setHeader("x-oss-storage-class", StorageClass.Archive); request.setNewObjectMetadata(objectMetadata); // 更改文件存储类型。 CopyObjectResult result = getInternalOssClient().copyObject(request); } public static void recoverVideoAsync(String bucket, String srckey) { OSSClient ossInternalClient = getInternalOssClient(); ObjectMetadata objectMetadata = ossInternalClient.getObjectMetadata(bucket, srckey); // 校验文件是否为归档文件。 StorageClass storageClass = objectMetadata.getObjectStorageClass(); if (storageClass == StorageClass.Archive) { // 解冻文件。 try { ossInternalClient.restoreObject(bucket, srckey); } catch (Exception e) { // OSS Auto-generated catch blockvideo-common/src/main/java/com/weiqu/video/common/enums/ExceptionCodeEnum.java // e.printStackTrace(); logger.error("视频可能在解冻中"); } } else if (storageClass == StorageClass.ColdArchive) { // 解冻文件。 try { RestoreJobParameters parameters = new RestoreJobParameters(RestoreTier.RESTORE_TIER_EXPEDITED); RestoreConfiguration configuration = new RestoreConfiguration(3, parameters); ossInternalClient.restoreObject(bucket, srckey, configuration); } catch (Exception ex) { logger.error("视频可能在解冻中", ex); } } } public static Boolean isRestoreCompleted(String bucket, String key) throws OSSException, ClientException { ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key); Boolean isRestoreCompleted = false; try { isRestoreCompleted = objectMetadata.isRestoreCompleted(); } catch (Exception e) { // OSS Auto-generated catch block // e.printStackTrace(); logger.error("视频可能在解冻中"); } return isRestoreCompleted; } /** * @param path * @param path * @return * @ApiModelProperty(value="冻结状态: -1:无须解冻 0:待解冻 1:解冻中 2:解冻完成") */ public static Integer getFrozenStatus(String path) { if (path.startsWith("http") && !path.startsWith(PropertiesUtils.getDownloadDomain())) { logger.info("getFrozenStatus-outer size video, path :" + path); return -1; } String realPath = path.replace(PropertiesUtils.getDownloadDomain(), ""); String bucketName = BasePropertiesUtils.getVideoBucket(); ObjectMetadata objectMetadata = null; try { objectMetadata = getInternalOssClient().getObjectMetadata(bucketName, realPath); } catch (Exception ex) { logger.error("getFrozenStatus-error", ex); return -1; } if (Objects.isNull(objectMetadata)) { logger.error("getFrozenStatus-error, path :" + path + " do not has metaData"); return -1; } StorageClass storageClass = objectMetadata.getObjectStorageClass(); if (storageClass != StorageClass.Archive && storageClass != StorageClass.ColdArchive) { logger.info("getFrozenStatus, path :" + path + " do not in Archive status"); return -1; } try { // 解冻完成 boolean isRestoreCompleted = objectMetadata.isRestoreCompleted(); if (isRestoreCompleted) { return 2; } else { return 1; } } catch (NullPointerException e) { logger.info("getFrozenStatus, path :" + path + " waiting for forzed!"); return 0; } } public static Map getMediaAllInfo(String inPath) { return getMediaAllInfo(inPath, BasePropertiesUtils.getVideoBucket()); } public static Map getMediaAllInfo(String inPath, String bucketName) { Map map = new HashMap(); String encodedInput; try { encodedInput = URLEncoder.encode(inPath, "utf-8"); } catch (UnsupportedEncodingException e) { logger.error("获取元数据输入流解析错误", e); map.put("status", "1"); return map; } SubmitMediaInfoJobRequest request = new SubmitMediaInfoJobRequest(); JSONObject input = new JSONObject(); input.put("Bucket", bucketName); input.put("Location", PropertiesUtils.getTranscodeLocation()); input.put("Object", encodedInput); request.setInput(input.toJSONString()); request.setPipelineId(PropertiesUtils.getTranscodePipelineId()); try { SubmitMediaInfoJobResponse response = new SubmitMediaInfoJobResponse(); response = AliOssConfig.getIAcsClient().getAcsResponse(request); if (response.getMediaInfoJob().getState() != null && response.getMediaInfoJob().getState().equalsIgnoreCase("Fail")) { logger.error("获取元数据错误:" + JSONObject.toJSONString(response.getMediaInfoJob()) + ",requestId:" + response.getRequestId()); map.put("status", "2"); return map; } Properties properties = response.getMediaInfoJob().getProperties(); Properties.Streams.VideoStream videoStream = null; if (CollectionUtils.isNotEmpty(properties.getStreams().getVideoStreamList())) { videoStream = properties.getStreams().getVideoStreamList().get(0); } Properties.Format format = properties.getFormat(); logger.info("videoStream:" + JSONObject.toJSONString(videoStream)); logger.info("format:" + JSONObject.toJSONString(format)); map.put("status", "0"); if (properties.getWidth() != null) { map.put("width", Integer.parseInt(properties.getWidth()) + ""); } if (properties.getHeight() != null) { map.put("height", Integer.parseInt(properties.getHeight()) + ""); } if (videoStream != null) { map.put("rotate", videoStream.getRotate()); map.put("codeName", videoStream.getCodecName()); } if (format != null) { map.put("size", format.getSize()); //设置成long类型的 大于0少于1的设置成1 if (Double.parseDouble(format.getDuration()) > 0 && Double.parseDouble(format.getDuration()) < 1) { map.put("duration", new Double(1).longValue()); } else { map.put("duration", StringUtils.isEmpty(format.getDuration()) ? 0 : new Double(Double.parseDouble(format.getDuration())).longValue()); } map.put("bitRate", StringUtils.isEmpty(format.getBitrate()) ? 0 : new Double(Double.parseDouble(format.getBitrate())).longValue() * 1000); } } catch (ServerException e) { logger.error("获取元数据服务器异常", e); map.put("status", "3"); } catch (ClientException e) { logger.error("获取元数据客户端异常", e); map.put("status", "4"); } catch (Exception e) { logger.error("获取元数据异常", e); map.put("status", "5"); } return map; } public static CopyObjectResult setStorageClassToColdArchive(String bucket, String key) { CopyObjectRequest request = new CopyObjectRequest(bucket, key, bucket, key); ObjectMetadata objectMetadata = new ObjectMetadata(); // 封装header,此处以设置存储类型为归档类型为例。 objectMetadata.setHeader("x-oss-storage-class", StorageClass.ColdArchive); request.setNewObjectMetadata(objectMetadata); // 更改文件存储类型。 return getInternalOssClient().copyObject(request); } public static String getRandomObjectKey(Integer fileType) { String env = PropertiesUtils.getProjectEnv(); if (StringUtils.isEmpty(env)) { env = "qa"; } String fileName = RandomUtil.generate18String(); if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) { fileName = "/video/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName; } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) { fileName = "/voice/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName; } else { fileName = "/pic/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName; } return getProjectName() + fileName; } public static StsTokenVO getStsToken(String fileName, Long durationSeconds) { String endpoint = BasePropertiesUtils.getLongvideoStsEndpoint(); String accessKeyId = BasePropertiesUtils.getLongvideoStsAccessKeyId(); String accessKeySecret = BasePropertiesUtils.getLongvideoStsAccessKeySecret(); String roleArn = BasePropertiesUtils.getLongvideoStsRoleArn(); String roleSessionName = BasePropertiesUtils.getLongvideoStsSessionName(); StsTokenVO result = new StsTokenVO(); try { String region = "cn-hangzhou"; DefaultProfile.addEndpoint("", "", "Sts", endpoint); IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret); DefaultAcsClient client = new DefaultAcsClient(profile); final AssumeRoleRequest request = new AssumeRoleRequest(); request.setMethod(MethodType.POST); request.setRoleArn(roleArn); request.setRoleSessionName(roleSessionName); //设置过期时间 临时访问凭证的有效时间,单位为秒。最小值为900,最大值以当前角色设定的最大会话时间为准。角色最大会话时间取值范围为3600秒~43200秒 if (Objects.nonNull(durationSeconds)) { request.setDurationSeconds(durationSeconds); } JSONObject policy = getUploadFileStsPolicy(BasePropertiesUtils.getVideoBucket(), fileName); request.setPolicy(policy.toJSONString()); final AssumeRoleResponse response = client.getAcsResponse(request); result.setExpiration(response.getCredentials().getExpiration()); result.setAccessKeyId(response.getCredentials().getAccessKeyId()); result.setAccessKeySecret(response.getCredentials().getAccessKeySecret()); result.setSecurityToken(response.getCredentials().getSecurityToken()); result.setRequestId(response.getRequestId()); result.setFileName(fileName); result.setHost(AliOssConfig.getUploadDomain()); String host0 = BasePropertiesUtils.getOssaccelerateUploadDomain(); String host1 = "https://" + AliOssConfig.getBucket(EnumPublicBuckets.PUBBUCKET.getBucketName()) + "." + AliOssConfig.getOssEndPoint() + "/"; result.setHosts(new String[]{host0, host1}); result.setBucket(BasePropertiesUtils.getVideoBucket()); result.setRegion(region); result.setCname(true); // 返回服务器当前时间 result.setServerTimestamp(System.currentTimeMillis()); } catch (com.aliyuncs.exceptions.ClientException e) { logger.error(String.format("获取临时令牌失败,errorCode:%s;errorMessage:%s;requestId:%s", e.getErrCode(), e.getErrMsg(), e.getRequestId())); } catch (Exception e) { logger.error("获取临时令牌失败", e); } return result; } private static JSONObject getUploadFileStsPolicy(String bucketName, String fileName) { JSONObject policy = new JSONObject(); policy.put("Version", "1"); JSONArray statements = new JSONArray(); JSONObject statement = new JSONObject(); statement.put("Effect", "Allow"); JSONArray action = new JSONArray(); action.add("oss:PutObject"); statement.put("Action", action); JSONArray resource = new JSONArray(); resource.add("acs:oss:*:1894469520484605:" + bucketName + "/" + fileName); statement.put("Resource", resource); statements.add(statement); policy.put("Statement", statements); logger.info(String.format("Policy:%s", JSON.toJSONString(policy))); return policy; } }