async uploadVideo(fileData) {
const { data } = await uploadVideo(fileData);
if (data.code === 1) {
this.$bus.$emit("videoLoading", true, "上传中");
成功
if (this.percentCount === 0) {
// 避免上传成功后会删除切片改变 chunkList 的长度影响到 percentCount 的值
this.percentCount = 99.99 / this.chunkList.length;
}
this.percent += this.percentCount; // 改变进度
} else {
// this.uploadVideo(fileData);
}
},
async handleChange(file) {
console.log(file);
console.log(file.raw);
this.percent = 0;
this.percentCount = 0;
this.videoSize = "";
// this.loading = true;
this.$bus.$emit("videoLoading", true, "检查中");
if (!file) return;
this.percent = 0;
this.videoUrl = "";
// 获取文件并转成 ArrayBuffer 对象
// const fileObj = file.raw;
const fileObj = file.raw;
let buffer;
try {
buffer = await this.fileToBuffer(fileObj);
} catch (e) {
console.log(e);
}
// 将文件按固定大小(1M)进行切片,注意此处同时声明了多个常量
const chunkSize = 1048576, //字节
chunkList = [], // 保存所有切片的数组
chunkListLength = Math.ceil(fileObj.size / chunkSize), // 计算总共多个切片
suffix = /\.([0-9A-z]+)$/.exec(fileObj.name)[1]; // 文件后缀名
console.log(chunkSize);
// 根据文件内容生成 hash 值
const spark = new SparkMD5.ArrayBuffer();
spark.append(buffer);
const hash = spark.end();
// 生成切片,这里后端要求传递的参数为字节数据块(chunk)和每个数据块的文件名(fileName)
let curChunk = 0; // 切片时的初始位置
this.videoSize = (fileObj.size / 1048576).toFixed(2); //视频大小
//获取视频时长
console.log(fileObj);
let url = URL.createObjectURL(fileObj);
let audioElement = new Audio(url);
audioElement.addEventListener("loadedmetadata", () => {
console.log(audioElement.duration.toFixed());
this.videoDuration = formatSeconds(
audioElement.duration.toFixed().toString
); //时长为秒,小数,182.36
console.log(this.videoDuration);
});
for (let i = 0; i < chunkListLength; i++) {
const item = {
chunk: fileObj.slice(curChunk, curChunk + chunkSize),
// chunk: fileObj,
fileName: `${hash}_${i}.${suffix}`, // 文件名规则按照 hash_1.jpg 命名
hash: `${hash}`,
};
curChunk += chunkSize;
chunkList.push(item);
}
this.chunkList = chunkList; // sendRequest 要用到
this.hash = hash; // sendRequest 要用到
this.sendRequest();
},
// 发送请求
async sendRequest() {
// const requestList = []; // 请求集合
this.randomNum =
currentTime() +
this.showCaptcha(10, 99) +
this.showCaptcha(10, 99) +
this.showCaptcha(10, 99);
let newObj = this.chunkList;
let n = 0;
// let errorN = null;
while (n < newObj.length) {
// console.log(`当前${n}次请求`);
console.log("当前" + n + "次请求");
const formData = new FormData();
formData.append("file", this.chunkList[n].chunk);
formData.append("hash", this.chunkList[n].hash);
formData.append("filename", this.chunkList[n].fileName);
formData.append("chunkLength", newObj.length);
formData.append("chunkIndex", n);
formData.append("UcNumber", this.randomNum);
try {
console.log("当前成功" + n);
await this.uploadVideo(formData, n); //async await让接口同步执行
n += 1;
} catch (err) {
console.log("请求异常2s");
}
}
try {
this.FileSuccess();
} catch (err) {
this.FileSuccess();
}
},
async FileSuccess() {
//分片上传成功之后通知后端合并
const { data } = await FileSuccess({
UcNumber: this.randomNum,
hash: this.chunkList[0].hash,
chunkLength: this.chunkList.length,
file_size: this.videoSize,
});
if (data.code === 1) {
this.percent = 100; // 改变进度
this.$bus.$emit("videoLoading", false, "");
this.$emit("handleId", data.file_id);
}
},
大视频分片上传与断点续传
最新推荐文章于 2023-08-07 11:09:10 发布