2021-8-6 重写上传视频

93

<template>
  <div>
    <a-modal v-model:visible="modalVisible" title="上传Graph测试视频" :destroyOnClose="true">
      <div class="graph-modal-form-item">
        <div class="graph-modal-form-item-label">待测Graph:</div>
        {{ record.name }}
      </div>
      <div style="display:flex;flex-direction: row;">
        <div class="graph-modal-form-item-label">
          上传测试视频:
        </div>
        <UploadToOss
          selectfilesId="idd"
          @returnFileSrc="returnFileSrc($event)"
          @deleteAllFile="deleteAllFile(a)"
          type="file"
          key="id"
          fileType="mp4"
          :md5="true"
        />
      </div>
      <template #footer>
        <a-button @click="sendUrl" type="primary">确定</a-button>
      </template>
    </a-modal>
    <a-modal v-model:visible="success" title="上传成功"
      ><div style="display:flex;justify-content:center">
        <CheckCircleTwoTone
          :style="{ fontSize: '80px' }"
          twoToneColor="#52c41a"
        />
      </div>
      <div style="display:flex;justify-content:center;margin-top:15px">
        正在测试模型,测试过程需要一段时间,完成后将邮件告知您
      </div>
      <template #footer>
        <a-button @click="success = false" type="primary">确定</a-button>
      </template></a-modal
    >
  </div>
</template>
<script>
import UploadToOss from '@/components/UploadToOss.vue'
import { CheckCircleTwoTone } from '@ant-design/icons-vue'
import { sendVideoUrl } from '@/requests'
export default {
  data () {
    return {
      success: false,
      modalVisible: false,
      record: {},
      url: ''
    }
  },
  components: {
    CheckCircleTwoTone,
    UploadToOss
  },
  methods: {
    open (record) {
      this.modalVisible = true
      this.record = record
      // console.log('openrecord', record)
    },
    returnFileSrc (url) {
      this.url = url
    },
    deleteAllFile () {
      this.url = ''
    },
    sendUrl () {
      if (this.url) {
        sendVideoUrl()
          .then(res => {
            console.log(res)
            this.modalVisible = false
            this.success = true
          })
          .catch(error => {
            this.$message.error(error)
          })
      } else {
        this.$message.error('请上传视频文件')
      }
    }
  }
}
</script>

<style scoped></style>

还是要先把视频文件上传到阿里云oss上返回一个url地址,再把这个地址发给后端。

<template lang="html">
  <div style="max-width: 500px;">
    <div v-if="currentStatus === 'before upload'">
      <a-button @click="doUpload" :disabled="disabled">{{btnText}}</a-button>
      <div class="desc">
        <span>只允许上传&nbsp;.{{allowFileType}}&nbsp;格式文件</span>
        <a-tooltip placement="right" v-if="fileDesc">
          <template #title>
            <span>{{fileDesc}}</span>
          </template>
          <QuestionCircleOutlined style="margin-left: 6px;"/>
        </a-tooltip>
      </div>
      <!-- {{fileDesc}} -->
    </div>
    <div id="container">
      <div
        hidden
        :id="selectfilesId"
        class="btn"
        :disabled="startUpload || files_array.length === 1"
      ></div>
      <a-progress style="width: 80%; min-width: 260px;" v-if="currentStatus === 'uploading'" :percent="upload_progress" size="small" status="active" />
      <div v-if="originalFileName" style="display: flex; align-items: center;">
        <span class="file-url">
          <a-tooltip>
            <template #title>{{originalFileName}}</template>
            {{ originalFileName }}
          </a-tooltip>
        </span>
        <DeleteOutlined style="cursor: pointer; margin-left: 10px;" @click="clearFiles" /></div>
    </div>
  </div>
</template>

<script>
import plupload from 'plupload'
import SparkMD5 from 'spark-md5'
import { DeleteOutlined, QuestionCircleOutlined } from '@ant-design/icons-vue'
function calculate (file, callBack) {
  const fileReader = new FileReader()
  const blobSlice =
      File.prototype.mozSlice ||
      File.prototype.webkitSlice ||
      File.prototype.slice
  const chunkSize = 2097152
  // read in chunks of 2MB
  const chunks = Math.ceil(file.size / chunkSize)
  let currentChunk = 0
  const spark = new SparkMD5()
  function loadNext () {
    const start = currentChunk * chunkSize
    const end = start + chunkSize >= file.size ? file.size : start + chunkSize
    fileReader.readAsBinaryString(blobSlice.call(file, start, end))
  }

  fileReader.onload = function (e) {
    spark.appendBinary(e.target.result) // append binary string
    currentChunk++
    if (currentChunk < chunks) {
      loadNext()
    } else {
      callBack(spark.end())
    }
  }
  loadNext()
}

export default {
  name: 'UploadFile',
  components: {
    DeleteOutlined,
    QuestionCircleOutlined
  },
  data () {
    return {
      ossFile: '',
      uploadMethod: '',
      accessid: '',
      accesskey: '',
      upload_progress: 0,
      host: '',
      policyBase64: '',
      signature: '',
      callbackbody: '',
      key: '',
      file_name: '',
      file_size: 0,
      startUpload: false,
      expire: 0,
      g_object_name: '',
      g_object_name_type: '',
      now: Date.parse(new Date()) / 1000,
      files_array: [],
      videoSrc: null,
      currentStatus: 'before upload',
      fileUrl: '',
      originalFileName: ''
    }
  },
  props: {
    beforeUpload: Function,
    onSuccess: Function,
    onError: Function,
    onProgress: Function,
    disabled: {
      default: false
    },
    project_id: {
      default: ''
    },
    selectfilesId: {
      default: ''
    },
    type: {
      default: ''
    },
    fileType: {
      default: ''
    },
    md5: {
      defalut: true
    },
    defaultFileName: {
      default: ''
    },
    btnText: {
      default: '上传文件'
    },
    fileDesc: {
      type: String,
      defalut: ''
    }
  },
  mounted () {
    this.file_name = ''
    this.$nextTick(() => {
      this.upload()
    })

    this.files_array = []

    // TODO: 初始化默认文件名称
    if (this.defaultFileName) {
      this.currentStatus = 'success'
      // const regx = /[^\\\/]*[\\\/]+/g
      // this.originalFileName = this.defaultFileName.replace(regx, '')
      this.originalFileName = this.defaultFileName.split('/').pop()
    }
  },
  computed: {
    allowFileType () {
      if (this.type === 'video') {
        return 'mp4'
      } else if (this.type === 'file') {
        if (this.fileType) {
          return this.fileType
        }
        console.log(333)
        return 'zip,rar,tar,apk,gzip'
      } else if (this.type === 'compress') {
        return 'zip,rar'
      } else {
        return 'png,jpg,jpeg'
      }
    }
  },
  methods: {
    cancelUpload () {
      this.uploader.stop()
      this.clearFiles()
      this.$emit('uploadCurrentStep', {
        step: 'before upload'
      })
    },
    doUpload () {
      document.getElementById(this.selectfilesId).click()
    },
    calculateMD5 () {
      const file = this.files_array[0]
      const filename = file.name
      const pos = filename.lastIndexOf('.')
      let suffix = ''
      let onlyFileName = ''
      if (pos !== -1) {
        suffix = filename.substring(pos)
        onlyFileName = filename.substring(0, pos)
      }
      calculate(this.files_array[0].getNative(), md5 => {
        this.setUploadParam(this.uploader, onlyFileName + '_' + md5 + suffix, false)
        this.startUpload = true
      })
    },
    clearFiles () {
      this.files_array = []
      this.upload_progress = 0
      this.g_object_name = ''
      this.currentStatus = 'before upload'
      this.startUpload = false
      this.videoSrc = null
      this.ossFile = null
      this.fileUrl = ''
      this.originalFileName = ''
      this.deleteAllFile()
      // this.$destroy()
      this.$emit('deleteAllFile')
    },
    deleteAllFile (file) {
      if (this.uploader.files[0]) {
        this.uploader.removeFile(this.uploader.files[0].id)
      }
    },
    sendRequest () {
      const xmlhttp = new XMLHttpRequest()
      // 你的服务端接口地址:  参考demo:http://oss-demo.aliyuncs.com/oss-h5-upload-js-php/
      // 服务端签名后直传文档:  https://help.aliyun.com/document_detail/31926.html

      const serverUrl = process.env.VUE_APP_API_BASE_URL + 'api/admin/oss_signature?type=advertise'
      xmlhttp.open('GET', serverUrl, false)

      xmlhttp.send(null)
      return xmlhttp.responseText
    },
    getSignature () {
      this.now = Date.parse(new Date()) / 1000
      if (this.expire < this.now + 3) {
        const body = this.sendRequest()
        let obj = JSON.parse(body)
        console.log(obj)
        console.log('----------------')
        obj = obj.data
        this.host = obj.host
        this.policyBase64 = obj.policy
        this.accessid = obj.accessid
        this.signature = obj.signature
        this.expire = parseInt(obj.expire, 10).toString()
        this.callbackbody = obj.callback
        this.key = obj.dir
        return true
      }
      return false
    },
    getSuffix (filename) {
      const pos = filename.lastIndexOf('.')
      let suffix = ''
      if (pos !== -1) {
        suffix = filename.substring(pos)
      }
      return suffix
    },
    calculateObjectName (filename) {
      this.g_object_name = this.key + filename
    },
    getUploadedObjectName (filename) {
      console.log('====================================')
      console.log(`${this.host}/${this.g_object_name}`)
      console.log('====================================')
      return `${this.host}/${this.g_object_name}`
    },
    getVideoDuration (file) {
      const binaryData = []
      binaryData.push(file)
      this.videoSrc = window.URL.createObjectURL(
        new Blob(binaryData, { type: 'video/mp4' })
      )
    },
    setUploadParam (up, filename, ret) {
      console.log(filename)
      console.log('------------------dd')
      if (ret === false) {
        this.getSignature()
      }
      this.g_object_name = this.key
      console.log('====================================')
      console.log(filename)
      console.log('====================================')
      if (filename !== '') {
        this.calculateObjectName(filename)
      }
      const newMultipartParams = {
        key: this.g_object_name,
        policy: this.policyBase64,
        OSSAccessKeyId: this.accessid,
        // 让服务端返回200,不然,默认会返回204
        success_action_status: '200',
        signature: this.signature,
        callback: this.callbackbody
      }
      up.setOption({
        url: this.host,
        multipart_params: newMultipartParams
      })
      up.start()
    },
    upload () {
      console.log('====================================')
      console.log('==========sssssssssss')
      console.log(this.allowFileType)
      console.log('====================================')
      const that = this
      that.uploader = new plupload.Uploader({
        runtimes: 'html5,flash,silverlight,html4',
        browse_button: that.selectfilesId,
        multi_selection: false,
        container: document.getElementById('container'),
        flash_swf_url: '../../static/pupload/plupload-2.1.2/js/Moxie.swf',
        silverlight_xap_url: '../../static/pupload/plupload-2.1.2/js/Moxie.xap',
        url: '',
        filters: {
          mime_types: [
            {
              title: '文件',
              extensions: this.allowFileType
            }
          ],
          // 最大只能上传200mb的文件
          // max_file_size: '200mb',
          // 不允许队列中存在重复文件
          prevent_duplicates: false
        },
        init: {
          removeFile: () => {
            console.log('=================ss')
          },
          // PostInit: () => {
          //   this.ossFile = '';
          //   document.getElementById('postfiles').onclick = () => {
          //     console.log('=========aa')
          //     that.setUploadParam(that.uploader, '', false);
          //     that.startUpload = true;
          //
          //     // console.log('...');
          //     return false;
          //   };
          // },
          FilesAdded: (up, files) => {
            console.log('==================ddd==================')
            console.log(files)
            console.log(up)
            console.log('====================ddd================')
            files.unshift()
            plupload.each(files, file => {
              file.calu_size = plupload.formatSize(file.size)
              const fileNative = file.getNative()

              that.files_array.push(file)
              const extName = file.name.substring(
                file.name.lastIndexOf('.') + 1
              )
              console.log(that.md5)
              if (that.md5) {
                that.calculateMD5(fileNative)
              } else {
                console.log(fileNative)
                that.setUploadParam(that.uploader, fileNative.name, false)
              }
              that.originalFileName = fileNative.name
              that.currentStatus = 'uploading'
            })
          },
          BeforeUpload: (up, file) => {
            // that.checkObjectRadio();
            // that.setUploadParam(up, file.md5name, true);
            console.group('before')
            console.log(up)
            console.log(file)
            console.groupEnd()
            this.$emit('uploading')
          },
          UploadProgress: (up, file) => {
            that.upload_progress = file.percent
          },
          FileUploaded: (up, file, info) => {
            console.group('after')
            console.log(up)
            console.log(file)
            console.log(info)
            console.groupEnd()
            this.$emit('uploadCurrentStep', {
              step: 'upload success'
            })
            file.finished = true
            that.upload_progress = 100
            that.currentStatus = 'success'
            if (info.status === 200) {
              const r = JSON.parse(info.response)
              this.fileUrl = this.getUploadedObjectName()
              this.$emit('returnFileSrc', this.fileUrl)
            } else {
              document
                .getElementById(file.id)
                .getElementsByTagName('b')[0].innerHTML = info.response
            }
          },
          Error: (up, err) => {
            if (err.code === -600) {
              this.$emit(
                'uploadError',
                'message.file_exceeding_the_limit'
              )
            } else if (err.status === 403) {
              // console.log('tocken过期,请刷新页面后再上传文件!');
              this.$emit('uploadError', 'token过期,请刷新页面后再上传文件!')
            } else {
              this.$emit('uploadError', '文件类型错误')
            }
            if (that.onError) {
              that.onError(err.message, up, err)
            }
          }
        }
      })
      that.uploader.init()
    }
  },
  watch: {
    defaultFileName (value) {
      console.log('value========', value)
      if (value) {
        this.currentStatus = 'success'
        // this.originalFileName = value
        // const regx = /[^\\\/]*[\\\/]+/g
        // this.originalFileName = value.replace(regx, '')
        this.originalFileName = value.split('/').pop()
      } else {
        this.currentStatus = 'before upload'
        this.originalFileName = value
      }
    }
  }
}
</script>
<style scoped>
.progress {
  width: 100px;
}
.file-info {
  line-height: 22px;
  font-size: 13px;
}

.upload-zone {
  width: 330px;
  height: 126px;
  background: #f4f4f4;
  border-radius: 4px;
}

.file-url {
  overflow: hidden;
  display: inline-block;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.desc {
  width: 100%;
  font-size: 12px;
  color: #666;
  line-height: 16px;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值