阿里云oss授权访问文档示例地址
阿里云没有提供直接的获取是视频时长的API接口,需要曲线处理
1、引入阿里云oss pom
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
阿里云工具类
/**
* @author ful
*/
@Component
@Slf4j
public class AliOSSUtil {
// endpoint 访问OSS的域名
@Value("${oss.agora.endpoint}")
public String endpoint;
// accessKeyId和accessKeySecret OSS的访问密钥
@Value("${oss.agora.id}")
public String accessKeyId;
@Value("${oss.agora.secret}")
public String accessKeySecret;
// Bucket 用来管理所存储Object的存储空间
@Value("${oss.agora.bucket}")
public String bucketName;
@Value("${oss.agora.region}")
public String region;
@Value("${oss.agora.vendor}")
public String vendor;
@Value("${oss.agora.cdn}")
public String cdn;
/**
* 文件直传
*
* @param objectKey 上传路径
* @param inputStream 上传流
* @throws RuntimeException
*/
public void fileUpload(String objectKey, InputStream inputStream) throws RuntimeException {
Map map = getCommon(objectKey);
OSS ossClient = null;
try {
ossClient = (OSS) map.get(0);
AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
if (ossClient.doesObjectExist(model.getBucketName(), model.getObjectKey())) {
log.error("此文件重名,请更改文件名重试!");
throw new RuntimeException("此文件重名,请更改文件名重试!");
}
PutObjectRequest putObjectRequest = new PutObjectRequest(model.getBucketName(), model.getObjectKey(), inputStream);
PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
String eTag = putObjectResult.getETag();
if (StringUtils.isBlank(eTag)) {
log.error("文件直传失败!");
throw new RuntimeException("文件直传失败");
}
} catch (Exception e) {
log.error("文件直传失败,exp={}", e);
throw new RuntimeException("文件直传失败:" + e.getMessage());
} finally {
ossClient.shutdown();
try {
inputStream.close();
} catch (IOException e) {
log.error("关闭文件流异常={}", e);
}
}
}
/**
* OSS获取下载签名URL
*
* @param objectKey 文件对象key
* @return 签名URL
*/
public String getOssObjectDownAuthUrl(String objectKey) throws RuntimeException {
Map map = getCommon(objectKey);
OSS ossClient = null;
try {
ossClient = (OSS) map.get(0);
AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
GeneratePresignedUrlRequest req =
new GeneratePresignedUrlRequest(model.getBucketName(), model.getObjectKey(), HttpMethod.GET);
//这里设置签名在30小时后过期
Date expiration = new Date(new Date().getTime() + 30L * 60L * 60L * 1000);// 生成URL
// Date expireDate = new Date(System.currentTimeMillis() + 30L * 60L * 60L * 1000L);
req.setExpiration(expiration);
URL url = ossClient.generatePresignedUrl(req);
String urlStr = url.toString();
return urlStr;
} catch (Exception e) {
log.error("getOssObjectDownAuthUrl 获取下载签名URL失败,exp={}", e);
throw new RuntimeException("获取下载签名URL失败");
} finally {
ossClient.shutdown();
}
}
/**
* OSS获取下载签名URL
*
* @param objectKey 文件对象key
* @param expireTime 当前时间加多少毫秒后过期,过期时间(毫秒)
* @return 签名URL
*/
public String getOssObjectDownAuthUrl(String objectKey, long expireTime) throws RuntimeException {
Map map = getCommon(objectKey);
OSS ossClient = null;
try {
ossClient = (OSS) map.get(0);
AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
GeneratePresignedUrlRequest req =
new GeneratePresignedUrlRequest(model.getBucketName(), model.getObjectKey(), HttpMethod.GET);
//这里设置签名在半个小时后过期
Date expireDate = new Date(System.currentTimeMillis() + expireTime);
req.setExpiration(expireDate);
URL url = ossClient.generatePresignedUrl(req);
String urlStr = url.toString();
return urlStr;
} catch (Exception e) {
log.error("getOssObjectDownAuthUrl long获取下载签名URL失败,exp={}", e);
throw new RuntimeException("获取下载签名URL失败");
} finally {
ossClient.shutdown();
}
}
/**
* OSS获取上传签名URL
*
* @param objectKey 文件对象key
* @return 签名URL
*/
public String getOssObjectUploadAuthUrl(String objectKey) throws RuntimeException {
Map map = getCommon(objectKey);
OSS ossClient = null;
try {
ossClient = (OSS) map.get(0);
AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
if (ossClient.doesObjectExist(model.getBucketName(), model.getObjectKey())) {
throw new RuntimeException("此文件重名,请更改文件名重试!");
}
Date expirationTime = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(model.getBucketName(), model.getObjectKey(), HttpMethod.PUT);
request.setExpiration(expirationTime);
//必须要!!!!!!,而且前端上传时,也需要在header里面设置,content-type为"application/octet-stream"
request.setContentType("application/octet-stream");
URL url = ossClient.generatePresignedUrl(request);
String urlstr = url.toString();
return urlstr;
} catch (Exception e) {
log.error("getOssObjectDownAuthUrl long获取上传签名URL失败,exp={}", e);
throw new RuntimeException("获取上传签名URL失败" + e.getMessage());
} finally {
ossClient.shutdown();
}
}
/**
* 删除存储对象
*
* @param objectKey 文件对象key
* @return 签名URL
*/
public void deleteObject(String objectKey) throws RuntimeException {
Map map = getCommon(objectKey);
OSS ossClient = null;
try {
ossClient = (OSS) map.get(0);
AliOssPublicEntity model = (AliOssPublicEntity) map.get(1);
// 指定对象所在的存储桶
ossClient.deleteObject(model.getBucketName(), model.getObjectKey());
} catch (RuntimeException clientException) {
log.error("deleteObject 删除存储对象失败,exp={}", clientException);
throw new RuntimeException("删除存储对象失败");
} finally {
ossClient.shutdown();
}
}
/**
* 绝对路径更换为相对路径
*
* @param url 绝对路径
* @return 相对路径
*/
public String getRelativePath(String url) {
url = url.substring(url.indexOf(".com") + 5, url.indexOf("?"));
return url;
}
/**
* client公共参数
*
* @param objectKey
* @return
*/
private Map getCommon(String objectKey) {
AliOssPublicEntity entity = AliOssPublicEntity.build(objectKey, endpoint, accessKeyId, accessKeySecret, bucketName);
OSS ossClient = new OSSClientBuilder().build(entity.getEndpoint(), entity.getAccessKeyId(), entity.getAccessKeySecret());
Map map = new HashMap();
map.put(0, ossClient);
map.put(1, entity);
return map;
}
}
阿里云配置类
@Data
public class AliOssPublicEntity {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String objectKey;
public static AliOssPublicEntity build(String objectKey,String endpoint,String accessKeyId,
String accessKeySecret,String bucketName) {
AliOssPublicEntity entity = new AliOssPublicEntity();
entity.setEndpoint(endpoint);
entity.setAccessKeyId(accessKeyId);
entity.setAccessKeySecret(accessKeySecret);
entity.setBucketName(bucketName);
entity.setObjectKey(objectKey);
return entity;
}
}
阿里云根据资源路径获取资源时长代码
public int getVideoDuration(String videoUrl) {
if (StringUtils.isNotEmpty(videoUrl) && "m3u8".equals(videoUrl.substring(videoUrl.length() - 4))) {
try {
videoUrl = aliOSSUtil.getOssObjectDownAuthUrl(videoUrl);
log.info("getVideoDuration:aliOSSUtil.videoUrl ={}", videoUrl);
HttpRequest httpRequest = HttpRequest.get(videoUrl)
.timeout(30000);
log.info("getRequest httpRequest:{}", httpRequest);
HttpResponse res = httpRequest.execute();
String result = res.body();
String pattern = "\\d+[.]\\d+";
List<String> matchStrs = new ArrayList<>();
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(result);
while (m.find()) { //此处find()每次被调用后,会偏移到下一个匹配
matchStrs.add(m.group());//获取当前匹配的值
}
Double durationDouble = 0.0;
for (int i = 0; i < matchStrs.size(); i++) {
durationDouble += Double.parseDouble(matchStrs.get(i));
}
log.info("LiveDetailController.getVideoDuration->duration=", durationDouble.intValue());
return durationDouble.intValue();
} catch (Exception e) {
log.error("getVideoDuration 异常={}", e);
}
}
return 0;
}
这里需要注意:
HttpRequest httpRequest = HttpRequest.get(videoUrl) .timeout(30000);请求是一定不要加 .header(“Content-Type”, “application/json”) 头,不然会验证签名失败