器组件,原⽣JS的。。。
说明:
请求⽤了⾃定义封装的原⽣js的ajax请求和axios
视频播放⽤了vue-video-player插件
⽂件的md5编码⽤了sparkmd5.js
读取⼆进制⽂件⽤的客户端⾃带的FileReader接⼝
封装的分⽚上传和断点续传组件:
<template>
<div class="biguploadfile">
<div class="videoBox">
<div class="progressBox" v-if="showProgress">
<span class="progressItem" ref="progressItem"></span>
</div>
<videoPlay :src="fileBaseUrl+src" poster='' v-if="showVideo && !pauseStatus && !showProgress"></videoPlay>
</div>
<input type="file" class="bigFile" @change="computedSliceMd5" ref="file" name="file">
<div class="btns">
<Button type="primary" v-if="!pauseStatus" @click="toUpload">上传</Button>
<Button type="default" v-if="pauseStatus" @click="pauseUpload">取消</Button>
</div>
</div>
</template>
<script>
import SparkMD5 from "spark-md5"; //获取⼆进制⽂件md5编码
import videoPlay from "@/components/videoPlayer"; //利⽤vue-video-player插件封装的播放器
import Ajax from "@/plugins/ajax.js"; //封装的原⽣JS ajax请求
import api from "@/api/commonApi.js"; //本地⽤的接⼝
import code from "@/config/base.js"; //这是项⽬中⾃定义的参数
export default {
data() {
return {
showVideo: false,
blobSlice: null,
file: null,
identifier: null,
chunkSize: 1024000,
chunks: 0,
currentChunk: 0,
spark: null,
fileReader: null,
tmpDataList: [],
formDataList: [],
uploadedList: [],
start: 0,
end: 0,
headers: {},
urlCode: code.urlCode.lectureDemand,
xhr: null,
pauseStatus: false,
showProgress: false,
percent: 0
};
},
props: {
src: { //利⽤props将上传的视频地址传回来,⽤于预览
type: String,
default: ""
}
},
components: { videoPlay }, //播放器组件
methods: {
pauseUpload() { //取消上传
this.xhr.abort();
this.xhr = null;
},
toUpload() { //调⽤上传接⼝
this.$refs.file.click();
},
checkMd5() { //断点续传需要⽤的⽅法,断点续传获取到的是已经上传过去的分⽚编号,已经上传过的分⽚直接跳过去 this.showProgress = true;
this.$axios
.post(api.lecturedemanduploadfilemd5, { md5: this.identifier })
.then(resp => {
if (resp.de == 2) {
let tmpIdsList = resp.data.object.ids;
tmpIdsList.map((el,index) => {
tmpIdsList[index] = parseInt(el);
});
this.uploadedList = tmpIdsList;
}
this.showVideo = false;
this.pauseStatus = true;
this.uploadFile(
1,
this.formDataList,
this.uploadedList,
this.chunks
);
})
.catch(err => {
this.initParam(0, "断点续传检查失败,请重试");
});
},
computedSliceMd5() { //获取⽂件的md5编码
this.file = this.$refs.file.files[0];
this.chunks = il(this.file.size / this.chunkSize);
load = e => {
this.spark.append(sult); // Append array buffer
this.currentChunk++;
if (this.currentChunk < this.chunks) {
this.loadNext();
} else {
this.identifier = d(); //⽂件的MD5⾝份标识
let formData = new FormData();
formData.append("filename", this.file.name);
formData.append("relativePath", this.file.name);
formData.append("totalSize", this.file.size);
formData.append("chunkSize", this.chunkSize);
formData.append("identifier", this.identifier);
formData.append("totalChunks", this.chunks);
formData.append("file", el.file);
formData.append("currentChunkSize", el.currentSize);
formData.append("chunkNumber", el.currentNum + 1);
formData.append("urlCode", this.urlCode);
this.formDataList.push(formData);
});
this.checkMd5();
}
};
r = function() {
this.$("读取⽂件出错,请重试");
},
loadNext() { //⽂件切⽚
(this.start = this.currentChunk * this.chunkSize),
(d =
this.start + this.chunkSize >= this.file.size
this.file.size
: this.start + this.chunkSize);
let pieceFile = this.blobSlice.call(
this.file,
this.start,
);
pieceFile.name = this.file.name;
let tmpObj = {
file: pieceFile,
currentSize: d - this.start,
currentNum: this.currentChunk
};
adAsArrayBuffer(pieceFile);
},
uploadFile(n, dataList, uploadedList, chunks) { //利⽤promise异步变同步上传 console.log("uploadedList",uploadedList);
let status = uploadedList.indexOf(n) == -1 ? true : false;
console.log("status",status);
let key = n - 1;
if (status) {
new Promise((resolve, reject) => {
Ajax(
resolve,
reject,
"post",
api.lecturedemanduploadfile,
this.headers,
dataList[key],
this.xhrReturn,
);
})
.then(resp => {
de == "401"){
this.$router.push({path:"/login"});
return ;
}
if (resp.object.uploadStatus == 1) {
let tmpUrl = JSON.parse(resp.object.fileUrl)[0]
.fileName;
this.$emit("getUrl", tmpUrl);
this.success();
} else {
this.uploadFile(
n + 1,
this.formDataList,
this.uploadedList,
this.chunks
)
;
}
})
.catch(err => {
this.initParam(0, "上传失败");
});
}else{
this.percent += Math.floor(100/this.chunks);
n + 1,
this.formDataList,
this.uploadedList,
this.chunks
);
}
},
getProgress(evt) { //ajax进度条回调⽅法
if (evt.lengthComputable) {
this.percent += Math.floor(
(evt.loaded * 100) / this.chunks / al
);
if(this.percent>=99){
this.percent = 99;
}
this.changeProgress(1);
} else {
this.changeProgress(0);
}
},
changeProgress(type) { //进度条展⽰
if (type) {
this.$refs.progressItem.innerHTML =
Fixed(2) + "%";
this.$refs.progressItem.style.width =
Fixed(2) + "%";
} else {
this.$refs.progressItem.innerHTML = "上传失败"; }
},
success() { //成功回调
this.percent = 100;
this.changeProgress(1);
setTimeout(() => {
this.initParam(1, "上传成功");
}, 500);
},
failed(err) { //失败回调
this.initParam(0, err);
},
initParam(type, msg) { //成功或失败之后的初始化
this.percent = 0;
this.pauseStatus = false;
this.showProgress = false;
this.file = null;
this.identifier = null;
this.chunks = 0;
this.currentChunk = 0;
this.formDataList = [];
this.uploadedList = [];
this.start = 0;
this.$refs.file.value = "";
if (type == 1) {
this.showVideo = true;
this.$Message.success(msg);
} else {
this.showVideo = false;
this.$(msg);
}
},
xhrReturn(xhr) {
}
},
created() { //⼀些变量的初始化
if (Boolean(this.src)) {
this.showVideo = true;
}
this.blobSlice =
window.File.prototype.slice ||
window.Slice ||
window.File.prototype.webkitSlice;
this.spark = new SparkMD5.ArrayBuffer(); this.fileReader = new FileReader();
this.percent = 0;
}
};
</script>
<style lang="less" scoped>
.biguploadfile {
display: inline-block;
.
bigFile {
display: none;
}
.progressBox {
display: inline-block;
width: 200px;
height: 20px;
大文件发送background-color: gray;
vertical-align: middle;
}
.progressItem {
display: inline-block;
height: 20px;
background-color: #2d8cf0;
font-weight: bold;
color:#ffffff;
}
.btns {
display: inline-block;
vertical-align: middle;
}
.videoBox {
display: inline-block;
vertical-align: middle;
}
}
</style>
可参考的⾃定义封装的Ajax
发布评论