Bootstrap

接口上传视频和oss直传视频到阿里云组件

在这里插入图片描述

接口视频上传

<template>
  <div class="component-upload-video">
    <el-upload
      class="avatar-uploader"
      :action="uploadImgUrl"
      :on-progress="uploadVideoProcess"
      :on-success="handleUploadSuccess"
      :limit="limit"
      :file-list="fileList"
      :before-upload="handleBeforeUpload"
      :show-file-list="false"
      :headers="headers"
      ref="uploadRef"
    >
      <video
        v-if="videoForm.showVideoPath && !videoFlag"
        :src="videoForm.showVideoPath"
        class="avatar video-avatar"
        controls="controls"
      >
        您的浏览器不支持视频播放
      </video>
      <!-- //i标签是上传前的那个+上传后隐藏 -->
      <i
        v-else-if="!videoForm.showVideoPath && !videoFlag"
        class="el-icon-plus avatar-uploader-icon"
      ></i>
      <el-progress
        v-if="videoFlag == true"
        type="circle"
        :percentage="videoUploadPercent"
        style="margin-top: 7px"
      ></el-progress>
    </el-upload>
    <el-button
      v-if="isShowBtn && videoForm.showVideoPath"
      class="mt-20"
      plain
      round
      @click="handleDelete"
      size="small"
      type="primary"
      >重新上传<i class="el-icon-upload el-icon--right"></i
    ></el-button>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth";

export default {
  props: {
    value: [String, Object, Array],
    // 图片数量限制
    limit: {
      type: Number,
      default: 5,
    },
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 50,
    },
    // 序号
    indexValue: {
      type: Number,
      default: null,
    },
    // 文件类型, 例如['video/avi', 'video/wmv', 'video/rmvb']
    fileType: {
      type: Array,
      default: () => ["video/mp4", "video/ogg", "video/flv"],
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: false,
    },
    // 是否显示进度条
    isShowUploadVideo: {
      type: Boolean,
      default: false,
    },
    // 是否显示重新上传按钮
    isShowBtn: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      number: 0,
      dialogVisible: false,
      hideUpload: false,
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/file/upload", // 上传的服务器地址
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      fileList: [],
      videoForm: {
        showVideoPath: "", //回显的变量
      },
      duration: 0, //时长秒
      videoFlag: false,
      videoUploadPercent: 0,
    };
  },

  watch: {
    value: {
      handler(val) {
        if (val) {
          this.videoForm.showVideoPath = val;
          // 首先将值转为数组
          const list = Array.isArray(val) ? val : this.value.split(",");
          // 然后将数组转为对象数组
          this.fileList = list.map((item) => {
            if (typeof item === "string") {
              item = { name: item, url: item };
            }
            return item;
          });
        } else {
          this.fileList = [];
          return [];
        }
      },
      deep: true,
      immediate: true,
    },
  },

  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    },
  },
  methods: {
    // 上传成功回调
    handleUploadSuccess(res) {
      this.isShowUploadVideo = true;
      this.videoFlag = false;
      // this.videoUploadPercent = 0;
      console.log("handleUploadSuccess");
      //后台上传数据
      if (res.code == 200) {
        this.videoForm.showVideoPath = res.data.url; //上传成功后端返回视频地址 回显
        // var audioElement = new Audio(url);
        this.$emit("input", res.data.url, this.duration);
        this.$modal.msgSuccess("上传成功!");
      } else {
        this.$message.error("上传失败!");
      }
    },
    // 上传前loading加载
    handleBeforeUpload(file) {
      var url = URL.createObjectURL(file);
      var audioElement = new Audio(url);
      var time;
      var that = this;
      audioElement.addEventListener("loadedmetadata", function () {
        time = audioElement.duration; //时长为秒
        that.duration = time;
      });
      var fileSize = file.size / 1024 / 1024 < this.fileSize; //控制大小  修改50的值即可
      if (
        ["video/mp4"].indexOf(file.type) == -1 //控制格式
      ) {
        this.$modal.msgError(
          `文件格式不正确, 请上传${this.fileType.join("/")}视频格式文件!`
        );
        return false;
      }
      if (!fileSize) {
        this.$modal.msgError(`上传视频大小不能超过 ${this.fileSize} MB!`);
        return false;
      }
    },
    //进度条--------
    uploadVideoProcess(event, file, fileList) {
      //注意在data中添加对应的变量名
      this.videoFlag = true;
      console.log(file, "file", file.percentage);
      this.videoUploadPercent = file.percentage.toFixed(0) * 1;
    },
    // 文件个数超出
    handleExceed() {
      this.$modal.msgError(`上传视频数量不能超过 ${this.limit} 个!`);
    },
    // 上传失败
    handleUploadError() {
      this.$modal.msgError("上传视频失败,请重试");
      this.$modal.closeLoading();
    },
    handleDelete() {
      this.videoFlag = false;
      // 清除已上传的文件
      this.$refs.uploadRef.clearFiles();
      // 在这里可以执行其他删除操作,例如将视频地址重置为null
      this.videoForm.showVideoPath = "";
    },
  },
};
</script>

<style scoped lang="scss">
// .el-upload--picture-card 控制加号部分
::v-deep.hideUpload .el-upload--picture-card {
  display: none;
}

::v-deep .el-upload--picture-card {
  width: 104px;
  height: 104px;
  line-height: 104px;
}

::v-deep .el-upload-list--picture-card .el-upload-list__item {
  width: 104px;
  height: 104px;
}

.avatar-uploader-icon {
  border: 1px dashed #d9d9d9 !important;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9 !important;
  border-radius: 6px !important;
  position: relative !important;
  overflow: hidden !important;
}

.avatar-uploader .el-upload:hover {
  border: 1px dashed #d9d9d9 !important;
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 300px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar {
  width: 300px;
  height: 178px;
  display: block;
}
</style>

oss直传视频到阿里云组件

<template>
  <div class="component-upload-image">
    <el-upload
      action=""
      :http-request="beforeUpload"
      class="avatar-uploader"
      :limit="limit"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      name="file"
      :show-file-list="false"
      :file-list="fileList"
      ref="uploadRef"
    >
      <video
        v-if="videoForm.showVideoPath && !videoFlag"
        :src="videoForm.showVideoPath"
        class="avatar video-avatar"
        controls="controls"
      >
        您的浏览器不支持视频播放
      </video>
      <!-- //i标签是上传前的那个+上传后隐藏 -->
      <i
        v-else-if="!videoForm.showVideoPath && !videoFlag"
        class="el-icon-plus avatar-uploader-icon"
      ></i>
      <el-progress
        v-if="videoFlag == true"
        type="circle"
        :percentage="videoUploadPercent"
        style="margin-top: 7px"
      ></el-progress>
    </el-upload>
    <el-button
      v-if="isShowBtn && videoForm.showVideoPath"
      class="mt-20"
      plain
      round
      @click="handleDelete"
      size="small"
      type="primary"
      >重新上传<i class="el-icon-upload el-icon--right"></i
    ></el-button>
  </div>
</template>

<script>
import { getOssParameter } from "./oss";

export default {
  props: {
    value: [String, Object, Array],
    // 图片数量限制
    limit: {
      type: Number,
      default: 1,
    },
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 5120,
    },
    fileType: {
      type: Array,
      default: () => ["video/*"],
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true,
    },
    // 是否显示进度条
    isShowUploadVideo: {
      type: Boolean,
      default: false,
    },
    // 是否显示重新上传按钮
    isShowBtn: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      dialogImageUrl: "",
      dialogVisible: false,
      hideUpload: false,
      baseUrl: process.env.VUE_APP_BASE_API,
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/file/upload", // 上传的图片服务器地址
      fileList: [],
      videoForm: {
        showVideoPath: "", //回显的变量
      },
      videoFlag: false,
      videoUploadPercent: 0,
      isCancel: false,
    };
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          this.videoForm.showVideoPath = val;
          // 首先将值转为数组
          const list = Array.isArray(val) ? val : this.value.split(",");
          // 然后将数组转为对象数组
          this.fileList = list.map((item) => {
            if (typeof item === "string") {
              item = { name: item, url: item };
            }
            return item;
          });
        } else {
          this.fileList = [];
          return [];
        }
      },
      deep: true,
      immediate: true,
    },
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    },
  },
  methods: {
    //自定义上传方法..
    Upload(file, data) {
      let OSS = require("ali-oss");
      let client = new OSS({
        region: data.region,
        accessKeyId: data.accessKeyId,
        accessKeySecret: data.accessKeySecret,
        bucket: data.bucket,
      });
      // let cdnUrl = data.cdnUrl;
      let cdnUrl = "https://cdn-learning.cscec83.cn/";
      this.isCancel = false;
      //判断扩展名
      const tmpcnt = file.file.name.lastIndexOf(".");
      const exname = file.file.name.substring(tmpcnt + 1);
      //  配置路径以及文件名称
      const fileName = file.file.uid + "." + exname;
      const progress = (p, _checkpoint) => {
        this.videoFlag = true;
        this.videoUploadPercent = Number((Number(p) * 100).toFixed(1));
        console.log(this.isCancel);
        if (this.isCancel) {
          client.cancel();
        }
      };
      client
        .multipartUpload(fileName, file.file, {
          progress,
          // 设置并发上传的分片数量。
          // parallel: 4,
          // 设置分片大小。默认值为1 MB,最小值为100 KB。
          partSize: 5 * 1024 * 1024,
        })
        .then((res) => {
          console.log(res, "res");
          this.videoFlag = false;
          if (res.name) {
            this.videoForm.showVideoPath = cdnUrl + res.name;
            console.log(this.videoForm.showVideoPath, "fileUrl");
            this.$emit("input", this.videoForm.showVideoPath, this.duration);
            // this.loading.close();
          } else {
            this.$modal.msgError("上传视频失败,请重试");
            // this.loading.close();
            this.handleDelete();
          }
        })
        .catch((err) => {
          console.log(err);
          if (err.name == "cancel") {
            this.$message("上传取消");
          } else {
            this.$modal.msgError(err);
          }
          this.handleDelete();
        });
    },
    handleDelete() {
      this.isCancel = true;
      this.videoFlag = false;
      this.$refs.uploadRef.clearFiles();
      this.duration = 0;
      this.videoForm.showVideoPath = "";
      this.$emit("input", this.videoForm.showVideoPath, this.duration);
      // 清除已上传的文件
    },
    // 上传前loading加载
    beforeUpload(file) {
      var fileSize = file.file.size / 1024 / 1024 < this.fileSize; //控制大小  修改50的值即可
      console.log(file.file.type);
      if (
        this.fileType.indexOf(file.file.type) == -1 //控制格式
      ) {
        this.$modal.msgError(
          `文件格式不正确, 请上传${this.fileType.join("/")}视频格式文件!`
        );
        return false;
      }
      if (!fileSize) {
        this.$modal.msgError(`上传视频大小不能超过 ${this.fileSize} MB!`);
        return false;
      }
      var url = URL.createObjectURL(file.file);
      var audioElement = new Audio(url);
      var time;
      var that = this;
      audioElement.addEventListener("loadedmetadata", function () {
        time = audioElement.duration; //时长为秒
        that.duration = time;
      });
      // this.loading = this.$loading({
      //   lock: true,
      //   text: "上传中",
      //   background: "rgba(0, 0, 0, 0.7)",
      // });
      getOssParameter().then((res) => {
        if (res.code == 200) {
          this.Upload(file, res.data);
        }
      });
    },
    // 文件个数超出
    handleExceed() {
      this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
    },
    // 上传失败
    handleUploadError() {
      this.$modal.msgError("上传失败,请重试");
      // this.loading.close();
    },
    uploadCancel() {
      this.isCancel = true;
    },
  },
};
</script>
<style scoped lang="scss">
// .el-upload--picture-card 控制加号部分
::v-deep.hideUpload .el-upload--picture-card {
  display: none;
}

::v-deep .el-upload--picture-card {
  width: 104px;
  height: 104px;
  line-height: 104px;
}

::v-deep .el-upload-list--picture-card .el-upload-list__item {
  width: 104px;
  height: 104px;
}

.avatar-uploader-icon {
  border: 1px dashed #d9d9d9 !important;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9 !important;
  border-radius: 6px !important;
  position: relative !important;
  overflow: hidden !important;
}

.avatar-uploader .el-upload:hover {
  border: 1px dashed #d9d9d9 !important;
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 300px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar {
  width: 300px;
  height: 178px;
  display: block;
}
</style>

;