Home

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>