Element UI Upload 组件中两个关键属性:
- http-request : 覆盖默认的上传行为,可以自定义上传的实现
- before-upload : 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
<el-upload
class="avatar2-uploader"
action
:show-file-list="false"
:http-request="videoUpload"
:before-upload="beforeVideoUpload"
>
<div>
<img
v-if="ruleForm.HeadImgUrl"
:src="preUrl+ruleForm.HeadImgUrl"
class="avatar2"
/>
<i v-else class="el-icon-plus avatar2-uploader-icon"></i>
</div>
<el-button class="upBtn" size="small">上传视频</el-button>
<div slot="tip" class="el-upload__tip2">
重要提示:
<br />支持常用视频格式,推荐使用mp4、webm
视频文件大小不超过500MB,时长在60分钟以内
分辨率为720p(1280x720)
<el-progress
class="progress"
:text-inside="true"
:stroke-width="26"
:percentage="progress"
></el-progress>
</div>
</el-upload>
我们可以自定义这两个函数时间完善业务
下面是文件上传前对文件格式的检验
注释部分为获取视频首帧画面
// 上传文件前的文件格式、尺寸等等的规则定制
beforeVideoUpload(file) {
let _this = this;
return new Promise(async function(resolve, reject) {
console.log("beforeeeee", file);
let fileName = file.name || "";
let ext = fileName.split(".")[fileName.split(".").length - 1];
let duration, width, height;
console.log(ext);
if (
ext !== "avi" &&
ext !== "mp4" &&
ext !== "3gp" &&
ext !== "mkv" &&
ext !== "mpg" &&
ext !== "mpeg" &&
ext !== "ts" &&
ext !== "rmvb" &&
ext !== "wmv" &&
ext !== "flv" &&
ext !== "mov"
) {
_this.$message.error(
"上传视频应为 avi/mp4/3gp/mkv/mpg/mpeg/ts/rmvb/wmv/flv/mov 格式!"
);
reject();
} else {
let video = await _this.loadVideo(file);
duration = video.duration;
width = video.videoWidth;
height = video.videoHeight;
if (Math.floor(duration) / 60 > 60) {
_this.$message.error("上传视频时长应在60分钟以内!");
reject();
}
if (width > 1280 || height > 720) {
_this.$message.error(
"上传视频分辨率应为720p(1280x720)!"
);
reject();
}
if (file.size / 1024 / 1024 > 500) {
_this.$message.error("上传视频文件大小不超过500MB!");
reject();
}
// 单集和系列区分
if (_this.tabName === "single") {
_this.runningTime = _this.formatSeconds(duration); // 页面显示的时间
_this.subSingleTime = Math.ceil(duration / 60); // 提交的时间
} else {
_this.multipleVideo.time = _this.formatSeconds(
duration
);
_this.subMultipleTime = Math.ceil(duration / 60);
}
// 获取视频第一帧画面
// _this.loadVideo(file).then(videoElem => {
// const canvasElem = document.createElement("canvas");
// const { videoWidth, videoHeight } = videoElem;
// canvasElem.width = videoWidth;
// canvasElem.height = videoHeight;
// canvasElem
// .getContext("2d")
// .drawImage(
// videoElem,
// 0,
// 0,
// videoWidth,
// videoHeight
// );
// // 导出成blob文件
// canvasElem.toBlob(blob => {
// _this.getImage(blob); // 获取文件 blob、file对象都可读取
// }, "image/png");
// });
}
resolve();
console.log(`时长:${duration}`);
console.log(`width:${width}`);
console.log(`height:${height}`);
});
},
// 将获取到的第一帧画面文件转为包含一个data:URL格式的字符串(base64编码)代表读取文件的内容。
// getImage(blob) {
// let _this = this;
// //1:获取file对象
// var reader = new FileReader();
// //2:解析对象,转成baae64对象的url
// reader.addEventListener(
// "load",
// function() {
// _this.thumbImg = reader.result;
// },
// false
// );
// if (blob) {
// //在load中返回一个base64编码
// reader.readAsDataURL(blob);
// }
// },
// 获取视频的尺寸,播放时长
loadVideo(file) {
return new Promise(function(resolve, reject) {
const videoElem = document.createElement("video");
const dataUrl = URL.createObjectURL(file);
// 当前帧的数据是可用的
videoElem.onloadeddata = function() {
resolve(videoElem);
};
videoElem.onerror = function() {
reject("video 后台加载失败");
};
// 设置 auto 预加载数据, 否则会出现截图为黑色图片的情况
videoElem.setAttribute("preload", "auto");
videoElem.src = dataUrl;
});
},
以下是自定义上传属性:http-request,将文件上传至阿里云OSS
// 两种方式一是引入oss-sdk js压缩文件,npm安装 ali-oss
import OSS from "@/utils/aliyun-oss-sdk";
let appServer = "https://xxxxx.xxxxx.com:8070/api/Oss/GetSTS"; //OSS用户授权接口
//覆盖默认的上传行为,自定义上传的实现
videoUpload(file) {
this.applyTokenDo(file);
},
applyTokenDo(file) {
let that = this;
var url = appServer;
return OSS.urllib
.request(url, {
method: "GET"
})
.then(async function(result) {
let creds = JSON.parse(result.data);
let db = creds.Data;
let client = new OSS({
region: db.Region,
accessKeyId: db.AccessKeyId,
accessKeySecret: db.AccessKeySecret,
stsToken: db.SecurityToken,
bucket: db.Bucket
});
//获取上传文件
let fileObj = file.file; // js 获取文件对象
// var file0 = fileObj[0];
let key = await that.getKeyName(fileObj);
// client 是第一步中的 client
// debugger
client
.multipartUpload(key, fileObj, {
//获取进度条的值
progress: function(p) {
// 这里是实时的上传进度
console.log(p);
}
})
.then(result => {
var key = result.name;
that.$message({
showClose: true,
message: "上传成功!",
type: "success"
});
// 走到这里已上传成功,key值即是返回拿到的上传文件的相对路径
})
.catch(err => {
console.log("err:", err);
});
});
},
//获取文件名称
// 这里通过后端接口拿到后台指向文件的路径
async getKeyName(fileObj) {
let params = {
xxx.....
};
let key = await GetKeyName(params);
return key;
},