之前做了基于vue-simple-uploader大文件的大文件上传,目前新的需求是把音频也进行大文件形式上传,
那么上传的时候需要进行字段校验上传的文件是视频还是音频,本文将针对这一点进行操作
1、我们通过选择框选择视频还是音频进行页面的显示,字段form.courseType,2是视频,3是音频
2、为uploader-btn标签添加id
3、注意不可以这么写
<uploader-btn :attrs="form.courseType == 2?attrs:attrs1" v-show="false" ref="upload">选择{{form.courseType == 2?'视频':'音频'}}文件</uploader-btn>
原因是还没等进行判断courseType 类型标签已经渲染结束,无法通过courseType 的改变进行动态渲染
<uploader
ref="uploader1"
:options="options"
:file-status-text="fileStatusText"
:autoStart="false"
@upload-start="onUploadStart"
@file-added="onFileAdded"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
class="uploader-example">
<uploader-unsupport></uploader-unsupport>
<!-- <p>Drop files here to upload or</p> -->
<el-button size="small" @click="beforeUploade">点击上传</el-button>
<div>{{form.courseType == 2?'只能上传mp4,mov,avi格式':'上传音频格式的文件'}}</div>
<div v-show="form.courseType == 2">
<uploader-btn :attrs="attrs" v-show="false" id="shipin" ref="upload">选择{{form.courseType == 2?'视频':'音频'}}文件</uploader-btn>
</div>
<div v-show="form.courseType == 3">
<uploader-btn :attrs="attrs1" v-show="false" id="yinpin" ref="upload1">选择{{form.courseType == 2?'视频':'音频'}}文件</uploader-btn>
</div>
<!-- <uploader-btn :directory="true">select folder</uploader-btn> -->
<uploader-list v-show="!form.videoUrl"></uploader-list>
<div v-show="form.videoUrl">{{form.videoUrl}}</div>
</uploader>
upload.js下
1、添加音频选择文件
2、上传前针对input的value置空,允许input框重复上传同一个文件
3、在onFileAdded(file)下做文件上传前的校验
data(){
return {
// 文件上传参数
uploaderInstance:undefined,
options: {
headers: { Authorization: "Bearer " + getToken() },
// target: process.env.VUE_APP_BASE_API + "/file?type=1",
target: process.env.VUE_APP_BASE_API + "/bigfile/upload",
testChunks: false,
chunkSize: 1024*1024*5, //5MB
simultaneousUploads: 3, //并发上传数
maxChunkRetries: 2, //最大自动失败重试上传次数
parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化时间
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
},
testChunks: true, //开启服务端分片校验
// 服务器分片校验函数
checkChunkUploadedByResponse: (chunk, message) => {
let obj = JSON.parse(message);
// console.log('sss',chunk,message,obj)
if (obj.data.isExist=='true') {
console.log('aaa')
this.statusTextMap.success = '秒传文件,处理中····';
this.form.videoUrl = obj.data.url
return true;
}
// return (obj.uploaded || []).indexOf(chunk.offset + 1) >= 0
return obj.data.uploaded >chunk.offset + 1
},
},
statusTextMap: {
success: '文件处理中···',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...',
cmd5: '准备中...'
},
fileStatusText: (status, response) => {
return this.statusTextMap[status];
},
attrs: {
accept: 'video/*',
// multiple: false,
// multipleLimit:1
},
++ attrs1: {
accept: 'audio/*',
// multiple: false,
// multipleLimit:1
},
}
},
beforeUploade(){
// if(this.$refs.uploader1.files.length>1){
// console.log('文件列表1',this.$refs.uploader1.files,this.$refs.uploader1.fileList)
// // this.$refs.uploader1.files.shift()
// this.$refs.uploader1.uploader.cancel()
// // this.$refs.uploader1.uploader.pause(this.$refs.uploader1.files[0])
// // this.$refs.uploader1.uploader.removeFile(this.$refs.uploader1.files[0])
// // this.$refs.uploader1.uploader.fileRemoved(this.$refs.uploader1.files[0])
// }
// if(this.$refs.uploader1.fileList.length>1){
// console.log('文件列表2',this.$refs.uploader1.files,this.$refs.uploader1.fileList)
// this.$refs.uploader1.uploader.cancel()
// }
// document.querySelector('.uploader-btn>input').value=''
// console.log('1111',this.$refs.uploader1.uploader.cancel)
this.$refs.uploader1.uploader.cancel()
this.form.videoUrl=''
if(this.form.courseType == 2){
document.querySelector('#shipin>input').nodeValue=''
document.querySelector('#shipin>input').click()
}else{
document.querySelector('#shipin>input').nodeValue=''
document.querySelector('#yinpin>input').click()
}
},
onFileAdded(file) { // 文件上传前的校验
console.log(file)
if(this.form.courseType == 2&&file.fileType.indexOf('video')==-1){
console.log('上传的不是视频')
this.form.videoUrl=''
this.$message.warning(this.form.courseType == 2?'请上传正确的视频类型':'请上传正确的音频类型')
setTimeout(() => {
this.$refs.uploader1.uploader.removeFile(file)
}, 0);
return
}
if(this.form.courseType == 3&&file.fileType.indexOf('audio')==-1){
console.log('上传的不是音频')
this.form.videoUrl=''
this.$message.warning(this.form.courseType == 2?'请上传正确的视频类型':'请上传正确的音频类型')
setTimeout(() => {
this.$refs.uploader1.uploader.removeFile(file)
}, 0);
return
}
this.computeMD5(file);
},
注意:
setTimeout(() => {
this.$refs.uploader1.uploader.removeFile(file)
}, 0);
import uploader from 'vue-simple-uploader'
Vue.use(uploader)
<uploader
ref="uploader1"
:options="options"
:file-status-text="fileStatusText"
:autoStart="false"
@upload-start="onUploadStart"
@file-added="onFileAdded"
@file-progress="onFileProgress"
@file-success="onFileSuccess"
@file-error="onFileError"
class="uploader-example">
<uploader-unsupport></uploader-unsupport>
<!-- <p>Drop files here to upload or</p> -->
<el-button size="small" @click="beforeUploade">点击上传</el-button>
<div>{{form.courseType == 2?'只能上传mp4,mov,avi格式':'上传音频格式的文件'}}</div>
<div v-show="form.courseType == 2">
<uploader-btn :attrs="attrs" v-show="false" id="shipin" ref="upload">选择{{form.courseType == 2?'视频':'音频'}}文件</uploader-btn>
</div>
<div v-show="form.courseType == 3">
<uploader-btn :attrs="attrs1" v-show="false" id="yinpin" ref="upload1">选择{{form.courseType == 2?'视频':'音频'}}文件</uploader-btn>
</div>
<!-- <uploader-btn :directory="true">select folder</uploader-btn> -->
<uploader-list v-show="!form.videoUrl"></uploader-list>
<div v-show="form.videoUrl">{{form.videoUrl}}</div>
</uploader>
import { upload } from '@/assets/mixins/upload.js'
mixins : [ upload ],
upload.js
import SparkMD5 from 'spark-md5';
import { getToken } from "@/utils/auth";
import { bigFile } from "@/api/course";
export const upload = {
data(){
return {
// 文件上传参数
uploaderInstance:undefined,
options: {
headers: { Authorization: "Bearer " + getToken() },
// target: process.env.VUE_APP_BASE_API + "/file?type=1",
target: process.env.VUE_APP_BASE_API + "/bigfile/upload",
testChunks: false,
chunkSize: 1024*1024*5, //5MB
simultaneousUploads: 3, //并发上传数
maxChunkRetries: 2, //最大自动失败重试上传次数
parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) { //格式化时间
return parsedTimeRemaining
.replace(/\syears?/, '年')
.replace(/\days?/, '天')
.replace(/\shours?/, '小时')
.replace(/\sminutes?/, '分钟')
.replace(/\sseconds?/, '秒')
},
testChunks: true, //开启服务端分片校验
// 服务器分片校验函数
checkChunkUploadedByResponse: (chunk, message) => {
let obj = JSON.parse(message);
// console.log('sss',chunk,message,obj)
if (obj.data.isExist=='true') {
console.log('aaa')
this.statusTextMap.success = '秒传文件,处理中····';
this.form.videoUrl = obj.data.url
return true;
}
// return (obj.uploaded || []).indexOf(chunk.offset + 1) >= 0
return obj.data.uploaded >chunk.offset + 1
},
},
statusTextMap: {
success: '文件处理中···',
error: '上传出错了',
uploading: '上传中...',
paused: '暂停',
waiting: '等待中...',
cmd5: '准备中...'
},
fileStatusText: (status, response) => {
return this.statusTextMap[status];
},
attrs: { // 视频
accept: 'video/*',
// multiple: false,
// multipleLimit:1
},
attrs1: { // 音频
accept: 'audio/*',
// multiple: false,
// multipleLimit:1
},
}
},
methods: {
onUploadStart(file){
// this.uploaderInstance = this.$refs.uploader1.uploader
// this.uploaderInstance.cancel()
},
beforeUploade(){
// if(this.$refs.uploader1.files.length>1){
// console.log('文件列表1',this.$refs.uploader1.files,this.$refs.uploader1.fileList)
// // this.$refs.uploader1.files.shift()
// this.$refs.uploader1.uploader.cancel()
// // this.$refs.uploader1.uploader.pause(this.$refs.uploader1.files[0])
// // this.$refs.uploader1.uploader.removeFile(this.$refs.uploader1.files[0])
// // this.$refs.uploader1.uploader.fileRemoved(this.$refs.uploader1.files[0])
// }
// if(this.$refs.uploader1.fileList.length>1){
// console.log('文件列表2',this.$refs.uploader1.files,this.$refs.uploader1.fileList)
// this.$refs.uploader1.uploader.cancel()
// }
// document.querySelector('.uploader-btn>input').value=''
// console.log('1111',this.$refs.uploader1.uploader.cancel)
this.$refs.uploader1.uploader.cancel()
this.form.videoUrl=''
if(this.form.courseType == 2){
document.querySelector('#shipin>input').nodeValue=''
document.querySelector('#shipin>input').click()
}else{
document.querySelector('#shipin>input').nodeValue=''
document.querySelector('#yinpin>input').click()
}
},
onFileAdded(file) { // 文件上传前的校验
console.log(file)
if(this.form.courseType == 2&&file.fileType.indexOf('video')==-1){
console.log('上传的不是视频')
this.form.videoUrl=''
this.$message.warning(this.form.courseType == 2?'请上传正确的视频类型':'请上传正确的音频类型')
setTimeout(() => {
this.$refs.uploader1.uploader.removeFile(file)
}, 0);
return
}
if(this.form.courseType == 3&&file.fileType.indexOf('audio')==-1){
console.log('上传的不是音频')
this.form.videoUrl=''
this.$message.warning(this.form.courseType == 2?'请上传正确的视频类型':'请上传正确的音频类型')
setTimeout(() => {
this.$refs.uploader1.uploader.removeFile(file)
}, 0);
return
}
if(file.size/1024/1024>200){ // 文件不能大于200M
this.form.videoUrl=''
this.$message.warning('文件大小不能超过200M')
setTimeout(() => {
this.$refs.uploader1.uploader.removeFile(file)
}, 0);
return
}
this.computeMD5(file);
},
//计算MD5
computeMD5(file) {
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice,
chunkSize = 1024*1024*5,
chunks = Math.ceil(file.size / chunkSize),
currentChunk = 0,
spark = new SparkMD5.ArrayBuffer(),
fileReader = new FileReader();
let time = new Date().getTime();
file.cmd5 = true;
fileReader.onload = (e) => {
spark.append(e.target.result); // Append array buffer
currentChunk++;
if (currentChunk < chunks) {
//console.log(`第${currentChunk}分片解析完成, 开始第${currentChunk +1} / ${chunks}分片解析`);
let percent = Math.floor(currentChunk / chunks * 100);
file.cmd5progress = percent;
loadNext();
} else {
console.log('finished loading');
let md5 = spark.end();
console.log(`MD5计算完成:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${file.size} 用时:${new Date().getTime() - time} ms`);
spark.destroy(); //释放缓存
file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
file.cmd5 = false; //取消计算md5状态
file.resume(); //开始上传
}
};
fileReader.onerror = () => {
console.warn('oops, something went wrong.');
file.cancel();
};
let loadNext = () => {
let start = currentChunk * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
};
loadNext();
},
// 文件进度的回调
onFileProgress(rootFile, file, chunk) {
console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
},
onFileSuccess(rootFile, file, response, chunk) {
let resp = JSON.parse(response);
console.log('resp',resp)
if(resp.data&&resp.data.isExist=='true'){
return
}
//合并分片
// if (resp.code === 0 && resp.merge === true) {
bigFile({
filename: file.name,
identifier: file.uniqueIdentifier,
// identifier: '9273dc4d57d39f382b53e02b3fbdcd5c',
totalSize: file.size,
totalChunks: chunk.offset + 1
}).then((res)=>{
console.log('res',res)
if (res.code === 200) {
this.form.videoUrl = res.msg
console.log('上传成功')
} else {
console.log(res.message);
}
})
.catch(function(error){
console.log(error);
});
// }
},
onFileError(rootFile, file, response, chunk) {
console.log('Error:', response)
},
},
}