vue切片上传大视频 组件
uploadVideo.vue
<template>
<div id="app">
<div>
<button type="button" class="h-btn" @click="choiceImg"><i class="h-icon-upload"></i></button>
<input type="file" ref="FileInput" @change="handleFiles" :accept="accept" style="display:none;" />
<div v-if="showCopy&&url!=''" class="h-input-group">
<input type="text" v-model="url" placeholder="" /><Button @click="copyText" color="primary">复制</Button>
</div>
<p v-if="percent">上传进度{{percent}}%,视频大小{{videosize}}MB</p>
</div>
</div>
</template>
<script>
import axios from 'axios';
const LENGTH = 1024 * 1024;
export default {
props:{
showCopy:{
type:Boolean,
default:true,
},
threadsNum:{
type: Number,
default: 4
},
accept:{
type: String,
default:'video/mp4'
}
},
computed:{
videosize(){
return (this.size/(1024*1024)).toFixed(2);
},
percent(){
if(this.fileParts.length==0){
return 0;
}else{
return (100*this.counts/(this.fileParts.length+1)).toFixed(2);
}
}
},
name: 'app',
data () {
return {
url:'',
fileName:'',
status:'normal',
exist:0,
md5:'',
md5file:'',
size:0,
uid:'',
counts:0,
ossParts:[],
fileParts:[],
error:null
}
},
watch:{
counts(val){
if(val!=0){
if(val == this.fileParts.length){
if(this.exist==0){
this.uploadSlice(-1)
}
}
}
}
},
methods:{
choiceImg(){
this.$refs.FileInput.dispatchEvent(new MouseEvent('click'));
},
copyText() {
this.$Clipboard({
text: this.url
});
},
selectImg(){
this.$refs.FileInput.click()
},
handleFiles() {
let file = this.$refs.FileInput.files[0];
//预览
this.counts = 0
this.exist = 0
this.md5 = '';
this.fileName = file.name;
this.uid = this.uuid();
this.sliceFile(file)
},
sliceFile(file){
this.fileParts = [];
this.ossParts = [];
let start = 0;
let end = 0;
let max = file.size;
this.size = max;
while(end<=max){
start = end;
end = start + LENGTH;
let file_blob = file.slice(start,end);
this.fileParts.push({blob:file_blob});
}
this.uploadSlice(0)
},
uuid(){
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4";
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
},
updateMedia(url){
R.Media.Store({file:url}).then(resp => {
});
},
uploadSlice(index){
if(index>=this.fileParts.length){
return
}
var formdata=new FormData();
let config = {
headers:{'Content-Type':'multipart/form-data'}
}; //添加请求头
let fileName = this.fileName
formdata.append('uid',this.uid);
formdata.append('size',this.size);
formdata.append('total',this.fileParts.length);
formdata.append('fileName',fileName);
formdata.append('md5',this.md5);
formdata.append('md5file',this.md5file);
if(index>=0){
let blobPart = this.fileParts[index].blob
formdata.append('index',index);
formdata.append('file',blobPart);
}else{
formdata.append('counts',this.counts);
formdata.append('ossParts',this.ossParts);
}
let that = this
axios.post('/uploadvideo.php',formdata,config)
.then((resource) => {
let res = resource
if(resource.status!=200){
console.log('uploadfail')
this.md5 = '';
this.status = 'wrong'
return
}else{
if(index>=0){
//this.ossParts[res.data.index] = res.data.part;
if(index==0){
if(typeof(res.data.exist)!='undefined' && res.data.exist==1){
this.exist = 1
this.counts = this.fileParts.length + 1
let msg = {size:this.videosize,url:res.data.url};
this.url = res.data.url
this.md5 = '';
this.updateMedia(res.data.url);
console.log(msg);
this.$emit('success', msg);
}else{
this.md5 = res.data.md5
this.md5file = res.data.md5file
this.counts++
for (var i = 1; i < this.threadsNum; i++) {
this.uploadSlice(i)
}
}
}else{
this.counts++
this.uploadSlice(index+this.threadsNum-1)
}
}else{
if(res.data.return==0){
this.counts++
this.status = 'success'
let msg = {size:this.videosize,url:res.data.url};
this.url = res.data.url
this.md5 = '';
this.updateMedia(res.data.url);
this.$emit('success', msg);
}else{
console.log('uploadfail')
}
}
}
})
.catch(function (error) {
that.error = error
});
},
}
};
</script>