首页 > 其他分享 >详解vue大文件视频切片上传的处理方法

详解vue大文件视频切片上传的处理方法

时间:2023-10-21 10:13:11浏览次数:32  
标签:vue console log chunkInfo res 详解 file 上传

前端上传大文件、视频的时候会出现超时、过大、很慢等情况,为了解决这一问题,跟后端配合做了一个切片的功能,接下来就详细的给大家介绍一下vue大文件视频切片上传的处理方法,需要的朋友可以参考下  

前端上传大文件、视频的时候会出现超时、过大、很慢等情况,为了解决这一问题,跟后端配合做了一个切片的功能。

我这个切片功能是基于 minion 的,后端会把文件放在minion服务器上。具体看后端怎么做

1、在项目的 util(这个文件夹是自己创建的,如果项目里没有可以自行创建) 文件家中创建一个js文件 upload.js   在js文件中添加如下代码:

import axios from 'axios';
import md5 from 'js-md5' //引入MD5加密
export const uploadByPieces = ({ urlList, file, pieceSize, progress, success, error }) => {
// 如果文件传入为空直接 return 返回
if (!file) return
let fileMD5 = ''// 总文件列表
const chunkSize = pieceSize * 1024 * 1024 // 5MB一片
const chunkCount = Math.ceil(file.size / chunkSize) // 总片数
// 获取md5
const readFileMD5 = () => {
// 读取视频文件的md5
// console.log("获取文件的MD5值")
let fileRederInstance = new FileReader()
// console.log('file', file)
fileRederInstance.readAsBinaryString(file)
fileRederInstance.addEventListener('load', e => {
let fileBolb = e.target.result
fileMD5 = md5(fileBolb)
// console.log('fileMD5', fileMD5)
// console.log("文件未被上传,将分片上传")
readChunkMD5()
})
}
const getChunkInfo = (file, currentChunk, chunkSize) => {
let start = currentChunk * chunkSize
let end = Math.min(file.size, start + chunkSize)
let chunk = file.slice(start, end)
return { start, end, chunk }
}
// 针对每个文件进行chunk处理
const readChunkMD5 = () => {
// 针对单个文件进行chunk上传
for (var i = 0; i < chunkCount; i++) {
const { chunk } = getChunkInfo(file, i, chunkSize)
// console.log("切片地址123" + urlList)
// console.log("总片数" + chunkCount)
// console.log("分片后的数据---测试:" + i)
// console.log(chunk)
let fileUrl = urlList[i];
// console.log(fileUrl,'地址');
uploadChunk({ chunk, currentChunk: i, chunkCount, fileUrl })
}
}
const uploadChunk = (chunkInfo) => {
// 上传请求方式1 (根据自身情况自行选择)
axios({
method: 'put',
url: chunkInfo.fileUrl,
}).then((res) => {
// console.log("分片上传返回信息:"+ res)
// console.log(res.status)
if (res.status == 200) {
// success(res.data[0])
// 下面如果在项目中没有用到可以不用打开注释
if (chunkInfo.currentChunk < chunkInfo.chunkCount - 1) {
// console.log("分片上传成功")
} else {
// 当总数大于等于分片个数的时候
if ((chunkInfo.currentChunk + 1) == chunkInfo.chunkCount) {
// console.log("文件开始------合并成功")
success(res.data[0])
}
}
}
}).catch((e) => {
console.log('失败!');
error && error(e)
});
// 上传请求方式2 (根据自身情况自行选择)
/*let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
console.log(chunkInfo,'chunkInfochunkInfo');
创建formData对象,下面是结合不同项目给后端传入的对象。
let fetchForm = new FormData()
fetchForm.append('identifier', randoms)
fetchForm.append('chunkNumber', chunkInfo.currentChunk + 1)
fetchForm.append('chunkSize', chunkSize)
fetchForm.append('currentChunkSize', chunkInfo.chunk.size)
fetchForm.append('file', chunkInfo.chunk)
fetchForm.append('filename', file.name)
fetchForm.append('totalChunks', chunkInfo.chunkCount)
fetchForm.append('totalSize', chunkSize)
fetchForm.append('md5', fileMD5)
api.queryUploadUploadAllFileLink(fetchForm, config).then(res => {
console.log("分片上传返回信息:"+ res)
if (res.code == 200) {
// 结合不同项目 将成功的信息返回出去,这里可变的是指 res.data[0]
success(res.data[0])
// 下面如果在项目中没有用到可以不用打开注释
// if (chunkInfo.currentChunk < chunkInfo.chunkCount - 1) {
// console.log("分片上传成功")
// } else {
// // 当总数大于等于分片个数的时候
// if ((chunkInfo.currentChunk + 1) == chunkInfo.chunkCount) {
// console.log("文件开始------合并成功")
// success(res.data[0])
// }
// }
}
else {
console.log(res.message)
}
}).catch((e) => {
error && error(e)
})*/
}
readFileMD5() // 开始执行代码
}

js-md5 如果没有的话需要自己在项目里安装:

npm install js-md5

2、创建一个上传视频文件的公共组件,便于不同地方引用,如下:

<template>
<div class="container" style="display:inline-block;width: 200px;">
<el-upload
class="upload-demo"
action="#"
:multiple="false"
:auto-upload="false"
accept=".mp4"
:on-change="handleChange"
:show-file-list="false">
<el-button slot="trigger" size="small" type="primary">选择视频</el-button>
<!-- <el-button size="small" type="primary" @click="uploadVideo()" style="margin-left: 10px;">开始上传</el-button> -->
</el-upload>
<!-- 进度条 -->
<el-progress v-if="progressFlag" :percentage="loadProgress"></el-progress>
</div>
</template>
<script>
import { uploadByPieces } from '@/util/upload'
import api from "@/api/mes2/index-lhj"
export default {
data() {
return {
loadingFile1: false,
uploadId: '', // 切片视频的唯一id(后端返回)
fileNameVal: '', // 文件名称(后端返回)
listUrl: [], // 切片路径集合
loadProgress: 0, // 动态显示进度条
progressFlag: false, // 关闭进度条
}
},
created(){
},
props:{
paramsData: {
type: Object,
default: {}
}
},
methods: {
// 选择视频
handleChange(file, fileList) {
this.progressFlag = true; // 显示进度条
this.loadProgress = 25; // 动态获取文件上传进度
let params = {
fileName: file.name,
partCount: 3,
fileType: "mp4",
fileSize: file.size,
sourceId: this.paramsData.id,
sourceType: this.paramsData.inspectionType,
sourceSystem: "MES2",
hierarchyCode:"MES2"
}
api.queryUploadBigFileUrl(params).then((res) => { // 调用后端接口,后端会返回所有切片的路径,及其他参数
this.loadProgress = 50;
this.listUrl = res.data.data.partUrlList;
this.uploadId = res.data.data.uploadId;
this.fileNameVal = res.data.data.fileName
// 调用切片方法
uploadByPieces({
urlList: this.listUrl,
file: file.raw, // 视频实体
pieceSize: 5, // 分片大小
success: data => {
// console.log('分片上传视频成功', data)
this.loadProgress = 75;
this.getFileAll()
},
error: e => {
console.log('分片上传视频失败', e)
this.$message.error('视频切片上传失败,请重新上传!')
}
})
}).catch(() => {
this.$message.error('发生错误,请重新上传!')
this.progressFlag = false
})
},
// 整合切片文件(最后调用接口整合所有切片进行合并)
getFileAll(){
let params = {
partCount: 3,
tenantId: this.userInfo.tenant_id,
uploadId: this.uploadId,
fileName: this.fileNameVal,
}
this.loadProgress = 95;
api.queryUploadBigFile(params).then(() => {
this.loadProgress = 100;
this.$message.success('视频上传成功!')
if (this.loadProgress >= 100) {
this.loadProgress = 100
setTimeout( () => {this.progressFlag = false}, 1000) // 一秒后关闭进度条
}
}).catch(() => {
this.$message.error('视频合并上传失败,请重新上传!')
})
},
},
}
</script>
<style scoped lang="scss">
</style>

具体根据自己的实际情况进行修改即可!

 

参考文章:http://blog.ncmem.com/wordpress/2023/10/21/%e8%af%a6%e8%a7%a3vue%e5%a4%a7%e6%96%87%e4%bb%b6%e8%a7%86%e9%a2%91%e5%88%87%e7%89%87%e4%b8%8a%e4%bc%a0%e7%9a%84%e5%a4%84%e7%90%86%e6%96%b9%e6%b3%95/

欢迎入群一起讨论

 

 

标签:vue,console,log,chunkInfo,res,详解,file,上传
From: https://www.cnblogs.com/songsu/p/17778516.html

相关文章

  • Makefile详解—clean
    每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。这是一个“修养”。一般的风格都是: clean:rmedit$(objects) 更为稳健的做法是: .PHONY:cleanclean:-rmedit$(objects) 前面说过,.PHONY意思表示clean是一......
  • SpringBoot Vue3打造企业级一体化SaaS系统[最新版完结]
    点击下载:SpringBoot+Vue3打造企业级一体化SaaS系统     提取码:3ixbSpringBoot和Vue3是目前十分盛行的JavaWeb开发技术栈。SpringBoot能够快速构建Web应用程序,并提供许多有用的功用,如自动配置、快速开发、高效性能、易于部署等。Vue3是一种盛行的前端框架,它能够协助开发......
  • markdown上传csdn调整插入图片大小及位置
    @目录前言1csdn插入图片1.1<img不显示图片?不能使用?2csdn带尺寸的图片3csdn移动图片位置并且带尺寸前言关于markdown上传csdn无法显示本地图片的问题请看我的另一篇文章【2023最新教程】解决markdown上传csdn无法显示本地图片的问题本文章讲叙了自己在markdown上传cs......
  • 上传超大文件到云端服务器
    一直以来,通过互联网传送超大文件都是个麻烦事,传统的SSH/FTP工具只适合传输不太大的文件和目录,遇到上G的文件经常会出现传输错误,常用手段如百度云在Linux服务器上没法使用,一些专业传输软件需要在服务端安装开端口,而我们日常遇到的超大文件越来越多,linux的安装包要几个G,docker镜像要......
  • Vue前端框架
    Vue渐进式javacript框架插件可选安装-谷歌访问助手这是一个谷歌浏览器上的插件安装必安插件(文件夹)下的google-access-helper-2.3.0(文件夹)复制到你想放的文件夹下(安装后不可以挪动位置)建议D盘下,弄一个专门按软件的文件夹打开谷歌浏览器-扩展程序-开......
  • Vue.js设计与实现 pdf电子版 霍春阳
    Vue.js设计与实现pdf电子版霍春阳作者: 霍春阳出版年: 2022-2-10ISBN: 9787115583864连接提取码:yfji干货密度极高,作者写技术文章确实有一套。既有API设计的背景分析,又有规范级别的细节讲解,看完后基本能从头写一个Vue3出来了。......
  • php提高文件上传速度
    PHP用超级全局变量数组$_FILES来记录文件上传相关信息的。1.file_uploads=on/off是否允许通过http方式上传文件2.max_execution_time=30允许脚本最大执行时间,超过这个时间就会报错3.memory_limit=50M设置脚本可以分配的最大内存量,防止失控脚本占用过多内存,此指令只有在编译......
  • 6基于SpringBoot + Vue 的超市进销存系统-计算机毕业设计源码+LW文档
    摘 要 超市管理系统是指一种针对超市的信息化管理系统,它通过计算机技术和网络技术,对超市的采购、销售、库存等业务进行管理和控制。随着社会经济的发展和人们生活水平的提高,超市已经成为人们日常生活中必不可少的消费场所,而超市管理系统的出现则极大地提高了超市的经营效率和......
  • Vue3 typescript script setup获取范型组件的ref
    原博客地址:https://juejin.cn/post/7247433208437850169?from=search-suggest在typescript下,如果想获取带类型的组件模板引用,官方文档中说明了方式:https://cn.vuejs.org/guide/typescript/composition-api.html#typing-component-template-refsconstmodal=ref<InstanceTy......
  • tcp/ip协议和opc协议对比详解
    TCP/IP协议和OPC协议是两种重要的网络协议,它们在不同的网络层级上运行,并为数据传输和通信提供了不同的功能。TCP/IP协议(TransmissionControlProtocol/InternetProtocol,传输控制协议/互联网协议)是互联网通信的基础协议,它定义了互联网中数据传输的基本规则和标准。TCP/IP协议包括......