一、业务场景:
ai课堂需求,涉及到视频的播放,需要在后台上传视频,视频的最大限制是500MB,当视频较大的时候,普通的上传会有问题,导致上传失败。这就要求我们将大文件进行拆分,分片进行上传,在所有分片上传成功之后,再进行合并。
二、前后端交互流程:
1、前端调用后端分片文件上传初始化接口

2、在初始化接口调用后,后端给前端返回分片上传的地址,分片数量是几个,后端就会给前端返回几个地址。前端去调用这些地址(前端直连minio),进行分片上传。

3、待所有分片都上传完毕后,调用合并接口进行文件的合并。

最终得到完整的视频播放地址。
三、核心代码
javascript
/分片上传
axiosPartUpload(file) {
//分片大小
const chunkSize = 10 * 1024 * 1024;
const fileSize = file.size
//计算当前选择文件需要的分片数量
const chunkCount = Math.ceil(fileSize / chunkSize)
this.totalCount=chunkCount;
let initParams={
fileName:file.name,
fileSize:fileSize,
partCount:chunkCount,
contentType:file.type
}
this.isUploading=true;
//调用初始化接口
initUpload(initParams).then(async res=>{
console.log(res,'初始化接口返回结果')
this.uploadId=res.uploadId;
this.objectName=res.objectName;
let urlList=res.urlList;
for(let i=0;i<urlList.length;i++){
//文件截取
let start = i * chunkSize;
let end = Math.min(fileSize, start + chunkSize);
let chunkFile = file.slice(start, end);
//调用分片上传接口
await uploadPart(urlList[i],chunkFile).then(res2=>{
console.log(`第${i+1}个分片上传成功`)
this.successCount=i+1;
}).catch(err=>{
this.isUploading=false;
this.$message.error(`第${i+1}个分片上传失败`)
})
}
//所有分片上传完成之后,进行合并
let mergeParams={
uploadId:this.uploadId,
objectName:this.objectName
}
mergeFile(mergeParams).then(res2=>{
console.log(res2,'合并接口返回结果')
this.$emit("getVideoUrl", res2.fileUrl, file.name);
this.$message({
message: "上传成功",
type: "success"
});
this.isUploading=false;
})
}).catch(err=>{
this.isUploading=false;
this.$message({
message: "上传失败,请重新选择文件上传!",
type: "error"
})
})
},
四、存在问题
1、缺少断点续传逻辑。
2、分片串行上传,上一分片上传结束后上传下一分片,效率不高。