vue antd上传视频或图片到阿里云 oss
1. 环境
需要提前引入好
npm install ali-oss
npm i moment
2. 封装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.封装一个上传文件的antd组件
代码在最下方
首先需要一个上传文件的组件a-upload,一个进度条, 在beforeUpload中对文件进行文件类型的检测,在customRequest上传文件到阿里云 oss
1.beforeUpload对文件类型进行判断
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 上传文件
1.文件前缀
文件类型放最前面
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/'
}
年/月/日
let time1 = moment().format('YYYY') // 年
let time2 = moment().format('MM') // 月
let time3 = moment().format('DD') // 日
上传文件时的file.uid 以及文件名 就可以实现有序的图片管理了
文件类型+年/月/日 作为目录
fileDir + file.uid + file.name
2.统一分片上传
因为视频需要分片上传,所以就统一为分片上传了
client(tamp) 创建oss实例,multipartUpload 分片上传
progress 监听进度条并取整,
当成功时返回上传到oss的路径,以及文件的类型
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
})
$emit 的处理
这里有具体的代码需求,给个思路
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
}
}
视频封面
t 截图时间 单位ms,[0,视频时长]
w 截图宽度,如果指定为0则自动计算 像素值:[0,视频宽度]
h 截图高度,如果指定为0则自动计算,如果w和h都为0则输出为原视频宽高 像素值:[0,视频高度]
m 截图模式,不指定则为默认模式,根据时间精确截图,如果指定为fast则截取该时间点之前的最近的一个关键帧 枚举值:fast
f 输出图片格式 枚举值:jpg、png
视频路径后面拼接 ?x-oss-process=video/snapshot,t_7000,f_jpg,w_800,h_600,m_fast
代码
// 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>
跨域及配置阿里云oss
还没有配置好跨域或者生成配置信息的需要配置这些