废话不多说直接上代码,不懂得可以留言
<template>
<div>
<div class="issue-item" style="border: none">
<div class="title text-bold">视频信息</div>
<div class="content upload">
<el-form-item label="商品视频:">
<div class="describe">
商品视频将会出现在商品详情页中,方便用户更好的了解您的商品
</div>
<div
class="fileBox"
v-if="!videoSrc && !progressFlag && !breakUpload"
>
<el-upload
class="avatar-uploader el-upload--text"
action=""
accept=".mp4"
:show-file-list="false"
:before-upload="beforeUploadVideo"
:auto-upload="false"
:on-change="uploadVideo"
:on-progress="uploadVideoProcess"
>
<img
src="../assets/issue_supply/video_bg.png"
alt=""
width="60"
height="46"
/>
<div class="uploading">点击上传</div>
</el-upload>
<div class="tip">
文件格式mp4,文件大小300MB以内,视频时长1分钟以内,建议尺寸800px*800px
<el-tooltip
class="item"
effect="light"
content="商品视频将会出现在商品详情页中,方便用户更好的了解您的商品。"
placement="bottom"
>
<svg-icon iconClass="help" class="icon"></svg-icon>
</el-tooltip>
</div>
</div>
<div
class="uploadImg videoSrc"
v-else-if="videoSrc && !progressFlag && !breakUpload"
>
<video id="myVideo" controls :autoplayNew="false">
<source :src="videoSrc" type="video/mp4" />
</video>
<div class="close" @click="handleCloseImg('src')">
<i class="el-icon-close"></i>
</div>
</div>
<!-- 上传视频中断 -->
<div
class="uploadImg videoSrc"
v-else-if="breakUpload && !progressFlag && !videoSrc"
>
<div class="error">
<el-upload
class="avatar-uploader el-upload--text"
action=""
accept=".mp4"
:show-file-list="false"
:before-upload="beforeUploadVideo"
:auto-upload="false"
:on-change="uploadVideo"
:on-progress="uploadVideoProcess"
>
<img
src="../assets/error-icon.png"
alt=""
width="32"
height="32"
/>
<div class="breakUpload">上传中断</div>
<div class="uploading">重新上传</div>
</el-upload>
</div>
</div>
<div v-else class="progress uploadImg">
<el-progress
v-show="progressFlag"
type="circle"
:percentage="loadProgress"
:stroke-width="2"
></el-progress>
</div>
</el-form-item>
<el-form-item label="视频封面:" style="margin-left: 30px">
<div class="describe" style="opacity: 0">占位</div>
<div class="uploadImg" v-if="Videoimage">
<upload-image
imgType="Videoimage"
:Videoimage.sync="Videoimage"
@image-success="hanleUploadImagesSuccess"
>
<img :src="Videoimage" alt="" width="236" height="236" />
</upload-image>
<div class="close" @click="handleCloseImg('one')">
<i class="el-icon-close"></i>
</div>
</div>
<div class="fileBox" v-else>
<upload-image
imgType="Videoimage"
:Videoimage.sync="Videoimage"
@image-success="hanleUploadImagesSuccess"
>
<img
src="../assets/issue_supply/pic_bg.png"
alt=""
width="55"
height="44"
/>
<div class="uploading">点击上传</div>
</upload-image>
<div class="tip">
文件格式GIF、JPG、JPEG、PNG,文件大小8MB以内,建议尺寸640px*640px,超出尺寸图片可能会被裁剪
</div>
</div>
</el-form-item>
</div>
</div>
</div>
</template>
<script>
import UploadImage from "@/components/UploadImage";
import { GetImgAddress } from "@/api/common";
export default {
name: "UploadVideo",
data() {
return {
Videoimage: "",
progressFlag: false, // 关闭进度条
loadProgress: 0, // 进度条初始值
videoSrc: "",
fileInfo: {},
imgType: "mp4",
breakUpload: false,
duration: 0,
showPlaceholder: false,
};
},
components: {
UploadImage,
},
methods: {
// 上传进度
uploadVideoProcess(e, file, fileList) {
console.log("上传进度====》", e, file, fileList);
},
// 删封面
handleCloseImg(i) {
console.log("i==》", i);
if (i == "one") {
let a = this.Videoimage.split();
this.Videoimage = String(a.splice());
} else if (i == "src") {
let a = this.videoSrc.split();
this.videoSrc = String(a.splice());
}
},
handleGetVal(e) {
this.$emit("update:form", { ...this.form, editorValue: e });
},
// 上传视频封面
hanleUploadImagesSuccess(e) {
console.log("e===>", e);
this.$emit("videoImgSrc", e.url);
},
beforeUploadVideo(file) {
console.log("object :>> ", file);
},
// 上传接口
uploadVideo(file, fileList) {
this.breakUpload = false;
this.fileInfo = file.raw;
console.log("file", file, fileList);
const isLt10M = file.size / 1024 / 1024 < 300;
if (!isLt10M) {
this.$message.error("上传视频大小不能超过300MB哦!");
return false;
}
this.fileInfo = file.raw;
console.log("dsdas", window.URL.createObjectURL(file.raw));
let that = this;
// 获取视频时长
let url = window.URL.createObjectURL(file.raw);
let audioElement = new Audio(url);
// setTimeout(() => {
audioElement.addEventListener("loadedmetadata", function (_event) {
console.log("_event", _event);
that.duration = parseInt(audioElement.duration); // 时长为秒,小数,182.36
that.$emit("videoDuration", that.duration);
console.log(this.duration);
if (that.duration > 60) {
that.$message.error("上传的视频时长过大,请重新上传");
return false;
} else {
that.uploadRequest(file);
}
});
// }, 3000);
},
// 图片上传方法
async uploadRequest(data) {
try {
const xhr = new XMLHttpRequest();
const ossData = new FormData();
const name =
this.fileInfo.uid +
Math.floor(Math.random() * 100) +
this.fileInfo.name;
let OSSURL = "";
let PATH = "";
let req = {
appId: process.env.VUE_APP_JAVA_APP_ID,
folder: this.imgType,
};
await GetImgAddress(req).then((res) => {
if (res.code === "1") {
this.dataObj = res.data;
ossData.append("name", name);
ossData.append("key", `${res.data.dir}${name}`);
ossData.append("policy", res.data.policy);
ossData.append("OSSAccessKeyId", res.data.accessId);
ossData.append("success_action_status", 200);
ossData.append("signature", res.data.signature);
OSSURL = res.data.host;
PATH = res.data.dir;
}
});
ossData.append("file", this.fileInfo, this.fileInfo.name);
xhr.open("post", OSSURL, true);
console.log("post-OSSURL", OSSURL);
// 进度条
xhr.upload.onprogress = (e) => {
this.progressFlag = true;
this.loadProgress = parseInt((e.loaded / e.total) * 100);
if (this.loadProgress >= 100) {
setTimeout(() => {
this.progressFlag = false;
}, 2000);
}
};
xhr.onload = async (res) => {
console.log("res", res);
if (res.target.status == 200) {
this.videoSrc = `${
process.env.VUE_APP_URL_IMG
}/${PATH}${encodeURIComponent(name)}`;
this.$emit("videoSrc", `${PATH}${encodeURIComponent(name)}`);
this.$emit("videoSize", data.size);
} else {
this.$message.error("图片上传失败,请重新上传!");
}
};
xhr.onabort = (e) => {
console.log("上传中断", e);
this.breakUpload = true;
};
xhr.onerror = (err) => {
console.log("上传失败", e);
this.$message.error("图片上传失败,请重新上传!");
};
xhr.send(ossData);
} catch (error) {
this.$message.error("图片上传失败,请重新上传!");
}
},
},
};
</script>
<style lang="scss" scoped>
.describe {
font-size: 12px;
font-weight: 400;
color: #999999;
padding-bottom: 18px;
}
.fileBox {
width: 678px;
height: 238px;
background: #ffffff;
border: 1px dashed #d7d9db;
border-radius: 3px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.uploading {
width: 112px;
height: 30px;
border: 1px solid #a5a5a5;
border-radius: 3px;
font-size: 14px;
font-weight: 400;
color: #666666;
text-align: center;
line-height: 30px;
// margin-top: 12px;
// margin-top: 12px;
margin-left: auto;
margin-right: auto;
}
.tip {
margin-top: 10px !important;
font-size: 12px;
font-weight: 400;
color: #999999;
}
::v-deep .avatar-uploader {
margin: 0 !important;
}
.newFileBox {
width: 678px;
height: 238px;
}
.uploadImg {
width: 678px;
height: 238px;
& img {
border-radius: 3px;
width: 236px !important;
height: 236px !important;
}
.avatar {
border-radius: 4px;
}
&:hover {
.close {
display: block;
.el-icon-close {
font-size: 16px;
}
}
}
.close {
width: 24px;
height: 24px;
border-radius: 50%;
text-align: center;
color: #fff;
background: #000000;
opacity: 0.5;
line-height: 24px;
position: absolute;
top: 20px;
left: 220px;
font-size: 20px;
display: none;
cursor: pointer;
.el-icon-close {
font-size: 16px;
}
}
::v-deep .avatar-uploader .el-upload {
position: static;
}
}
.issue-item {
margin-top: 60px;
}
#myVideo {
width: 324px;
height: 236px;
border-radius: 3px;
& :hover {
.close {
display: block;
}
}
}
.progress {
display: flex;
justify-content: center;
align-items: center;
}
.videoSrc {
.close {
position: absolute;
top: 24px !important;
left: 308px !important;
}
}
.upload {
display: flex;
justify-content: space-between;
padding: 30px;
background-color: #fafbfc;
}
.error {
border: 1px dashed #d7d9db;
border-radius: 3px;
width: 325px;
height: 236px;
background: #ffffff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
& img {
width: 32px !important;
height: 32px !important;
}
.breakUpload {
font-size: 14px;
font-weight: 400;
color: #999999;
margin-top: 10px;
}
}
::v-deep .el-form-item {
.el-form-item__label {
float: none !important;
line-height: 0 !important;
}
}
.text-bold {
margin-bottom: 28px;
}
</style>