AliOssFileTool.java 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507
  1. package com.tzld.piaoquan.api.util;
  2. import cn.hutool.http.HttpUtil;
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONArray;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.aliyun.opensearch.sdk.dependencies.org.apache.commons.codec.binary.Base64;
  7. import com.aliyun.oss.*;
  8. import com.aliyun.oss.common.utils.BinaryUtil;
  9. import com.aliyun.oss.model.*;
  10. import com.aliyuncs.DefaultAcsClient;
  11. import com.aliyuncs.exceptions.ServerException;
  12. import com.aliyuncs.http.MethodType;
  13. import com.aliyuncs.http.ProtocolType;
  14. import com.aliyuncs.mts.model.v20140618.SubmitJobsRequest;
  15. import com.aliyuncs.mts.model.v20140618.SubmitJobsResponse;
  16. import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobRequest;
  17. import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobResponse;
  18. import com.aliyuncs.mts.model.v20140618.SubmitMediaInfoJobResponse.MediaInfoJob.Properties;
  19. import com.aliyuncs.profile.DefaultProfile;
  20. import com.aliyuncs.profile.IClientProfile;
  21. import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
  22. import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
  23. import com.stuuudy.commons.external.filestorage.alibaba.OSSFileDO;
  24. import com.stuuudy.commons.external.filestorage.enums.*;
  25. import com.stuuudy.commons.util.BlankUtil;
  26. import com.stuuudy.commons.util.CompressImage;
  27. import com.stuuudy.commons.util.MD5.Md5Util;
  28. import com.stuuudy.commons.util.exception.CommonsException;
  29. import com.stuuudy.commons.util.exception.EnumErrorException;
  30. import com.tzld.piaoquan.api.common.enums.EnumUploadFileType;
  31. import com.tzld.piaoquan.api.config.AliOssConfig;
  32. import com.tzld.piaoquan.api.model.vo.SignatureVO;
  33. import com.tzld.piaoquan.api.model.vo.StsTokenVO;
  34. import com.tzld.piaoquan.growth.common.utils.DateUtils;
  35. import com.tzld.piaoquan.growth.common.utils.RandomUtil;
  36. import lombok.extern.slf4j.Slf4j;
  37. import org.apache.commons.collections4.CollectionUtils;
  38. import org.apache.commons.io.IOUtils;
  39. import org.apache.commons.lang3.StringUtils;
  40. import org.apache.log4j.Logger;
  41. import org.springframework.stereotype.Component;
  42. import javax.crypto.Mac;
  43. import javax.crypto.SecretKey;
  44. import javax.crypto.spec.SecretKeySpec;
  45. import javax.imageio.ImageIO;
  46. import javax.xml.crypto.dsig.SignatureMethod;
  47. import java.awt.image.BufferedImage;
  48. import java.io.*;
  49. import java.net.URL;
  50. import java.net.URLEncoder;
  51. import java.security.DigestInputStream;
  52. import java.security.InvalidKeyException;
  53. import java.security.MessageDigest;
  54. import java.security.NoSuchAlgorithmException;
  55. import java.util.*;
  56. /**
  57. * (阿里对象存储工具类)<BR>
  58. * AliOssFileTool<BR>
  59. * 创建人:陈海 <BR>
  60. * 时间:2016年7月18日-下午12:47:52 <BR>
  61. *
  62. * @version 1.0.0
  63. */
  64. @Component
  65. @Slf4j
  66. public class AliOssFileTool extends AliOssConfig {
  67. private static Logger logger = Logger.getLogger(AliOssFileTool.class);
  68. private static final String ENCODE_TYPE = "UTF-8";
  69. private static final String ALGORITHM = "HmacSHA1";
  70. private static final String HTTP_METHOD = "GET";
  71. private static final String SEPARATOR = "&";
  72. private static final String EQUAL = "=";
  73. public static String saveInPublicWithPress(InputStream inputStream, EnumPublicBuckets bucket, String key, EnumFileType type,
  74. EnumFileSuffix fileSuffix) throws OSSException, ClientException {
  75. inputStream = compressImg(inputStream, fileSuffix, type);
  76. return saveInPublicNoPress(inputStream, bucket, key, type);
  77. }
  78. public static String saveInPublicReturnHost(InputStream inputStream, EnumPublicBuckets bucket, String fullKey,
  79. EnumFileType type) {
  80. String path = saveInPublic(inputStream, bucket, fullKey, type);
  81. // 保存路径
  82. return CdnUtil.getCdnUrlHost(type) + path;
  83. }
  84. public static String saveInPublic(InputStream inputStream, EnumPublicBuckets bucket, String fullKey, EnumFileType type) {
  85. String bucketName = getBucket(bucket.getBucketName());
  86. if (EnumFileType.VOICE.equals(type)) {
  87. ObjectMetadata om = new ObjectMetadata();
  88. om.setContentType("audio/mpeg");
  89. getOssClient().putObject(bucketName, fullKey, inputStream, om);
  90. } else {
  91. getOssClient().putObject(bucketName, fullKey, inputStream);
  92. }
  93. return fullKey;
  94. }
  95. public static String saveInPublic(String bucketName, String ossKey, InputStream inputStream, String contentType) {
  96. bucketName = getBucket(bucketName);
  97. ObjectMetadata om = new ObjectMetadata();
  98. om.setContentType(contentType);
  99. getOssClient().putObject(bucketName, ossKey, inputStream, om);
  100. return ossKey;
  101. }
  102. public static String moveFile(EnumPublicBuckets sourceBucket, String sourceKey, EnumPublicBuckets targetBucket, String targetKey) {
  103. getOssClient().copyObject(getBucket(sourceBucket.getBucketName()), sourceKey,
  104. getBucket(targetBucket.getBucketName()), targetKey);
  105. if (!StringUtils.equals(sourceKey, targetKey)) {
  106. getOssClient().deleteObject(getBucket(sourceBucket.getBucketName()), sourceKey);
  107. }
  108. return targetKey;
  109. }
  110. public static void deleteFile(EnumPublicBuckets bucket, String key) {
  111. getOssClient().deleteObject(getBucket(bucket.getBucketName()), key);
  112. }
  113. public static String saveInPublicNoPress(InputStream inputStream, EnumPublicBuckets bucket, String key,
  114. EnumFileType type) throws OSSException, ClientException {
  115. String fullKey = getProjectName() + "/" + type.getLocation() + key;
  116. saveInPublic(inputStream, bucket, fullKey, type);
  117. return fullKey;
  118. }
  119. /**
  120. * (网络资源上传) 方法名saveURLInPublicNoPress
  121. *
  122. * @param url 资源地址
  123. * @param key
  124. * @param type
  125. * @param fileSuffix
  126. * @return
  127. * @throws OSSException
  128. * @throws ClientException
  129. * @throws IOException String
  130. * @throws @version 1.0
  131. * @author 创建人:何振斌
  132. * @time 创建日期:2018年3月12日 下午7:10:00
  133. */
  134. public static String saveURLInPublicNoPress(String url, String bucketName, String key, EnumFileType type,
  135. EnumFileSuffix fileSuffix) throws OSSException, ClientException, IOException {
  136. String fullKey = getProjectName() + "/" + type.getLocation() + key;
  137. InputStream inputStream = null;
  138. if (!BlankUtil.isBlank(url)) {
  139. inputStream = new URL(url).openStream();
  140. }
  141. if (EnumFileType.VOICE.equals(type)) {
  142. ObjectMetadata om = new ObjectMetadata();
  143. om.setContentType("audio/mpeg");
  144. getOssClient().putObject(bucketName, fullKey, inputStream, om);
  145. } else {
  146. getOssClient().putObject(bucketName, fullKey, inputStream);
  147. }
  148. return getProjectName() + "/" + type.getLocation() + key;
  149. }
  150. /**
  151. * (根据名称和类型保存文件,返回是否成功)<BR>
  152. * 方法名:saveWiteKeyAndType<BR>
  153. * 创建人:陈海 <BR>
  154. * 时间:2016年7月18日-下午1:02:10 <BR>
  155. *
  156. * @param inputStream 文件流
  157. * @param bucket 空间名称
  158. * @param key 文件保存在服务器上的另存名
  159. * @param type 枚举文件类型,声音或图片等
  160. * @return boolean<BR>
  161. * @throws IOException
  162. * @throws ClientException
  163. * @throws OSSException
  164. * @throws <BR>
  165. * @since 1.0.0
  166. */
  167. public static boolean saveInPrivate(InputStream inputStream, EnumPrivateBuckets bucket, String key,
  168. EnumFileType type, EnumFileSuffix suffix) throws OSSException, ClientException, IOException {
  169. inputStream = compressImg(inputStream, suffix, type);
  170. String bucketName = getBucket(bucket.getBucketName());
  171. String fullKey = getProjectName() + "/" + type.getLocation() + key;
  172. getOssClient().putObject(bucketName, fullKey, inputStream);
  173. return true;
  174. }
  175. /**
  176. * (获取前缀为prefix的全部文件)<BR>
  177. * 方法名:listFileInFolder<BR>
  178. * 创建人:陈海 <BR>
  179. * 时间:2017年1月20日-下午4:59:25 <BR>
  180. *
  181. * @param bucket
  182. * @param prefix
  183. * @return List<OSSObjectSummary><BR>
  184. * @throws <BR>
  185. * @since 1.0.0
  186. */
  187. public static List<OSSObjectSummary> listFileInFolder(EnumPublicBuckets bucket, String prefix) {
  188. final int maxKeys = 200;
  189. String nextMarker = null;
  190. ObjectListing objectListing;
  191. List<OSSObjectSummary> sums = new ArrayList<OSSObjectSummary>();
  192. // 递归列出fun目录下的所有文件
  193. do {
  194. ListObjectsRequest listObjectsRequest = new ListObjectsRequest(getBucket(bucket.getBucketName()));
  195. listObjectsRequest.setPrefix(prefix);
  196. listObjectsRequest.withMarker(nextMarker).withMaxKeys(maxKeys);
  197. objectListing = getOssClient().listObjects(listObjectsRequest);
  198. List<OSSObjectSummary> temp = objectListing.getObjectSummaries();
  199. if (temp != null) {
  200. sums.addAll(temp);
  201. }
  202. nextMarker = objectListing.getNextMarker();
  203. } while (objectListing.isTruncated());
  204. return sums;
  205. }
  206. /**
  207. * (判断是否存在文件)<BR>
  208. * 方法名:isExist<BR>
  209. * 创建人:陈海 <BR>
  210. * 时间:2016年11月21日-下午3:54:36 <BR>
  211. *
  212. * @param bucket
  213. * @param key
  214. * @param type
  215. * @return boolean<BR>
  216. * @throws <BR>
  217. * @since 1.0.0
  218. */
  219. public static boolean isExist(EnumPrivateBuckets bucket, String key, EnumFileType type) {
  220. String fullKey = getProjectName() + "/" + type.getLocation() + key;
  221. return getOssClient().doesObjectExist(getBucket(bucket.getBucketName()), fullKey);
  222. }
  223. public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
  224. public static final String STS_API_VERSION = "2015-04-01";
  225. public static AssumeRoleResponse getTempUserToken(long durationSeconds, Integer uid)
  226. throws com.aliyuncs.exceptions.ClientException {
  227. // 只有 RAM用户(子账号)才能调用 AssumeRole 接口
  228. // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
  229. // 请首先在RAM控制台创建一个RAM用户,并为这个用户创建AccessKeys
  230. String accessKeyId = "LTAIQLkVvDFXRO7j";
  231. String accessKeySecret = "aOnxO0xyoa0lDmTxTI1cNmVLNotF15";
  232. // RoleArn 需要在 RAM 控制台上获取
  233. String roleArn = "acs:ram::1894469520484605:role/aliyunosstokengeneratorrole";
  234. String policy = JSONObject.toJSONString(AliOssFileTool.getPolicyDetail());
  235. // RoleSessionName 是临时Token的会话名称,自己指定用于标识你的用户,主要用于审计,或者用于区分Token颁发给谁
  236. // 但是注意RoleSessionName的长度和规则,不要有空格,只能有'-' '_' 字母和数字等字符
  237. // 具体规则请参考API文档中的格式要求
  238. String roleSessionName = "uid_" + uid;
  239. // 此处必须为 HTTPS
  240. ProtocolType protocolType = ProtocolType.HTTPS;
  241. try {
  242. final AssumeRoleResponse stsResponse = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName,
  243. policy, protocolType, durationSeconds);
  244. return stsResponse;
  245. /*
  246. * Map<String, String> respMap = new LinkedHashMap<String, String>();
  247. * respMap.put("status", "200"); respMap.put("AccessKeyId",
  248. * stsResponse.getCredentials().getAccessKeyId());
  249. * respMap.put("AccessKeySecret",
  250. * stsResponse.getCredentials().getAccessKeySecret());
  251. * respMap.put("SecurityToken",
  252. * stsResponse.getCredentials().getSecurityToken()); respMap.put("Expiration",
  253. * stsResponse.getCredentials().getExpiration());
  254. */
  255. } catch (ClientException e) {
  256. throw e;
  257. }
  258. }
  259. protected static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn,
  260. String roleSessionName, String policy, ProtocolType protocolType, long durationSeconds)
  261. throws com.aliyuncs.exceptions.ClientException {
  262. try {
  263. // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
  264. IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
  265. DefaultAcsClient client = new DefaultAcsClient(profile);
  266. // 创建一个 AssumeRoleRequest 并设置请求参数
  267. final AssumeRoleRequest request = new AssumeRoleRequest();
  268. request.setVersion(STS_API_VERSION);
  269. request.setMethod(MethodType.POST);
  270. request.setProtocol(protocolType);
  271. request.setRoleArn(roleArn);
  272. request.setRoleSessionName(roleSessionName);
  273. request.setPolicy(policy);
  274. request.setDurationSeconds(durationSeconds);
  275. // 发起请求,并得到response
  276. final AssumeRoleResponse response = client.getAcsResponse(request);
  277. return response;
  278. } catch (com.aliyuncs.exceptions.ClientException e) {
  279. throw e;
  280. }
  281. }
  282. /**
  283. * (判断是否存在文件)<BR>
  284. * 方法名:isExist<BR>
  285. * 创建人:陈海 <BR>
  286. * 时间:2016年11月21日-下午3:54:36 <BR>
  287. *
  288. * @param bucket
  289. * @param key
  290. * @param type
  291. * @return boolean<BR>
  292. * @throws <BR>
  293. * @since 1.0.0
  294. */
  295. @Deprecated
  296. public boolean isExist(EnumPublicBuckets bucket, String key, EnumFileType type) {
  297. String fullKey = getProjectName() + "/" + type.getLocation() + key;
  298. return getOssClient().doesObjectExist(getBucket(bucket.getBucketName()), fullKey);
  299. }
  300. /**
  301. * (用bucket名称和完整key 判断文件是否存在)<BR>
  302. * 方法名:isExist<BR>
  303. * 创建人:陈海 <BR>
  304. * 时间:2017年5月12日-下午6:38:49 <BR>
  305. *
  306. * @param bucket
  307. * @param fullKey
  308. * @return boolean<BR>
  309. * @throws <BR>
  310. * @since 1.0.0
  311. */
  312. public static boolean isExist(String bucket, String fullKey) {
  313. return getOssClient().doesObjectExist(bucket, fullKey);
  314. }
  315. /**
  316. * 文件是否存在 内网
  317. *
  318. * @param bucket
  319. * @param fullKey
  320. * @return
  321. */
  322. public static boolean isExistOfInternal(String bucket, String fullKey) {
  323. return getInternalOssClient().doesObjectExist(bucket, fullKey);
  324. }
  325. /**
  326. * (删除oss文件)<BR>
  327. * 方法名:delFile<BR>
  328. * 创建人:陈海 <BR>
  329. * 时间:2016年7月20日-上午10:44:52 <BR>
  330. *
  331. * @param bucket 存储空间名称
  332. * @param key 文件保存在服务器上的另存名
  333. * @param type 枚举文件类型,声音或图片等
  334. * @return boolean<BR>
  335. * @throws <BR>
  336. * @since 1.0.0
  337. */
  338. public static boolean delFile(EnumAllBuckets bucket, String key, EnumFileType type) {
  339. getOssClient().deleteObject(getBucket(bucket.getBucketName()),
  340. getProjectName() + "/" + type.getLocation() + key);
  341. return true;
  342. }
  343. public static boolean deleteObject(String bucketName, String objectKey) {
  344. getInternalOssClient().deleteObject(bucketName, objectKey);
  345. return true;
  346. }
  347. public static boolean deleteObjects(String bucketName, List<String> objectKeys) {
  348. if (objectKeys == null || objectKeys.size() == 0) {
  349. return false;
  350. }
  351. DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName);
  352. deleteObjectsRequest.setKeys(objectKeys);
  353. deleteObjectsRequest.setQuiet(true);
  354. getInternalOssClient().deleteObjects(deleteObjectsRequest);
  355. return true;
  356. }
  357. /**
  358. * (获取经处理的图片签名url)<BR>
  359. * 方法名:getPicUrlWithSign<BR>
  360. * 创建人:陈海 <BR>
  361. * 时间:2016年7月18日-下午1:07:23 <BR>
  362. *
  363. * @param bucket 空间名称
  364. * @param key 文件保存在服务器上的名称
  365. * @param type 枚举文件类型,声音或图片等
  366. * @return String<BR>
  367. * @throws <BR>
  368. * @since 1.0.0
  369. */
  370. public static String getPicUrl(EnumPrivateBuckets bucket, String key, EnumFileType type, Long expiresSec) {
  371. if (expiresSec == null) {
  372. expiresSec = getExpiration();
  373. }
  374. Date expires = new Date(new Date().getTime() + getExpiration() * 1000);
  375. String picUrl = getPriClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
  376. getProjectName() + "/" + type.getLocation() + key, expires).toString();
  377. return picUrl;
  378. }
  379. /**
  380. * (获取文件对象的签名url)<BR>
  381. * 方法名:getUrlWithSign<BR>
  382. * 创建人:陈海 <BR>
  383. * 时间:2016年7月18日-下午1:05:50 <BR>
  384. *
  385. * @param bucket 空间名称
  386. * @param key 文件保存在服务器上的名称
  387. * @param type 枚举文件类型,声音或图片等
  388. * @return String<BR>
  389. * @throws <BR>
  390. * @since 1.0.0
  391. */
  392. public static String getUrl(EnumPrivateBuckets bucket, String key, EnumFileType type, Long expiresSec) {
  393. if (expiresSec == null) {
  394. expiresSec = getExpiration();
  395. }
  396. Date expires = new Date(new Date().getTime() + expiresSec * 1000);
  397. String url = "";
  398. if (type.equals(EnumFileType.VIDEO)) {
  399. url = getVideoClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
  400. getProjectName() + "/" + type.getLocation() + key, expires).toString();
  401. } else {
  402. url = getPriClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
  403. getProjectName() + "/" + type.getLocation() + key, expires).toString();
  404. }
  405. return url;
  406. }
  407. public static String getUrlWithOssEndPoint(EnumPrivateBuckets bucket, String key, EnumFileType type,
  408. Long expiresSec) {
  409. if (expiresSec == null) {
  410. expiresSec = getExpiration();
  411. }
  412. Date expires = new Date(new Date().getTime() + expiresSec * 1000);
  413. return getOssClient().generatePresignedUrl(getBucket(bucket.getBucketName()),
  414. getProjectName() + "/" + type.getLocation() + key, expires).toString();
  415. }
  416. /**
  417. * (获取object)<BR>
  418. * 方法名:getObject<BR>
  419. * 创建人:陈海 <BR>
  420. * 时间:2016年12月28日-上午10:55:43 <BR>
  421. *
  422. * @param bucket
  423. * @param key
  424. * @param type
  425. * @return OSSObject<BR>
  426. * @throws <BR>
  427. * @since 1.0.0
  428. */
  429. public static OSSObject getObject(EnumPrivateBuckets bucket, String key, EnumFileType type) {
  430. OSSObject ossObject = getOssClient().getObject(getBucket(bucket.getBucketName()),
  431. getProjectName() + "/" + type.getLocation() + key);
  432. return ossObject;
  433. }
  434. public static OSSObject getPubObject(EnumAllBuckets bucket, String key, EnumFileType type) {
  435. OSSObject ossObject = getOssClient().getObject(getBucket(bucket.getBucketName()),
  436. getProjectName() + "/" + type.getLocation() + key);
  437. return ossObject;
  438. }
  439. public static OSSObject getPubObject(String bucketName, String fullKey) {
  440. OSSObject ossObject = getOssClient().getObject(bucketName, fullKey);
  441. return ossObject;
  442. }
  443. public static OSSObject getInternalPubObject(String bucketName, String fullKey) {
  444. OSSObject ossObject = getInternalOssClient().getObject(bucketName, fullKey);
  445. return ossObject;
  446. }
  447. public static ObjectMetadata getPubObjectMedeta(EnumAllBuckets bucket, String key, EnumFileType type) {
  448. ObjectMetadata ossObjectMeta = getOssClient().getObjectMetadata(getBucket(bucket.getBucketName()),
  449. getProjectName() + "/" + type.getLocation() + key);
  450. return ossObjectMeta;
  451. }
  452. public static String calcFileMD5(String bucketName, String objectKey) {
  453. try {
  454. OSSObject ossObj = getOssClient().getObject(bucketName, objectKey);
  455. MessageDigest md = MessageDigest.getInstance("MD5");
  456. try (DigestInputStream digestInputStream = new DigestInputStream(ossObj.getObjectContent(), md)) {
  457. // 读取数据流并更新 MD5
  458. byte[] buffer = new byte[8192];
  459. while (digestInputStream.read(buffer) != -1) {
  460. // DigestInputStream 会自动更新 MessageDigest
  461. }
  462. } catch (Exception e) {
  463. logger.info("读取oss文件异常: ", e);
  464. return "";
  465. }
  466. // 获取最终的 MD5 值
  467. byte[] md5Bytes = md.digest();
  468. // 转换为十六进制字符串
  469. StringBuilder sb = new StringBuilder();
  470. for (byte b : md5Bytes) {
  471. sb.append(String.format("%02x", b));
  472. }
  473. String md5 = sb.toString();
  474. logger.info(String.format("buketName: %s, objectKey: %s, MD5: %s", bucketName, objectKey, md5));
  475. return md5;
  476. } catch (Exception e) {
  477. logger.error("计算文件MD5异常: ", e);
  478. }
  479. return "";
  480. }
  481. /**
  482. * (重命名文件,实现是先拷贝文件,再删掉旧的文件)<BR>
  483. * 方法名:renameFile<BR>
  484. * 创建人:陈海 <BR>
  485. * 时间:2016年8月1日-下午4:03:09 <BR>
  486. *
  487. * @param srcBucket
  488. * @param srckey
  489. * @param destkey
  490. * @return boolean<BR>
  491. * @throws <BR>
  492. * @since 1.0.0
  493. */
  494. @Deprecated
  495. public boolean renameFile(EnumAllBuckets srcBucket, String srckey, String destkey, EnumFileType srcType,
  496. EnumFileType destType) {
  497. // 拷贝Object
  498. getOssClient().copyObject(getBucket(srcBucket.getBucketName()),
  499. getProjectName() + "/" + srcType.getLocation() + srckey, getBucket(srcBucket.getBucketName()),
  500. getProjectName() + "/" + destType.getLocation() + destkey);
  501. delFile(srcBucket, srckey, srcType);
  502. return true;
  503. }
  504. /**
  505. * (将oss srckey 命名为 destkey)<BR>
  506. * 方法名:renameFileWithFullKey<BR>
  507. * 创建人:陈海 <BR>
  508. * 时间:2017年9月16日-下午5:24:39 <BR>
  509. *
  510. * @param srcBucket
  511. * @param srckey
  512. * @param destkey
  513. * @return boolean<BR>
  514. * @throws <BR>
  515. * @since 1.0.0
  516. */
  517. public static boolean renameFileWithFullKey(EnumAllBuckets srcBucket, String srckey, String destkey) {
  518. // 拷贝Object
  519. getOssClient().copyObject(getBucket(srcBucket.getBucketName()), srckey, getBucket(srcBucket.getBucketName()),
  520. destkey);
  521. getOssClient().deleteObject(getBucket(srcBucket.getBucketName()), srckey);
  522. return true;
  523. }
  524. public static boolean renameFileWithFullKeyFromInternal(EnumAllBuckets srcBucket, String srckey, String destkey, long size) {
  525. // 拷贝Object
  526. if (size < 1024 * 1024 * 1024) {
  527. getInternalOssClient().copyObject(getBucket(srcBucket.getBucketName()), srckey,
  528. getBucket(srcBucket.getBucketName()), destkey);
  529. } else {
  530. multipartCopyObjectFromInternal(getBucket(srcBucket.getBucketName()), srckey,
  531. getBucket(srcBucket.getBucketName()), destkey);
  532. }
  533. getInternalOssClient().deleteObject(getBucket(srcBucket.getBucketName()), srckey);
  534. return true;
  535. }
  536. // 分片拷贝object,大于1G的文件需要分片拷贝
  537. public static void multipartCopyObjectFromInternal(String sourceBucketName, String sourceObjectName,
  538. String destinationBucketName, String destinationObjectName) {
  539. OSSClient ossClient = getInternalOssClient();
  540. ObjectMetadata objectMetadata = ossClient.getObjectMetadata(sourceBucketName, sourceObjectName);
  541. // 获取被拷贝文件的大小。
  542. long contentLength = objectMetadata.getContentLength();
  543. // 设置分片大小为10MB。
  544. long partSize = 1024 * 1024 * 10;
  545. // 计算分片总数。
  546. int partCount = (int) (contentLength / partSize);
  547. if (contentLength % partSize != 0) {
  548. partCount++;
  549. }
  550. logger.info("oss 分片拷贝开始,sourceObjectName:" + sourceObjectName + ",size:" + contentLength + ",partCount:" + partCount);
  551. // 初始化拷贝任务。可以通过InitiateMultipartUploadRequest指定目标文件元信息。
  552. InitiateMultipartUploadRequest initiateMultipartUploadRequest = new InitiateMultipartUploadRequest(
  553. destinationBucketName, destinationObjectName);
  554. InitiateMultipartUploadResult initiateMultipartUploadResult = ossClient
  555. .initiateMultipartUpload(initiateMultipartUploadRequest);
  556. String uploadId = initiateMultipartUploadResult.getUploadId();
  557. // 分片拷贝。
  558. List<PartETag> partETags = new ArrayList<PartETag>();
  559. for (int i = 0; i < partCount; i++) {
  560. // 计算每个分片的大小。
  561. long skipBytes = partSize * i;
  562. long size = partSize < contentLength - skipBytes ? partSize : contentLength - skipBytes;
  563. // 创建UploadPartCopyRequest。可以通过UploadPartCopyRequest指定限定条件。
  564. UploadPartCopyRequest uploadPartCopyRequest = new UploadPartCopyRequest(sourceBucketName, sourceObjectName,
  565. destinationBucketName, destinationObjectName);
  566. uploadPartCopyRequest.setUploadId(uploadId);
  567. uploadPartCopyRequest.setPartSize(size);
  568. uploadPartCopyRequest.setBeginIndex(skipBytes);
  569. uploadPartCopyRequest.setPartNumber(i + 1);
  570. UploadPartCopyResult uploadPartCopyResult = ossClient.uploadPartCopy(uploadPartCopyRequest);
  571. // 将返回的分片ETag保存到partETags中。
  572. partETags.add(uploadPartCopyResult.getPartETag());
  573. }
  574. // 提交分片拷贝任务。
  575. CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(
  576. destinationBucketName, destinationObjectName, uploadId, partETags);
  577. ossClient.completeMultipartUpload(completeMultipartUploadRequest);
  578. logger.info("oss 分片拷贝结束,sourceObjectName:" + sourceObjectName + ",size:" + contentLength + ",partCount:" + partCount);
  579. }
  580. public static void copyObject(String srcBucketName, String srcObjectKey,
  581. String destBucketName, String destObjectKey) {
  582. getOssClient().copyObject(srcBucketName, srcObjectKey, destBucketName, destObjectKey);
  583. }
  584. public static void copyObjectFromInternal(String srcBucketName, String srcObjectKey,
  585. String destBucketName, String destObjectKey) {
  586. getInternalOssClient().copyObject(srcBucketName, srcObjectKey, destBucketName, destObjectKey);
  587. }
  588. private static InputStream compressImg(InputStream stream, EnumFileSuffix suffix, EnumFileType fileType) {
  589. if (!getNeedPress()) {
  590. return stream;
  591. }
  592. if (suffix == EnumFileSuffix.JPG || suffix == EnumFileSuffix.PNG || suffix == EnumFileSuffix.JPEG
  593. || suffix == EnumFileSuffix.BMP) {
  594. try {
  595. byte[] file = CompressImage.compress(stream, 1080);
  596. if (file != null) {
  597. stream = new ByteArrayInputStream(file);
  598. } else {
  599. logger.warn("图片上传有误");
  600. return null;
  601. }
  602. } catch (Exception e) {
  603. logger.error("图片压缩失败", e);
  604. if (null != stream) {
  605. try {
  606. stream.close();
  607. } catch (IOException e1) {
  608. }
  609. }
  610. throw new CommonsException(EnumErrorException.PIC_FORMAT_ERROR);
  611. }
  612. }
  613. return stream;
  614. }
  615. public static String submitPubTranscodeJob(EnumPublicBuckets inputBucket, EnumAllBuckets outputBucket,
  616. String fullKey, String outPutKey, String templateId) {
  617. OSSFileDO inputFile = new OSSFileDO(OSS_REGION, getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName()),
  618. fullKey);
  619. JSONArray outputs = new JSONArray();
  620. JSONObject outPutConfig = new JSONObject();
  621. outPutConfig.put("OutputObject", outPutKey);
  622. outPutConfig.put("TemplateId", templateId);
  623. outputs.add(outPutConfig);
  624. SubmitJobsRequest request = new SubmitJobsRequest();
  625. request.setInput(inputFile.toJsonString());
  626. request.setOutputs(outputs.toJSONString());
  627. request.setPipelineId(PIPELINEID);
  628. request.setOutputBucket(getBucket(outputBucket.getBucketName()));
  629. request.setOutputLocation(OSS_REGION);
  630. Integer outputJobCount = 1;
  631. SubmitJobsResponse response = null;
  632. try {
  633. response = getDefaultAcsClient().getAcsResponse(request);
  634. if (response.getJobResultList().size() != outputJobCount) {
  635. throw new RuntimeException("SubmitJobsRequest Size failed");
  636. }
  637. return response.getJobResultList().get(0).getJob().getJobId();
  638. } catch (ServerException e) {
  639. logger.error("submitTranscodeJob Server failed", e);
  640. throw new CommonsException(EnumErrorException.TRANS_CODE_SERVER_ERROR);
  641. } catch (com.aliyuncs.exceptions.ClientException e) {
  642. logger.error("submitTranscodeJob Client failed", e);
  643. throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR);
  644. }
  645. }
  646. public static String getPubPicAverageColor(EnumAllBuckets bucket, String key) {
  647. String style = "image/average-hue";
  648. try {
  649. GetObjectRequest request = new GetObjectRequest(getBucket(bucket.getBucketName()), key);
  650. request.setProcess(style);
  651. OSSObject obj = getOssClient().getObject(request);
  652. if (obj != null) {
  653. String a = IOUtils.toString(obj.getObjectContent());
  654. JSONObject jo = (JSONObject) JSONObject.parse(a);
  655. String rgb = jo.getString("RGB");
  656. if (rgb != null) {
  657. rgb = rgb.replace("0x", "#");
  658. }
  659. return rgb;
  660. }
  661. } catch (Exception e) {
  662. throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR);
  663. }
  664. return null;
  665. }
  666. public static Properties getPubObjMediaInfoData(String bucketName, String fullKey) {
  667. DefaultAcsClient client = getDefaultAcsClient();
  668. SubmitMediaInfoJobRequest request = new SubmitMediaInfoJobRequest();
  669. request.setReadTimeout(Integer.MAX_VALUE);
  670. SubmitMediaInfoJobResponse response = new SubmitMediaInfoJobResponse();
  671. JSONObject json = new JSONObject();
  672. json.put("Location", "oss-cn-hangzhou");
  673. json.put("Bucket", bucketName);
  674. json.put("Object", fullKey);
  675. request.setInput(json.toJSONString());
  676. try {
  677. response = client.getAcsResponse(request);
  678. // String width = response.getMediaInfoJob().getProperties().getWidth();
  679. // String height = response.getMediaInfoJob().getProperties().getHeight();
  680. return response.getMediaInfoJob().getProperties();
  681. } catch (Exception e) {
  682. throw new CommonsException(EnumErrorException.TRANS_CODE_CLIENT_ERROR, e);
  683. }
  684. }
  685. public static SignatureVO getUploadPolicy(Integer fileType) throws Exception {
  686. // 后台随机生成唯一文件名
  687. String env = PropertiesUtils.getProjectEnv();
  688. if (StringUtils.isEmpty(env)) {
  689. env = "qa";
  690. }
  691. String fileName = RandomUtil.generate18String();
  692. String contentType = "";
  693. if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) {
  694. fileName = "/video/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
  695. } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) {
  696. fileName = "/voice/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
  697. } else {
  698. fileName = "/pic/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
  699. }
  700. long expireTime = 60 * 60 * 4;
  701. long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
  702. Date expiration = new Date(expireEndTime);
  703. PolicyConditions policyConds = new PolicyConditions();
  704. //4.95G 上限是5个G
  705. policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 5261334938l);
  706. policyConds.addConditionItem(MatchMode.Exact, PolicyConditions.COND_KEY,
  707. AliOssConfig.getProjectName() + fileName);
  708. if (!StringUtils.isEmpty(contentType)) {
  709. policyConds.addConditionItem(PolicyConditions.COND_CONTENT_TYPE, contentType);
  710. }
  711. String postPolicy = AliOssConfig.getOssClient().generatePostPolicy(expiration, policyConds);
  712. byte[] binaryData = postPolicy.getBytes("utf-8");
  713. String encodedPolicy = BinaryUtil.toBase64String(binaryData);
  714. String postSignature = AliOssConfig.getOssClient().calculatePostSignature(postPolicy);
  715. SignatureVO signatureVO = new SignatureVO();
  716. signatureVO.setAccessId(AliOssConfig.getAccessKeyId());
  717. signatureVO.setPolicy(encodedPolicy);
  718. signatureVO.setSignature(postSignature);
  719. signatureVO.setFileName(AliOssConfig.getProjectName() + fileName);
  720. signatureVO.setHost(AliOssConfig.getUploadDomain());
  721. signatureVO.setExpire(String.valueOf(expireEndTime / 1000));
  722. return signatureVO;
  723. }
  724. public static String getSignaturedUrl(String fileName, Boolean isPrivate) {
  725. if (StringUtils.isBlank(fileName)) {
  726. return fileName;
  727. }
  728. if (StringUtils.startsWith(fileName, "https")) {
  729. return fileName;
  730. }
  731. String host = AliOssConfig.getVideoDomain();
  732. fileName = host + fileName;
  733. return fileName;
  734. }
  735. public static String getSignaturedInternalUrl(String fileName, Boolean isPrivate) throws Exception {
  736. if (StringUtils.isBlank(fileName)) {
  737. return fileName;
  738. }
  739. if (StringUtils.startsWith(fileName, "https")) {
  740. return fileName;
  741. }
  742. String bucket = getBucket(isPrivate);
  743. String host = "http://" + bucket + "." + AliOssConfig.getInternalEndPoint();
  744. fileName = host + "/" + fileName;
  745. return fileName;
  746. }
  747. public static String saveVideoCoverImagFromInternal(File file, Integer fileType, Boolean isPrivate, Long videoId)
  748. throws Exception {
  749. Date begin = new Date();
  750. logger.info(String.format("开始往阿里云OSS上传封面图片,当前时间为:%s", begin.getTime()));
  751. String bucketName = getBucket(isPrivate);
  752. String fullKey = getVideoCoverImagPath(fileType, isPrivate, videoId.toString(), null);
  753. AliOssConfig.getInternalOssClient().putObject(bucketName, fullKey, file);
  754. Date end = new Date();
  755. logger.info(String.format("阿里云OSS上传封面图片完成,总耗时为 %s 毫秒。图片地址为:%s, 正在执行下一步。。", end.getTime() - begin.getTime(),
  756. fullKey));
  757. return fullKey;
  758. }
  759. public static String saveVideoCoverImagFromInternal(InputStream input, Integer fileType, Boolean isPrivate,
  760. String filePrex, String dic) throws Exception {
  761. Date begin = new Date();
  762. logger.info(String.format("开始往阿里云OSS上传图片,当前时间为:%s", begin.getTime()));
  763. String bucketName = getBucket(isPrivate);
  764. String fullKey = getVideoCoverImagPath(fileType, isPrivate, filePrex, dic);
  765. // AliOssConfig.getOssClient().putObject(bucketName, fullKey, file);
  766. AliOssConfig.getInternalOssClient().putObject(bucketName, fullKey, input);
  767. Date end = new Date();
  768. logger.info(
  769. String.format("阿里云OSS上传图片完成,总耗时为 %s 毫秒。图片地址为:%s, 正在执行下一步。。", end.getTime() - begin.getTime(), fullKey));
  770. return fullKey;
  771. }
  772. public static String getVideoCoverImagPath(Integer fileType, Boolean isPrivate, String filePrex, String dic)
  773. throws Exception {
  774. String fileName = UUID.randomUUID().toString().replaceAll("-", "") + Calendar.getInstance().getTimeInMillis()
  775. + "_" + filePrex;
  776. if (StringUtils.isNotBlank(dic)) {
  777. fileName = (dic + "/" + fileName);
  778. }
  779. if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) {
  780. fileName = "/video/" + fileName;
  781. } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) {
  782. fileName = "/voice/" + fileName;
  783. } else {
  784. fileName = "/pic/" + fileName;
  785. }
  786. String fullKey = AliOssConfig.getProjectName() + fileName;
  787. return fullKey;
  788. }
  789. public static String getBucket(boolean isPrivate) {
  790. if (isPrivate) {
  791. return AliOssFileTool.getBucket(EnumAllBuckets.PRIVIDEOBUCKET.getBucketName());
  792. } else {
  793. return AliOssFileTool.getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName());
  794. }
  795. }
  796. public static ObjectMetadata getObjectMetadata(String fileName) throws Exception {
  797. // Endpoint以杭州为例,其它Region请按实际情况填写。
  798. // 创建OSSClient实例。
  799. OSSClient ossClient = new OSSClient(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(),
  800. AliOssConfig.getAccessKeySecret());
  801. // // 获取文件的部分元信息。
  802. // SimplifiedObjectMeta objectMeta = ossClient.getSimplifiedObjectMeta(
  803. // getBucket(false), fileName);
  804. // logger.info( "SimplifiedObjectMeta==="+ JSON.toJSONString(objectMeta));
  805. // 获取文件的全部元信息。
  806. ObjectMetadata metadata = ossClient.getObjectMetadata(getBucket(false), fileName);
  807. // logger.info( "metadata==="+ JSON.toJSONString(metadata));
  808. return metadata;
  809. }
  810. /**
  811. * 获取部分元信息
  812. *
  813. * @param bucketName
  814. * @param fileName
  815. * @return
  816. * @throws Exception
  817. */
  818. public static SimplifiedObjectMeta getSimpleObjectMetadata(String bucketName, String fileName) throws Exception {
  819. OSS ossClient = new OSSClientBuilder().build(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(),
  820. AliOssConfig.getAccessKeySecret());
  821. SimplifiedObjectMeta metadata = ossClient.getSimplifiedObjectMeta(bucketName, fileName);
  822. ossClient.shutdown();
  823. return metadata;
  824. }
  825. /**
  826. * 获取全部元信息
  827. *
  828. * @param bucketName
  829. * @param fileName
  830. * @return
  831. * @throws Exception
  832. */
  833. public static ObjectMetadata getObjectMetadata(String bucketName, String fileName) throws Exception {
  834. // OSS ossClient = new OSSClientBuilder().build(AliOssConfig.getInternalEndPoint(), AliOssConfig.getAccessKeyId(),
  835. // AliOssConfig.getAccessKeySecret());
  836. // // 获取文件的全部元信息
  837. // ObjectMetadata metadata = ossClient.getObjectMetadata(bucketName, fileName);
  838. // ossClient.shutdown();
  839. // return metadata;
  840. ObjectMetadata metadata = getInternalOssClient().getObjectMetadata(bucketName, fileName);
  841. return metadata;
  842. }
  843. // public static void main(String[] args) throws Exception {
  844. //// String a = JSONObject.toJSONString(AliOssFileTool.getDefaultAcsClient());
  845. //// System.out.println(a);
  846. // }
  847. public static Map<String, String> buildCommonParameters() {
  848. Map<String, String> parameterMap = new HashMap<>();
  849. // 请求公共参数
  850. parameterMap.put("Version", "2014-06-18");
  851. parameterMap.put("AccessKeyId", AliOssConfig.getAccessKeyId()); // 此处请替换成您自己的AccessKeyId
  852. // parameterMap.put("Timestamp",
  853. // "2018-07-27T13:03:45Z");//此处将时间戳固定只是测试需要,这样此示例中生成的签名值就不会变,方便您对比验证,可变时间戳的生成需要用下边这句替换
  854. parameterMap.put("Timestamp", DateUtils.formatIso8601Date(new Date()));
  855. parameterMap.put("SignatureMethod", "HMAC-SHA1");
  856. parameterMap.put("SignatureVersion", "1.0");
  857. // parameterMap.put("SignatureNonce", "4902260a-516a-4b6a-a455-45b653cf6150");
  858. // //此处将唯一随机数固定只是测试需要,这样此示例中生成的签名值就不会变,方便您对比验证,可变唯一随机数的生成需要用下边这句替换
  859. parameterMap.put("SignatureNonce", UUID.randomUUID().toString());
  860. parameterMap.put("Format", "JSON"); // 另外支持JSON格式
  861. return parameterMap;
  862. }
  863. /**
  864. * @Title: sendAsyncSnapshotJob @Description: 获取发送视频批量截图的任务的URL,此接口为异步任务 @param
  865. * fileName 要截图的视频的路径,如 longvideo/video/XXXXX,其中XXXXX为视频名称 @param
  866. * snapshotPath 截图后的图片输出路径,如
  867. * longvideo/snapshot/XXXXX,截图时会自动在文件名后面加序号,输出路径为空时,自动指定为longvideo/snapshot/XXXXX @param
  868. * startMillseconds 截图时间,单位毫秒 @param interval
  869. * 截图间隔时间,若指定则表示异步模式序列截图,Interval必须大于等于0,默认10,单位秒。其中Interval=0表示根据视频时长平均截图。 @param
  870. * snapshotNumber
  871. * 截图数量,若指定则表示异步模式序列截图,且必须大于0,当Time+Interval*Num的截取点超过视频时长时,后续截图自动失效,截图完成时返回实际截取的个数;当Num=1,忽略Interval参数,表示异步单张截图 @return @throws
  872. * Exception @author 王树杞 @date 2018年7月27日 下午5:17:31 @version 2.0 @throws
  873. */
  874. public static String sendAsyncSnapshotJob(String fileName, String snapshotPath, Integer startMillseconds,
  875. Integer interval, Integer snapshotNumber) throws Exception {
  876. // 首先获取公众参数
  877. Map<String, String> parameterMap = buildCommonParameters();
  878. parameterMap.put("Action", "SubmitSnapshotJob");
  879. Map<String, String> inputParamsMap = new HashMap<>();
  880. inputParamsMap.put("Bucket", AliOssFileTool.getBucket(false));
  881. inputParamsMap.put("Location", AliOssFileTool.getSnapshotLocation());
  882. inputParamsMap.put("Object", URLEncoder.encode(fileName, "UTF-8"));
  883. parameterMap.put("Input", JSON.toJSONString(inputParamsMap));
  884. Map<String, String> snapshotConfig = new HashMap<>();
  885. Map<String, String> outPutFile = new HashMap<>();
  886. outPutFile.put("Bucket", AliOssFileTool.getBucket(false));
  887. outPutFile.put("Location", AliOssFileTool.getSnapshotLocation());
  888. if (StringUtils.isBlank(snapshotPath)) {
  889. snapshotPath = fileName.replace("/video/", "/snapshot/");
  890. }
  891. outPutFile.put("Object", URLEncoder.encode(snapshotPath + "_{Count}", "UTF-8"));
  892. snapshotConfig.put("Interval", interval.toString());
  893. snapshotConfig.put("Num", snapshotNumber.toString());
  894. parameterMap.put("PipelineId", "abe6a0b9b9334858913eb416974485d2");
  895. snapshotConfig.put("OutputFile", JSON.toJSONString(outPutFile));
  896. parameterMap.put("SnapshotConfig", JSON.toJSONString(snapshotConfig));
  897. String canonicalizedQueryString = buildCanonicalizedQueryString(parameterMap);
  898. String stringToSign = buildStringToSign(canonicalizedQueryString);
  899. String signature = buildSignature(AliOssConfig.getAccessKeySecret(), stringToSign);
  900. return buildRequestURL(signature, parameterMap);
  901. }
  902. /**
  903. * @Title: sendSyncSnapshotJob @Description: 获取发送某个视频的同步截图的任务URL地址 @param
  904. * fileName 视频路径 @param snapshotPath 输出的截图路径 @param startMillseconds
  905. * 截图的时间戳 @return 某个视频的同步截图的任务URL地址 @throws Exception @author 王树杞 @date
  906. * 2018年7月27日 下午8:07:47 @version 2.0 @throws
  907. */
  908. public static String sendSyncSnapshotJob(String fileName, String snapshotPath, Integer startMillseconds)
  909. throws Exception {
  910. // 首先获取公众参数
  911. Map<String, String> parameterMap = buildCommonParameters();
  912. parameterMap.put("Action", "SubmitSnapshotJob");
  913. Map<String, String> inputParamsMap = new HashMap<>();
  914. inputParamsMap.put("Bucket", AliOssFileTool.getBucket(false));
  915. inputParamsMap.put("Location", AliOssFileTool.getSnapshotLocation());
  916. inputParamsMap.put("Object", URLEncoder.encode(fileName, "UTF-8"));
  917. parameterMap.put("Input", JSON.toJSONString(inputParamsMap));
  918. Map<String, String> snapshotConfig = new HashMap<>();
  919. Map<String, String> outPutFile = new HashMap<>();
  920. outPutFile.put("Bucket", AliOssFileTool.getBucket(false));
  921. outPutFile.put("Location", AliOssFileTool.getSnapshotLocation());
  922. if (StringUtils.isBlank(snapshotPath)) {
  923. snapshotPath = fileName.replace("/video/", "/snapshot/");
  924. }
  925. outPutFile.put("Object", URLEncoder.encode(snapshotPath, "UTF-8"));
  926. snapshotConfig.put("Time", startMillseconds.toString());
  927. snapshotConfig.put("OutputFile", JSON.toJSONString(outPutFile));
  928. parameterMap.put("SnapshotConfig", JSON.toJSONString(snapshotConfig));
  929. String canonicalizedQueryString = buildCanonicalizedQueryString(parameterMap);
  930. String stringToSign = buildStringToSign(canonicalizedQueryString);
  931. String signature = buildSignature(AliOssConfig.getAccessKeySecret(), stringToSign);
  932. return buildRequestURL(signature, parameterMap);
  933. }
  934. private static String percentEncode(String value) throws UnsupportedEncodingException {
  935. return URLEncoder.encode(value, ENCODE_TYPE).replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
  936. }
  937. private static String buildCanonicalizedQueryString(Map<String, String> parameterMap)
  938. throws UnsupportedEncodingException {
  939. // 对参数进行排序
  940. List<String> sortedKeys = new ArrayList<String>(parameterMap.keySet());
  941. Collections.sort(sortedKeys);
  942. StringBuilder temp = new StringBuilder();
  943. for (String key : sortedKeys) {
  944. // 此处需要对key和value进行编码
  945. String value = parameterMap.get(key);
  946. temp.append(SEPARATOR).append(percentEncode(key)).append(EQUAL).append(percentEncode(value));
  947. }
  948. return temp.toString().substring(1);
  949. }
  950. private static String buildStringToSign(String canonicalizedQueryString) throws UnsupportedEncodingException {
  951. // 生成stringToSign字符
  952. StringBuilder temp = new StringBuilder();
  953. temp.append(HTTP_METHOD).append(SEPARATOR);
  954. temp.append(percentEncode("/")).append(SEPARATOR);
  955. // 此处需要对canonicalizedQueryString进行编码
  956. temp.append(percentEncode(canonicalizedQueryString));
  957. return temp.toString();
  958. }
  959. private static String buildSignature(String keySecret, String stringToSign)
  960. throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
  961. SecretKey key = new SecretKeySpec((keySecret + SEPARATOR).getBytes(ENCODE_TYPE), SignatureMethod.HMAC_SHA1);
  962. Mac mac = Mac.getInstance(ALGORITHM);
  963. mac.init(key);
  964. byte[] hashBytes = mac.doFinal(stringToSign.toString().getBytes(ENCODE_TYPE));
  965. byte[] base64Bytes = new Base64().encode(hashBytes);
  966. String base64UTF8String = new String(base64Bytes, "utf-8");
  967. return URLEncoder.encode(base64UTF8String, ENCODE_TYPE);
  968. }
  969. private static String buildRequestURL(String signature, Map<String, String> parameterMap)
  970. throws UnsupportedEncodingException {
  971. // 生成请求URL
  972. StringBuilder temp = new StringBuilder("http://mts.cn-hangzhou.aliyuncs.com?");
  973. temp.append(URLEncoder.encode("Signature", ENCODE_TYPE)).append("=").append(signature);
  974. for (Map.Entry<String, String> e : parameterMap.entrySet()) {
  975. temp.append("&").append(percentEncode(e.getKey())).append("=").append(percentEncode(e.getValue()));
  976. }
  977. return temp.toString();
  978. }
  979. public static String saveInputStreamPic(InputStream inputStream, String bucket, String project, String dir,
  980. String key) throws OSSException, ClientException, IOException {
  981. String fullKey = project + "/" + dir + "/" + key;
  982. ObjectMetadata objectMetadata = new ObjectMetadata();
  983. objectMetadata.setContentType("image/jpg");
  984. getOssClient().putObject(bucket, fullKey, inputStream, objectMetadata);
  985. return fullKey;
  986. }
  987. public static String sendImageToAliOss(BufferedImage image) throws Exception {
  988. ByteArrayOutputStream os = new ByteArrayOutputStream();
  989. ImageIO.write(image, "jpg", os);
  990. InputStream is = new ByteArrayInputStream(os.toByteArray());
  991. // 将生成的图片往OSS里面上传
  992. String random = UUID.randomUUID().toString().replaceAll("-", "") + new Random().nextLong();
  993. String key = Md5Util.encoderByMd5(random);
  994. String coverImgPath = AliOssFileTool.saveVideoCoverImagFromInternal(is, key);
  995. return coverImgPath;
  996. }
  997. public static String saveVideoCoverImagFromInternal(InputStream inputStream, String key)
  998. throws OSSException, ClientException, IOException {
  999. String bucketName = AliOssConfig.getBucket(EnumAllBuckets.PUBVIDEOBUCKET.getBucketName());
  1000. String fullKey = getProjectName() + "/pic/video/cover/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/"
  1001. + key;
  1002. ObjectMetadata objectMetadata = new ObjectMetadata();
  1003. objectMetadata.setContentType("image/jpg");
  1004. getInternalOssClient().putObject(bucketName, fullKey, inputStream, objectMetadata);
  1005. return fullKey;
  1006. }
  1007. /**
  1008. * @param duration 时长,如果是图片则传0,视频则传视频时长
  1009. * @param isInternal 是否内网访问
  1010. * @return
  1011. * @return String
  1012. * @Title: generatePresignedUrl
  1013. * @Description:得到对象的临时访问URL
  1014. * @author 王树杞
  1015. * @date 2019年2月25日 上午11:04:22
  1016. * @version 2.0
  1017. */
  1018. public static String generatePresignedUrl(String filePath, Integer duration, boolean isInternal) {
  1019. if (StringUtils.isEmpty(filePath)) {
  1020. return null;
  1021. }
  1022. if (filePath.startsWith("http")) {
  1023. filePath = filePath.replace(PropertiesUtils.getDownloadDomain(), "");
  1024. filePath = filePath.replace("https://weappupload.piaoquantv.com/", "");
  1025. filePath = filePath.replace("https://testweappupload.yishihui.com/", "");
  1026. filePath = filePath.replace("https://lvupload.piaoquantv.com/", "");
  1027. }
  1028. if (filePath.contains("Signature") && filePath.contains("OSSAccessKeyId")) {
  1029. return filePath;
  1030. }
  1031. if (duration == null) {
  1032. duration = 0;
  1033. }
  1034. // 设置URL过期时间为视频时长+3天。
  1035. // 单位为秒;
  1036. Date expiration = new Date(new Date().getTime() + (duration + (3 * 24 * 60 * 60)) * 1000);
  1037. // //一分钟
  1038. // Date expiration = new Date(new Date().getTime() +( 60) * 1000);
  1039. // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
  1040. URL url = getOssReadOnlyClient().generatePresignedUrl(BasePropertiesUtils.getVideoBucket(),
  1041. filePath, expiration, HttpMethod.GET);
  1042. String path = url.getFile();
  1043. if (StringUtils.startsWith(path, "/")) {
  1044. return StringUtils.substring(path, 1);
  1045. }
  1046. return path;
  1047. }
  1048. public static String saveObjectFromInternal(InputStream inputStream, String fullKey)
  1049. throws OSSException, ClientException, IOException {
  1050. String bucketName = BasePropertiesUtils.getVideoBucket();
  1051. getInternalOssClient().putObject(bucketName, fullKey, inputStream);
  1052. return fullKey;
  1053. }
  1054. public static String saveObjectFromInternal(String bucketName, String url, String fullKey)
  1055. throws Exception {
  1056. InputStream inputStream = new URL(url).openStream();
  1057. getInternalOssClient().putObject(bucketName, fullKey, inputStream);
  1058. if (inputStream != null) {
  1059. inputStream.close();
  1060. }
  1061. return fullKey;
  1062. }
  1063. public static boolean checkObjectExistFromInternal(String bucketName, String fullKey) {
  1064. return getInternalOssClient().doesObjectExist(bucketName, fullKey);
  1065. }
  1066. public static String uploadShangHaiVideo(InputStream inputStream, String key, String bucketName) {
  1067. ObjectMetadata objectMetadata = new ObjectMetadata();
  1068. objectMetadata.setContentType("video/mp4");
  1069. getShangHaiInternalOssClient().putObject(bucketName, key, inputStream, objectMetadata);
  1070. return key;
  1071. }
  1072. public static boolean isShangHaiExist(String bucket, String fullKey) {
  1073. return getShangHaiInternalOssClient().doesObjectExist(bucket, fullKey);
  1074. }
  1075. public static Boolean isStorageClassArchive(String bucket, String key) throws OSSException, ClientException {
  1076. ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key);
  1077. StorageClass storageClass = objectMetadata.getObjectStorageClass();
  1078. return storageClass == StorageClass.Archive;
  1079. }
  1080. public static boolean isStorageClassColdArchive(String bucket, String key) throws OSSException, ClientException {
  1081. ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key);
  1082. StorageClass storageClass = objectMetadata.getObjectStorageClass();
  1083. return storageClass == StorageClass.ColdArchive;
  1084. }
  1085. public static void setStorageClassToArchive(String bucket, String key) throws OSSException, ClientException {
  1086. // 创建CopyObjectRequest对象。
  1087. CopyObjectRequest request = new CopyObjectRequest(bucket, key, bucket, key);
  1088. // 创建ObjectMetadata对象。
  1089. ObjectMetadata objectMetadata = new ObjectMetadata();
  1090. // 封装header,此处以设置存储类型为归档类型为例。
  1091. objectMetadata.setHeader("x-oss-storage-class", StorageClass.Archive);
  1092. request.setNewObjectMetadata(objectMetadata);
  1093. // 更改文件存储类型。
  1094. CopyObjectResult result = getInternalOssClient().copyObject(request);
  1095. }
  1096. public static void recoverVideoAsync(String bucket, String srckey) {
  1097. OSSClient ossInternalClient = getInternalOssClient();
  1098. ObjectMetadata objectMetadata = ossInternalClient.getObjectMetadata(bucket, srckey);
  1099. // 校验文件是否为归档文件。
  1100. StorageClass storageClass = objectMetadata.getObjectStorageClass();
  1101. if (storageClass == StorageClass.Archive) {
  1102. // 解冻文件。
  1103. try {
  1104. ossInternalClient.restoreObject(bucket, srckey);
  1105. } catch (Exception e) {
  1106. // OSS Auto-generated catch blockvideo-common/src/main/java/com/weiqu/video/common/enums/ExceptionCodeEnum.java
  1107. // e.printStackTrace();
  1108. logger.error("视频可能在解冻中");
  1109. }
  1110. } else if (storageClass == StorageClass.ColdArchive) {
  1111. // 解冻文件。
  1112. try {
  1113. RestoreJobParameters parameters = new RestoreJobParameters(RestoreTier.RESTORE_TIER_EXPEDITED);
  1114. RestoreConfiguration configuration = new RestoreConfiguration(3, parameters);
  1115. ossInternalClient.restoreObject(bucket, srckey, configuration);
  1116. } catch (Exception ex) {
  1117. logger.error("视频可能在解冻中", ex);
  1118. }
  1119. }
  1120. }
  1121. public static Boolean isRestoreCompleted(String bucket, String key) throws OSSException, ClientException {
  1122. ObjectMetadata objectMetadata = getInternalOssClient().getObjectMetadata(bucket, key);
  1123. Boolean isRestoreCompleted = false;
  1124. try {
  1125. isRestoreCompleted = objectMetadata.isRestoreCompleted();
  1126. } catch (Exception e) {
  1127. // OSS Auto-generated catch block
  1128. // e.printStackTrace();
  1129. logger.error("视频可能在解冻中");
  1130. }
  1131. return isRestoreCompleted;
  1132. }
  1133. /**
  1134. * @param path
  1135. * @param path
  1136. * @return
  1137. * @ApiModelProperty(value="冻结状态: -1:无须解冻 0:待解冻 1:解冻中 2:解冻完成")
  1138. */
  1139. public static Integer getFrozenStatus(String path) {
  1140. if (path.startsWith("http") && !path.startsWith(PropertiesUtils.getDownloadDomain())) {
  1141. logger.info("getFrozenStatus-outer size video, path :" + path);
  1142. return -1;
  1143. }
  1144. String realPath = path.replace(PropertiesUtils.getDownloadDomain(), "");
  1145. String bucketName = BasePropertiesUtils.getVideoBucket();
  1146. ObjectMetadata objectMetadata = null;
  1147. try {
  1148. objectMetadata = getInternalOssClient().getObjectMetadata(bucketName, realPath);
  1149. } catch (Exception ex) {
  1150. logger.error("getFrozenStatus-error", ex);
  1151. return -1;
  1152. }
  1153. if (Objects.isNull(objectMetadata)) {
  1154. logger.error("getFrozenStatus-error, path :" + path + " do not has metaData");
  1155. return -1;
  1156. }
  1157. StorageClass storageClass = objectMetadata.getObjectStorageClass();
  1158. if (storageClass != StorageClass.Archive && storageClass != StorageClass.ColdArchive) {
  1159. logger.info("getFrozenStatus, path :" + path + " do not in Archive status");
  1160. return -1;
  1161. }
  1162. try {
  1163. // 解冻完成
  1164. boolean isRestoreCompleted = objectMetadata.isRestoreCompleted();
  1165. if (isRestoreCompleted) {
  1166. return 2;
  1167. } else {
  1168. return 1;
  1169. }
  1170. } catch (NullPointerException e) {
  1171. logger.info("getFrozenStatus, path :" + path + " waiting for forzed!");
  1172. return 0;
  1173. }
  1174. }
  1175. public static Map<String, Object> getMediaAllInfo(String inPath) {
  1176. return getMediaAllInfo(inPath, BasePropertiesUtils.getVideoBucket());
  1177. }
  1178. public static Map<String, Object> getMediaAllInfo(String inPath, String bucketName) {
  1179. Map<String, Object> map = new HashMap<String, Object>();
  1180. String encodedInput;
  1181. try {
  1182. encodedInput = URLEncoder.encode(inPath, "utf-8");
  1183. } catch (UnsupportedEncodingException e) {
  1184. logger.error("获取元数据输入流解析错误", e);
  1185. map.put("status", "1");
  1186. return map;
  1187. }
  1188. SubmitMediaInfoJobRequest request = new SubmitMediaInfoJobRequest();
  1189. JSONObject input = new JSONObject();
  1190. input.put("Bucket", bucketName);
  1191. input.put("Location", PropertiesUtils.getTranscodeLocation());
  1192. input.put("Object", encodedInput);
  1193. request.setInput(input.toJSONString());
  1194. request.setPipelineId(PropertiesUtils.getTranscodePipelineId());
  1195. try {
  1196. SubmitMediaInfoJobResponse response = new SubmitMediaInfoJobResponse();
  1197. response = AliOssConfig.getIAcsClient().getAcsResponse(request);
  1198. if (response.getMediaInfoJob().getState() != null
  1199. && response.getMediaInfoJob().getState().equalsIgnoreCase("Fail")) {
  1200. logger.error("获取元数据错误:" + JSONObject.toJSONString(response.getMediaInfoJob())
  1201. + ",requestId:" + response.getRequestId());
  1202. map.put("status", "2");
  1203. return map;
  1204. }
  1205. Properties properties = response.getMediaInfoJob().getProperties();
  1206. Properties.Streams.VideoStream videoStream = null;
  1207. if (CollectionUtils.isNotEmpty(properties.getStreams().getVideoStreamList())) {
  1208. videoStream = properties.getStreams().getVideoStreamList().get(0);
  1209. }
  1210. Properties.Format format = properties.getFormat();
  1211. logger.info("videoStream:" + JSONObject.toJSONString(videoStream));
  1212. logger.info("format:" + JSONObject.toJSONString(format));
  1213. map.put("status", "0");
  1214. if (properties.getWidth() != null) {
  1215. map.put("width", Integer.parseInt(properties.getWidth()) + "");
  1216. }
  1217. if (properties.getHeight() != null) {
  1218. map.put("height", Integer.parseInt(properties.getHeight()) + "");
  1219. }
  1220. if (videoStream != null) {
  1221. map.put("rotate", videoStream.getRotate());
  1222. map.put("codeName", videoStream.getCodecName());
  1223. }
  1224. if (format != null) {
  1225. map.put("size", format.getSize());
  1226. //设置成long类型的 大于0少于1的设置成1
  1227. if (Double.parseDouble(format.getDuration()) > 0 && Double.parseDouble(format.getDuration()) < 1) {
  1228. map.put("duration", new Double(1).longValue());
  1229. } else {
  1230. map.put("duration", StringUtils.isEmpty(format.getDuration()) ? 0 : new Double(Double.parseDouble(format.getDuration())).longValue());
  1231. }
  1232. map.put("bitRate", StringUtils.isEmpty(format.getBitrate()) ? 0 : new Double(Double.parseDouble(format.getBitrate())).longValue() * 1000);
  1233. }
  1234. } catch (ServerException e) {
  1235. logger.error("获取元数据服务器异常", e);
  1236. map.put("status", "3");
  1237. } catch (ClientException e) {
  1238. logger.error("获取元数据客户端异常", e);
  1239. map.put("status", "4");
  1240. } catch (Exception e) {
  1241. logger.error("获取元数据异常", e);
  1242. map.put("status", "5");
  1243. }
  1244. return map;
  1245. }
  1246. public static CopyObjectResult setStorageClassToColdArchive(String bucket, String key) {
  1247. CopyObjectRequest request = new CopyObjectRequest(bucket, key, bucket, key);
  1248. ObjectMetadata objectMetadata = new ObjectMetadata();
  1249. // 封装header,此处以设置存储类型为归档类型为例。
  1250. objectMetadata.setHeader("x-oss-storage-class", StorageClass.ColdArchive);
  1251. request.setNewObjectMetadata(objectMetadata);
  1252. // 更改文件存储类型。
  1253. return getInternalOssClient().copyObject(request);
  1254. }
  1255. public static String getRandomObjectKey(Integer fileType) {
  1256. String env = PropertiesUtils.getProjectEnv();
  1257. if (StringUtils.isEmpty(env)) {
  1258. env = "qa";
  1259. }
  1260. String fileName = RandomUtil.generate18String();
  1261. if (EnumUploadFileType.VIDEO.getIntType().equals(fileType)) {
  1262. fileName = "/video/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
  1263. } else if (EnumUploadFileType.VOICE.getIntType().equals(fileType)) {
  1264. fileName = "/voice/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
  1265. } else {
  1266. fileName = "/pic/" + env + "/" + DateUtils.dateToStringyyyyMMdd(new Date()) + "/" + fileName;
  1267. }
  1268. return getProjectName() + fileName;
  1269. }
  1270. public static StsTokenVO getStsToken(String fileName, Long durationSeconds) {
  1271. String endpoint = BasePropertiesUtils.getLongvideoStsEndpoint();
  1272. String accessKeyId = BasePropertiesUtils.getLongvideoStsAccessKeyId();
  1273. String accessKeySecret = BasePropertiesUtils.getLongvideoStsAccessKeySecret();
  1274. String roleArn = BasePropertiesUtils.getLongvideoStsRoleArn();
  1275. String roleSessionName = BasePropertiesUtils.getLongvideoStsSessionName();
  1276. StsTokenVO result = new StsTokenVO();
  1277. try {
  1278. String region = "cn-hangzhou";
  1279. DefaultProfile.addEndpoint("", "", "Sts", endpoint);
  1280. IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
  1281. DefaultAcsClient client = new DefaultAcsClient(profile);
  1282. final AssumeRoleRequest request = new AssumeRoleRequest();
  1283. request.setMethod(MethodType.POST);
  1284. request.setRoleArn(roleArn);
  1285. request.setRoleSessionName(roleSessionName);
  1286. //设置过期时间 临时访问凭证的有效时间,单位为秒。最小值为900,最大值以当前角色设定的最大会话时间为准。角色最大会话时间取值范围为3600秒~43200秒
  1287. if (Objects.nonNull(durationSeconds)) {
  1288. request.setDurationSeconds(durationSeconds);
  1289. }
  1290. JSONObject policy = getUploadFileStsPolicy(BasePropertiesUtils.getVideoBucket(), fileName);
  1291. request.setPolicy(policy.toJSONString());
  1292. final AssumeRoleResponse response = client.getAcsResponse(request);
  1293. result.setExpiration(response.getCredentials().getExpiration());
  1294. result.setAccessKeyId(response.getCredentials().getAccessKeyId());
  1295. result.setAccessKeySecret(response.getCredentials().getAccessKeySecret());
  1296. result.setSecurityToken(response.getCredentials().getSecurityToken());
  1297. result.setRequestId(response.getRequestId());
  1298. result.setFileName(fileName);
  1299. result.setHost(AliOssConfig.getUploadDomain());
  1300. String host0 = BasePropertiesUtils.getOssaccelerateUploadDomain();
  1301. String host1 = "https://" + AliOssConfig.getBucket(EnumPublicBuckets.PUBBUCKET.getBucketName()) + "." + AliOssConfig.getOssEndPoint() + "/";
  1302. result.setHosts(new String[]{host0, host1});
  1303. result.setBucket(BasePropertiesUtils.getVideoBucket());
  1304. result.setRegion(region);
  1305. result.setCname(true);
  1306. // 返回服务器当前时间
  1307. result.setServerTimestamp(System.currentTimeMillis());
  1308. } catch (com.aliyuncs.exceptions.ClientException e) {
  1309. logger.error(String.format("获取临时令牌失败,errorCode:%s;errorMessage:%s;requestId:%s",
  1310. e.getErrCode(), e.getErrMsg(), e.getRequestId()));
  1311. } catch (Exception e) {
  1312. logger.error("获取临时令牌失败", e);
  1313. }
  1314. return result;
  1315. }
  1316. private static JSONObject getUploadFileStsPolicy(String bucketName, String fileName) {
  1317. JSONObject policy = new JSONObject();
  1318. policy.put("Version", "1");
  1319. JSONArray statements = new JSONArray();
  1320. JSONObject statement = new JSONObject();
  1321. statement.put("Effect", "Allow");
  1322. JSONArray action = new JSONArray();
  1323. action.add("oss:PutObject");
  1324. statement.put("Action", action);
  1325. JSONArray resource = new JSONArray();
  1326. resource.add("acs:oss:*:1894469520484605:" + bucketName + "/" + fileName);
  1327. statement.put("Resource", resource);
  1328. statements.add(statement);
  1329. policy.put("Statement", statements);
  1330. logger.info(String.format("Policy:%s", JSON.toJSONString(policy)));
  1331. return policy;
  1332. }
  1333. public static String downloadAndSaveInOSS(String fileName, String url, String contentType) {
  1334. try {
  1335. if (url.startsWith(CdnUtil.VIDEO_CDN_URL_HOST)
  1336. || url.startsWith(CdnUtil.DOWNLOAD_CDN_URL_HOST_PICTURE)) {
  1337. return url;
  1338. }
  1339. byte[] fileData = HttpUtil.downloadBytes(url);
  1340. if (fileData == null || fileData.length == 0) {
  1341. log.warn("downloadAndSaveInOSS 下载media失败,URL: {}", url);
  1342. return null;
  1343. }
  1344. InputStream inputStream = new ByteArrayInputStream(fileData);
  1345. return CdnUtil.getOssHttpUrl(saveInPublic(EnumPublicBuckets.PUBBUCKET.getBucketName(),
  1346. fileName, inputStream, contentType));
  1347. } catch (Exception e) {
  1348. log.error("downloadAndSaveInOSS 下载转存OSS失败,URL: {}", url, e);
  1349. return null;
  1350. }
  1351. }
  1352. }