詳解vue大文件視頻切片上傳的處理方法
前端上傳大文件、視頻的時候會出現(xiàn)超時、過大、很慢等情況,為了解決這一問題,跟后端配合做了一個切片的功能。
我這個切片功能是基于 minion 的,后端會把文件放在minion服務(wù)器上。具體看后端怎么做
1、在項目的 util(這個文件夾是自己創(chuàng)建的,如果項目里沒有可以自行創(chuàng)建) 文件家中創(chuàng)建一個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) // 總片數(shù) // 獲取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("總片數(shù)" + chunkCount) // console.log("分片后的數(shù)據(jù)---測試:" + i) // console.log(chunk) let fileUrl = urlList[i]; // console.log(fileUrl,'地址'); uploadChunk({ chunk, currentChunk: i, chunkCount, fileUrl }) } } const uploadChunk = (chunkInfo) => { // 上傳請求方式1 (根據(jù)自身情況自行選擇) 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 { // 當總數(shù)大于等于分片個數(shù)的時候 if ((chunkInfo.currentChunk + 1) == chunkInfo.chunkCount) { // console.log("文件開始------合并成功") success(res.data[0]) } } } }).catch((e) => { console.log('失敗!'); error && error(e) }); // 上傳請求方式2 (根據(jù)自身情況自行選擇) /*let config = { headers: { 'Content-Type': 'multipart/form-data' } } console.log(chunkInfo,'chunkInfochunkInfo'); 創(chuàng)建formData對象,下面是結(jié)合不同項目給后端傳入的對象。 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) { // 結(jié)合不同項目 將成功的信息返回出去,這里可變的是指 res.data[0] success(res.data[0]) // 下面如果在項目中沒有用到可以不用打開注釋 // if (chunkInfo.currentChunk < chunkInfo.chunkCount - 1) { // console.log("分片上傳成功") // } else { // // 當總數(shù)大于等于分片個數(shù)的時候 // if ((chunkInfo.currentChunk + 1) == chunkInfo.chunkCount) { // console.log("文件開始------合并成功") // success(res.data[0]) // } // } } else { console.log(res.message) } }).catch((e) => { error && error(e) })*/ } readFileMD5() // 開始執(zhí)行代碼 }
js-md5 如果沒有的話需要自己在項目里安裝:
npm install js-md5
2、創(chuàng)建一個上傳視頻文件的公共組件,便于不同地方引用,如下:
<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, // 動態(tài)顯示進度條 progressFlag: false, // 關(guān)閉進度條 } }, created(){ }, props:{ paramsData: { type: Object, default: {} } }, methods: { // 選擇視頻 handleChange(file, fileList) { this.progressFlag = true; // 顯示進度條 this.loadProgress = 25; // 動態(tài)獲取文件上傳進度 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) => { // 調(diào)用后端接口,后端會返回所有切片的路徑,及其他參數(shù) this.loadProgress = 50; this.listUrl = res.data.data.partUrlList; this.uploadId = res.data.data.uploadId; this.fileNameVal = res.data.data.fileName // 調(diào)用切片方法 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('發(fā)生錯誤,請重新上傳!') this.progressFlag = false }) }, // 整合切片文件(最后調(diào)用接口整合所有切片進行合并) 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) // 一秒后關(guān)閉進度條 } }).catch(() => { this.$message.error('視頻合并上傳失敗,請重新上傳!') }) }, }, } </script> <style scoped lang="scss"> </style>
具體根據(jù)自己的實際情況進行修改即可!
到此這篇關(guān)于詳解vue大文件視頻切片上傳的處理方法的文章就介紹到這了,更多相關(guān)vue大文件視頻切片上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue讀取本地靜態(tài).md并側(cè)邊欄導(dǎo)航跳轉(zhuǎn)、展示.md文件的操作方法
這篇文章主要介紹了Vue讀取本地靜態(tài).md并側(cè)邊欄導(dǎo)航跳轉(zhuǎn)、展示.md文件,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08vue2基本響應(yīng)式實現(xiàn)方式之讓數(shù)組也變成響應(yīng)式
這篇文章主要介紹了vue2基本響應(yīng)式實現(xiàn)方式之讓數(shù)組也變成響應(yīng)式問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04vue3中element-plus?icon圖標的正確使用姿勢
element-plus官方提示,Icon圖標正在向SVG?Icon遷移,之前使用的Font?Icon即將被棄用,下面這篇文章主要給大家介紹了關(guān)于vue3中element-plus?icon圖標的正確使用姿勢,需要的朋友可以參考下2022-03-03