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;
}
}