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.