vue antd uploads videos or pictures to Alibaba Cloud oss

vue antd uploads videos or pictures to Alibaba Cloud oss

1. Environment

Need to be introduced in advance

npm install ali-oss

npm i moment

2. Encapsulate cilent

const OSS = require('ali-oss');


export function client(obj) {
    
    

 let tamp = {
    
    

  region: obj.region || "xxxxxxx",

  accessKeyId: obj.accessKeyId || "xxxxxxxx", 

  accessKeySecret: obj.accessKeySecret || "xxxx", 

  bucket: obj.bucket || "xxxxxxx",

  secure: true,   // secure: 配合region使用,如果指定了secure为true,则使用HTTPS访问 

 }

 var client = new OSS(tamp)  

 return client

}

3. Encapsulate an antd component for uploading files

The code is at the bottom

First, you need a component a-upload to upload files, a progress bar, detect the file type in beforeUpload, and upload the file to Alibaba Cloud oss ​​in customRequest.

1.beforeUpload determines the file type

beforeUpload(file) {
    
    
  const isJpgOrPng =
    file.type === 'image/jpeg' ||
    file.type === 'image/png' ||
    file.type === 'image/svg' ||
    file.type === 'image/jpg' ||
    file.type === 'image/gif' ||
    file.type === 'video/ogg' ||
    file.type === 'video/flv' ||
    file.type === 'video/avi' ||
    file.type === 'video/wmv' ||
    file.type === 'video/mov' ||
    file.type === 'video/mp4'
  if (!isJpgOrPng) {
    
    
    this.$message.error('只能上传图片/视频!')
    return
  }
},

2.customRequest upload file

1. File prefix

Put file type first

  if (file.type === 'video/ogg' ||
    file.type === 'video/flv' ||
    file.type === 'video/avi' ||
    file.type === 'video/wmv' ||
    file.type === 'video/mov' ||
    file.type === 'video/mp4') {
    
    
    fileType = 'videos/'
  } else {
    
    
    fileType = 'images/'
  }

year month day

  let time1 = moment().format('YYYY') // 年
  let time2 = moment().format('MM') // 月
  let time3 = moment().format('DD') // 日

The file.uid and file name when uploading files can achieve orderly image management.

File type + year/month/day as directory

fileDir + file.uid + file.name

2. Unified multi-part upload

Because the video needs to be uploaded in parts, it is unified into multipart uploads.

client(tamp) creates oss instance, multipartUpload multipart upload

progress monitors the progress bar and rounds it,

When successful, the path uploaded to oss and the file type are returned.

  client(tamp).multipartUpload(fileDir + file.uid + file.name, file, {
    
    
    progress: function (p) {
    
    
      const e = {
    
    };
      e.percent = Math.floor(p * 100);
      _this.defaultPercent = e.percent
    }
  }
  ).then(res => {
    
    
    _this.$emit('url', res.res.requestUrls[0].split("?")[0], file.type)
  }).catch(err => {
    
    
    this.$emit('btnStartLoading', false)
    _this.$message.error('上传失败,请检查上传文件或是否配置了云存储服务器')
  }).finally(() => {
    
    
    this.showProgress = false
  })

Handling of $emit

There are specific code requirements here, please give me some ideas.

    getimgurl(e, type) {
    
    
      let arr = ['video/ogg', 'video/flv', 'video/avi', 'video/wmv', 'video/rmvb', 'video/mov', 'video/mp4']
      if (arr.indexOf(type) !== -1) {
    
    
        this.fileArr.push({
    
    
          mp4: e,
          explain: ''
        })
        this.btnLoading = false
      } else {
    
    
        this.fileArr.push({
    
    
          img: e,
          explain: ''
        })
        this.btnLoading = false
      }
    }

Video cover

t screenshot time unit ms, [0, video duration]
w screenshot width, if specified as 0, the pixel value is automatically calculated: [0, video width]
h screenshot height, if specified as 0, automatically calculated, if w and h are both 0, the output is the width and height pixel value of the original video: [0, video height]
m screenshot mode, if not specified, it is the default mode, which takes accurate screenshots based on time. If fast is specified, the most recent key frame before that time point will be captured. Enumeration value: fast
f Output picture format enumeration value: jpg, png

Splicing behind the video path?x-oss-process=video/snapshot,t_7000,f_jpg,w_800,h_600,m_fast

code

// uploadImg_AvI/index.vue

<template>
  <div class="clearfix">
    <!-- 自定义上传事件customRequest -->
    <a-upload ref="upload" :customRequest="customRequest" :beforeUpload="beforeUpload" class="upload-list-inline"
      :showUploadList="false">
      <a-button>
        <a-icon type="upload" />上传图片/视频
      </a-button>
      <!-- 进度条 -->
      <a-progress v-if="showProgress" :percent="defaultPercent" />
    </a-upload>
  </div>
</template>
<script>
import {
    
     client } from "@/utils/alioss"
import moment from 'moment'
export default {
    
    
  data() {
    
    
    name: 'uploadMp4'
    return {
    
    
      previewVisible: false,
      previewImage: '',
      fileList: [],
      defaultPercent: 0,
      showProgress: false,
    }
  },
  methods: {
    
    
    customRequest(options) {
    
    
      let file = options.file
      let fileType = ''
      // 这一步有些重复,可以在beforeUpload 实现
      if (file.type === 'video/ogg' ||
        file.type === 'video/flv' ||
        file.type === 'video/avi' ||
        file.type === 'video/wmv' ||
        file.type === 'video/mov' ||
        file.type === 'video/mp4') {
    
    
        fileType = 'videos/'
      } else {
    
    
        fileType = 'images/'
      }
      this.showProgress = true
      let _this = this
      console.log(options);
      this.$emit('btnStartLoading', true)
      let tamp = {
    
    }
      // 由于我的系统中有多个oss 所以需要按需配置
      this.$store.state.user.info.schools.forEach(val => {
    
    
        // oss_type 是否为系统的
        val.oss_domain = val.oss_domain.replace(/\..*$/, '')
        if (val.id == this.$store.state.user.school) {
    
    
          tamp['region'] = val.oss_domain || undefined
          tamp['accessKeyId'] = val.access_key || undefined
          tamp['accessKeySecret'] = val.access_secret || undefined
          tamp['bucket'] = val.bucket || undefined
          tamp['oss_type'] = val.oss_type == 1 ? true : false
        }
      })

      let time1 = moment().format('YYYY') // 年
      let time2 = moment().format('DD') // 月
      let time3 = moment().format('hh') // 日
      let fileDir = fileType + this.$store.state.user.school + '/' + time1 + '/' + time2 + '/' + time3 + '/'
      client(tamp).multipartUpload(fileDir + file.uid + file.name, file, {
    
    
        progress: function (p) {
    
    
          const e = {
    
    };
          e.percent = Math.floor(p * 100);
          _this.defaultPercent = e.percent
        }
      }
      ).then(res => {
    
    
        _this.$emit('url', res.res.requestUrls[0].split("?")[0], file.type)
      }).catch(err => {
    
    
        this.$emit('btnStartLoading', false)
        _this.$message.error('上传失败,请检查上传文件或是否配置了云存储服务器')
      }).finally(() => {
    
    
        this.showProgress = false
      })
    },
    beforeUpload(file) {
    
    
      const isJpgOrPng =
        file.type === 'image/jpeg' ||
        file.type === 'image/png' ||
        file.type === 'image/svg' ||
        file.type === 'image/jpg' ||
        file.type === 'image/gif' ||
        file.type === 'video/ogg' ||
        file.type === 'video/flv' ||
        file.type === 'video/avi' ||
        file.type === 'video/wmv' ||
        file.type === 'video/mov' ||
        file.type === 'video/mp4'
      if (!isJpgOrPng) {
    
    
        this.$message.error('只能上传图片/视频!')
        return
      }
    },
    handleCancel() {
    
    
      this.previewVisible = false
    }
  }
}
</script>

Cross-domain and configure Alibaba Cloud oss

If you have not configured cross-domain or generated configuration information, you need to configure these.

(31 messages) Vue directly transfers pictures to Alibaba Cloud OSS (single direct upload)_vue Alibaba Cloud direct transfer__Xiao Zheng's blog - CSDN blog

Guess you like

Origin blog.csdn.net/lfeishumomol/article/details/131359359