使用阿里云sdk,前端页面直传视频文件阿里云OSS存储,文件不需要经过服务端。
技术栈
前端:html、js、layui
服务端:Springboot
1、html页面创建元素
<input type="hidden" name="videoUrl" id="videoUrl" value="">
<input type="hidden" name="duration" id="duration" value="">
<video type="hidden" name="videoAttr" id="videoAttr"></video>
2、获取OSS的Token方法
(1)前端:ajax方式请求服务端获取阿里云OSS的token
async function getSysToken() {
return new Promise((resolve, reject) => {
$.ajax({
type: 'get',
url: '/api/upload/stsToken',
data: {id: userId},
contentType: 'application/json',
success: function (res) {
if (res.code == 0) {
let stsToken = {
region: res.data.region,
accessKeyId: res.data.accessKeyId,
accessKeySecret: res.data.accessKeySecret,
bucket: res.data.bucket,
stsToken: res.data.securityToken
};
let client = new OSS(stsToken);
resolve({client: client})
} else {
layer.msg('stsToken获取失败')
}
}
});
})
}
(2)服务端:通过自建配置文件类OSSProperties,获取yaml中阿里云OSS配置
@Resource
private OSSProperties OSS;
@RequestMapping("stsToken")
public Result stsToken(User user) {
// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
String roleSessionName = "RamOssTest" + (Objects.nonNull(user.getId()) ? user.getId() : new Random().nextInt(10000));
String policy = "{\n" +
" \"Version\": \"1\",\n" +
" \"Statement\": [\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Action\": \"oss:*\",\n" +
" \"Resource\": [\n" +
" \"acs:oss:*:*:" + OSS.getBucketName() + "/" + OSS.getFile() + "\"\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}";
try {
String regionId = OSS.getEndPoint().split("\\.")[0].split("oss-")[1];
// 添加endpoint。
DefaultProfile.addEndpoint(regionId, OSS.getBucketName(), OSS.getEndPoint());
// 构造default profile。
IClientProfile profile = DefaultProfile.getProfile(regionId, OSS.getAccessKeyId(), OSS.getAccessKeySecret());
// 构造client。
DefaultAcsClient client = new DefaultAcsClient(profile);
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setSysMethod(MethodType.POST);
request.setRoleArn(OSS.getArn());
request.setRoleSessionName(roleSessionName);
request.setPolicy(null);
request.setDurationSeconds(OSS.getTimeout());
final AssumeRoleResponse response = client.getAcsResponse(request);
STSToken stsToken = new STSToken(response.getCredentials().getExpiration(), response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(), response.getCredentials().getSecurityToken(), "oss-" + regionId, OSS.getBucketName(), new Date().getTime() + OSS.getTimeout() * 1000);
return Result.ok().data(stsToken);
} catch (ClientException e) {
System.out.println("Failed:");
System.out.println("Error code: " + e.getErrCode());
System.out.println("Error message: " + e.getErrMsg());
System.out.println("RequestId: " + e.getRequestId());
return Result.error(e.getMessage());
}
}
3、前端上传按钮,绑定点击方法为以下操作。点击
注意,重点是添加监听!!
let client = (await getSysToken()).client;
client.multipartUpload(fileName, file, {
progress: function(p, checkpoint) {
// 上传进度条
element.progress('progressBar', (p * 100).toFixed(2) + '%');
if (p == 1) {
$("input[name='file']").val('');
}
}
}).then(function(res) {
let vUrl = res.res.requestUrls[0].split("?")[0];
$("#videoUrl").val(vUrl);
// 获取<video>元素
var videoElement = document.getElementById('videoAttr');
videoElement.src = vUrl;
// 重点是添加监听loadedmetadata事件
videoElement.addEventListener('loadedmetadata', function() {
console.log('视频总时长: ' + videoElement.duration);
var vtime = videoElement.duration;
var ddd = document.getElementById('duration');
ddd.value = vtime;
});
layer.alert("上传完成");
}).catch(function(err) {
console.log(err);
});
4、前端,获取时长的js方法
上传视频文件后,就可以调用获取时长方法,返回的时间格式:mm:SS,例如23:10,23分10秒
function getDuration(){
var time = document.getElementById("duration").value;
//如果不是数字则返回原值
var isNumeric = !isNaN(parseFloat(time)) && isFinite(time);
if(!isNumeric){
return time;
}
var totalSecond = Math.floor(time);
var minute = "00";
// 得到分钟数加秒数
if (totalSecond > 60){
minute = Math.floor(totalSecond / 60) ;
if (minute < 10) {
minute = "0" + minute;
}
}
var sec = totalSecond%60;
if(sec < 10){
sec = "0"+sec;
}
var finalDuration = minute + ":"+sec;
return finalDuration;
}