最近有一个上传视频到服务器的功能,然后发现视频太大了,比如1个G的视频文件基本都是上传失败的,我之前都是上传阿里云的,所以面对大文件上传服务器就做了分片上传和断点续传。

首先解释什么是分片上传:比如一个文件是22M,我令5M为一片那么就可以分5片,一片一片上传给后端然后都上传完成开始合并这个文件。

断点续传:还是以上面的例子,有5片小文件,比如我传第一片的时侯没问题,第二片,第三片因为网络啊什么的原因打断了,第四片,第五片又上传成功了;那我下一次传相同的文件时,后端会返回给我那几片没成功,那么我只要传没成功的分片就可以,全部传完就可以调用合并文件接口。

接下来我就说说自己项目这个大文件视频是怎么进行分片断点续传的,代码里有注释,菜鸡写的不好,轻点喷

1.上传文件然后自定义上传

<el-uploadclass="upload-demo"action="#":http-request="requestUpload":show-file-list="false":before-upload="beforeUpload"drag:accept="'video/*'"v-if="file === null"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip" slot="tip">只能上传视频文件</div></el-upload><div v-else><p>{{ file.name }}</p><el-progress :percentage="percentage" v-if="percentage !== 0"></el-progress></div>
 // 覆盖默认的上传行为requestUpload() {},//上传前的操作,可以对文件做一些限制beforeUpload(file) {if (file.type != "video/mp4") {this.$modal.msgError("视频上传只支持Mp4格式");return false;} else {this.file = file;}},

然后点击确定进行上传到服务器

/** 确定提交按钮 */submitForm() {this.$refs["form"].validate((valid) => {if (valid) {if (this.file != null) {//点击确定显示loading效果this.confirmLoading = true;//重置进度条为0this.percentage = 0;//这里走分片上传逻辑this.uploadByPieces({file: this.file, //视频实体pieceSize: 5, //分片大小success: (data) => {this.confirmLoading = false;this.percentage = 100;this.$modal.msgSuccess("新增成功");this.open = false;this.getList();},error: (e) => {this.confirmLoading = false;this.file = null;this.percentage = 0;this.$modal.msgError("分片上传视频失败");},});} else {this.$modal.msgError("请上传视频");}}});},
//断点分片上传uploadByPieces({ file, pieceSize = 2, success, error }) {// 上传过程中用到的变量let fileMD5 = ""; // md5加密文件的标识const chunkSize = pieceSize * 1024 * 1024; // 分片大小const chunkCount = Math.ceil(file.size / chunkSize); // 总片数//得到某一片的分片const getChunkInfo = (file, currentChunk, chunkSize) => {let start = currentChunk * chunkSize;let end = Math.min(file.size, start + chunkSize);let chunk = file.slice(start, end);return chunk;};// 第一步const readFileMD5 = () => {// 读取视频文件的md5console.log("获取文件的MD5值");//得到第一片和最后一片const startChunk = getChunkInfo(file, 0, chunkSize);const endChunk = getChunkInfo(file, chunkCount - 1, chunkSize);console.log(startChunk, endChunk);//对第一片进行转码然后md5加密,网上很多是直接对整个文件转码加密得到标识,但是我发现大文件尤其是几个G的文件会崩溃,所以我是先分片然后取第一片加密let fileRederInstance = new FileReader();fileRederInstance.readAsBinaryString(startChunk);fileRederInstance.addEventListener("load", (e) => {let fileBolb = e.target.result;fileMD5 = md5(fileBolb);//检查文件有没有上传过的状态uploadCheckAxios({ identifier: fileMD5, totalChunks: chunkCount }).then((res) => {if (res.data.needMerge == true) {console.log("文件都已上传,现在需要合并");//调用合并接口,合并接口后端做了异步处理不然会超时let time = new Date().getTime();mergeFileAxios({name: this.form.name,subjectName: this.form.subjectName,teacherName: this.form.teacherName,categoryId: this.form.categoryId,description: this.form.description,identifier: fileMD5,totalSize: file.size,filename: time + "_" + file.name,}).then((res) => {console.log("文件合并成功");success && success(res);}).catch((e) => {console.log(e, "文件合并错误");error && error(e);});} else {//这里很多博客都是直接for循环,可我实际联调发现for循环不等返回,虽然上传对顺序没影响但是很多分片其实是超时了会上传失败,所以我处理成数组,从需要上传的数组第一个分片上传有了返回后就从前面删掉数组元素直到数组为[]//文件未被上传if (res.data.status === 0) {console.log("文件未被上传");//整理需要上传的分片的数组let needUploadList = [];for (let i = 0; i < chunkCount; i++) {needUploadList.push(i);}console.log(needUploadList);readChunkMD5(needUploadList);}//文件已被上传过一部分else {let arr = res.data.uploaded;//如果上传过,进度条开始的数据要计算一下let per = 100 / chunkCount;this.percentage = Number((arr.length * per).toFixed(2));console.log(this.percentage);console.log(arr);let needUploadList = [];console.log("文件已被上传过一部分");//整理需要上传的分片的数组for (let i = 0; i < chunkCount; i++) {if (!arr.includes(i)) {needUploadList.push(i);}}console.log(needUploadList);readChunkMD5(needUploadList);}}}).catch((e) => {error && error(e);});});};// 针对每个分片文件进行上传处理const readChunkMD5 = (needUploadList) => {if (needUploadList.length > 0) {let i = needUploadList[0];console.log(i);//得到当前需要上传的分片文件const chunk = getChunkInfo(file, i, chunkSize);let fetchForm = new FormData();//后端需要的参数fetchForm.append("chunkNumber", i);fetchForm.append("chunkSize", chunkSize);fetchForm.append("currentChunkSize", chunk.size);fetchForm.append("file", chunk);fetchForm.append("filename", fileMD5 + "-" + i);fetchForm.append("identifier", fileMD5);fetchForm.append("totalChunks", chunkCount);fetchForm.append("totalSize", file.size);//上传接口uploadVideoChunkAxios(fetchForm).then((res) => {console.log(res);//都上传了,等待合并if (res.data === true) {console.log("文件开始合并");let time = new Date().getTime();mergeFileAxios({name: this.form.name,subjectName: this.form.subjectName,teacherName: this.form.teacherName,categoryId: this.form.categoryId,description: this.form.description,identifier: fileMD5,totalSize: file.size,filename: time + "_" + file.name,}).then((res) => {console.log("文件合并成功");success && success(res);}).catch((e) => {console.log(e, "文件合并错误");error && error(e);});} else {//每上传一个就在进度条上加数据let per = 100 / chunkCount;console.log(per, this.percentage);let totalPrecent = Number((this.percentage + per).toFixed(2));if (totalPrecent > 100) {this.percentage === 100;} else {this.percentage = totalPrecent;}console.log(this.percentage);let newArr = JSON.parse(JSON.stringify(needUploadList));if (newArr.length > 0) {newArr.shift();readChunkMD5(newArr);}}}).catch((e) => {error && error(e);});} else {console.log("上传结束");}};readFileMD5(); // 开始执行代码},

就到这里啦,结束

vue实现大文件分片上传断点续传并展示上传进度条相关推荐

  1. Vue实现大文件分片上传,包括断点续传以及上传进度条

    首先解释一下什么是分片上传 分片上传就是把一个大的文件分成若干块,一块一块的传输.这样做的好处可以减少重新上传的开销.比如:如果我们上传的文件是一个很大的文件,那么上传的时间应该会比较久,再加上网络不 ...

  2. 大文件分片上传,断点续传,秒传 实现

    前段时间做视频上传业务,通过网页上传视频到服务器. 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制:2,请求时间过长, ...

  3. vue+element-ui大文件的分片上传和断点续传js-spark-md5和browser-md5-file

    注意:以下共两份代码片段,第一份为原博主链接代码,第二份自己写的整体代码(比较乱) 1.参考 https://www.cnblogs.com/kelelipeng/p/10158599.html (j ...

  4. Vue项目中遇到了大文件分片上传的问题

    Vue项目中遇到了大文件分片上传的问题,之前用过webuploader,索性就把Vue2.0与webuploader结合起来使用,封装了一个vue的上传组件,使用起来也比较舒爽. 上传就上传吧,为什么 ...

  5. 大文件分片上传前端框架_无插件实现大文件分片上传,断点续传

    文件上传.gif 1. 简介: 本篇文章基于实际项目的开发,将介绍项目中关于大文件分片上传.文件验证.断点续传.手动重试上传等需求的使用场景及实现: 2. 项目需求 在一个音视频的添加中,既要有音视频 ...

  6. 无插件实现大文件分片上传,断点续传

    代码地址如下: http://www.demodashi.com/demo/11888.html 1. 简介: 本篇文章基于实际项目的开发,将介绍项目中关于大文件分片上传.文件验证.断点续传.手动重试 ...

  7. 使用webuploader组件实现大文件分片上传,断点续传

    无组件断点续传.gif 1. 组件简介 webuploader:是一个以HTML5为主, Flash为辅的文件上传组件,采用大文件分片/并发上传的方式,极大地提高了文件上传的效率,同时兼容多种浏览器版 ...

  8. minio实现大文件分片上传+断点续传+预览

    minio实现大文件分片上传+断点续传+预览 只提供后端java代码 思路: 前端分片 校验文件md5是否已经存在 --不存在创建临时桶存分片 校验分块是否已经上传 分块上传 合并分块 校验合成后md ...

  9. 大文件分片上传、断点续传

    话前 一开始在做文件上传的时候,没考虑过文件上传失败的问题,因为上传的多数都是几十兆几百兆的文件.但是也有会上传比较大的文件,此时传统的上传直接没了反应,也不知道上传了多少就很头疼.后来网上搜索的关于 ...

最新文章

  1. FPGA笔试题解析(二)
  2. PhpStorm Swoole 和 CI 代码自动补全
  3. mysql数据迁移数据一致性检教6_如何在数据库迁移中保证数据一致性?
  4. 过程的首要目的是好的结果
  5. like ,order 使用索引
  6. ajax17,17个使用AJAX技术的数据表格控件
  7. Linux系统编程--2(环境变量,进程控制)
  8. MySQL 插入数据时,中文乱码???问题的解决
  9. 多期高收入的C++on-job学员
  10. 【知识索引】【汇编语言】
  11. android json解析歌词,网易云歌词获取
  12. 计算机总是提醒更新,联想电脑老提示更新怎么办啊
  13. 利用Medium的CDN来改善Feed的页面加载时间
  14. Josh 的学习笔记之数字通信(Part 1——信号和频谱)
  15. Freemarker+Fmpp简介
  16. Navy maneuvers(dfs)
  17. PyTorch聊天机器人(一)
  18. 五、DMSP/OLS和NPP/VIIRS夜间灯光数据拟合校正
  19. 创新工厂面试题详解:共打了多少鱼
  20. 龙腾国产液晶面板15寸LCD工控显示屏M150GNN2 R1 规格书

热门文章

  1. 获得100000+点击的程序员高薪职业建议!
  2. 智能手机销售网后台管理系统手机销售网程序设计
  3. Multimedia Standards Introduction——专业术语
  4. UltraISO制作U盘启动盘安装Windows系统攻略
  5. day26-多进程多线程
  6. 数据结构与算法——给定整数A1,A2,....An,....(可能有负数),求该数据序列的最大子序列的和
  7. 德州扑克实践之三-----比较大小
  8. SAP ABAP BDC(批量数据通信)-018
  9. 通过一个具体的例子,讲解 SAP BDC 技术的使用步骤
  10. Novavax和武田宣布在日本合作Novavax的COVID-19候选疫苗