大视频分片上传与断点续传

在这里插入图片描述

  async uploadVideo(fileData) {
      const { data } = await uploadVideo(fileData);
      if (data.code === 1) {
        this.$bus.$emit("videoLoading", true, "上传中");
         成功
        if (this.percentCount === 0) {
          // 避免上传成功后会删除切片改变 chunkList 的长度影响到 percentCount 的值
          this.percentCount = 99.99 / this.chunkList.length;
        }
        this.percent += this.percentCount; // 改变进度
      } else {
        // this.uploadVideo(fileData);
      }
    },
    async handleChange(file) {
      console.log(file);
      console.log(file.raw);
      this.percent = 0;
      this.percentCount = 0;
      this.videoSize = "";
      // this.loading = true;
      this.$bus.$emit("videoLoading", true, "检查中");
      if (!file) return;
      this.percent = 0;
      this.videoUrl = "";
      // 获取文件并转成 ArrayBuffer 对象
      // const fileObj = file.raw;
      const fileObj = file.raw;
      let buffer;
      try {
        buffer = await this.fileToBuffer(fileObj);
      } catch (e) {
        console.log(e);
      }
      // 将文件按固定大小(1M)进行切片,注意此处同时声明了多个常量
      const chunkSize = 1048576, //字节
        chunkList = [], // 保存所有切片的数组
        chunkListLength = Math.ceil(fileObj.size / chunkSize), // 计算总共多个切片
        suffix = /\.([0-9A-z]+)$/.exec(fileObj.name)[1]; // 文件后缀名
      console.log(chunkSize);
      // 根据文件内容生成 hash 值
      const spark = new SparkMD5.ArrayBuffer();
      spark.append(buffer);
      const hash = spark.end();
      // 生成切片,这里后端要求传递的参数为字节数据块(chunk)和每个数据块的文件名(fileName)
      let curChunk = 0; // 切片时的初始位置
      this.videoSize = (fileObj.size / 1048576).toFixed(2); //视频大小
      //获取视频时长
      console.log(fileObj);
      let url = URL.createObjectURL(fileObj);
      let audioElement = new Audio(url);
      audioElement.addEventListener("loadedmetadata", () => {
        console.log(audioElement.duration.toFixed());
        this.videoDuration = formatSeconds(
          audioElement.duration.toFixed().toString
        ); //时长为秒,小数,182.36
        console.log(this.videoDuration);
      });
      for (let i = 0; i < chunkListLength; i++) {
        const item = {
          chunk: fileObj.slice(curChunk, curChunk + chunkSize),
          // chunk: fileObj,
          fileName: `${hash}_${i}.${suffix}`, // 文件名规则按照 hash_1.jpg 命名
          hash: `${hash}`,
        };
        curChunk += chunkSize;
        chunkList.push(item);
      }
      this.chunkList = chunkList; // sendRequest 要用到
      this.hash = hash; // sendRequest 要用到
      this.sendRequest();
    },
    // 发送请求
    async sendRequest() {
      // const requestList = []; // 请求集合
      this.randomNum =
        currentTime() +
        this.showCaptcha(10, 99) +
        this.showCaptcha(10, 99) +
        this.showCaptcha(10, 99);
      let newObj = this.chunkList;
      let n = 0;
      // let errorN = null;
      while (n < newObj.length) {
        // console.log(`当前${n}次请求`);
        console.log("当前" + n + "次请求");
        const formData = new FormData();
        formData.append("file", this.chunkList[n].chunk);
        formData.append("hash", this.chunkList[n].hash);
        formData.append("filename", this.chunkList[n].fileName);
        formData.append("chunkLength", newObj.length);
        formData.append("chunkIndex", n);
        formData.append("UcNumber", this.randomNum);
        try {
          console.log("当前成功" + n);
          await this.uploadVideo(formData, n); //async  await让接口同步执行
          n += 1;
        } catch (err) {
          console.log("请求异常2s");
        }
      }
      try {
        this.FileSuccess();
      } catch (err) {
        this.FileSuccess();
      }
    },
    async FileSuccess() {
      //分片上传成功之后通知后端合并
      const { data } = await FileSuccess({
        UcNumber: this.randomNum,
        hash: this.chunkList[0].hash,
        chunkLength: this.chunkList.length,
        file_size: this.videoSize,
      });
      if (data.code === 1) {
        this.percent = 100; // 改变进度
        this.$bus.$emit("videoLoading", false, "");
        this.$emit("handleId", data.file_id);
      }
    },
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值