松鼠的博客

导航

大文件上传之--切片上传和断点续传

<template>
  <div id="app">
    <el-upload
      drag
      action
      :auto-upload="false"
      :show-file-list="false"
      :on-change="changeFile"
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        将文件拖到此处,或
        <em>点击上传</em>
      </div>
    </el-upload>

    <!-- PROGRESS -->
    <div class="progress">
      <span>上传进度:{{ total | totalText }}%</span>
      <el-link
        type="primary"
        v-if="total > 0 && total < 100"
        @click="handleBtn"
        >{{ btn | btnText }}</el-link
      >
    </div>

    <!-- VIDEO -->
    <div class="uploadImg" v-if="video">
      <video :src="video" controls />
    </div>
  </div>
</template>
<script>
import { fileParse } from "./assets/utils";
import axios from "axios";
import SparkMD5 from "spark-md5";

export default {
  name: "App4",
  data() {
    return {
      total: 0, //上传进度条
      video: null, //存储地址path
      btn: false, //暂停和开始按钮
    };
  },
  filters: {
    btnText(btn) {
      return btn ? "继续" : "暂停";
    },
    totalText(total) {
      return total > 100 ? 100 : total;
    },
  },
  methods: {
    async changeFile(file) {
      if (!file) return;
      file = file.data;

      // 1解析为BUFFER数据
      // 32我们会把文件切片处理:把一个文件分割成为好几个部分(固定数量/固定大小)
      // 每一个切片有自己的部分数据和自己的名字
      // HASH_1.mp4
      // HASH_2.mp4

      let buffer = await fileParse(file, base64);
      (spark = new SparkMD5.ArrayBuffer()),
        hash,
        suffix,
        spark.append(buffer),
        (hash = spark.end());
      suffix = /\.([0-9a-zA-Z]+)$/i.exec(file.name)[1];
      // 创建100个切片,生成切片
      let partList = [];
      partsize = file.size / 100;
      cur = 0;
      for (let i = 0; i < 100; i++) {
        let item = {
          chunk: file.slice(cur, cur + partsize),
          filename: `${hash}_${i}.${suffix}`,
        };
        cur += partsize;
        partList.push(item);
      }
      this.partList = partList;
      this.hash = hash;
      this.requestList();
    },
    async requestList() {
      let requestList = [];
      this.partList.forEach((item, index) => {
        let fn = () => {
          let fordata = new FormData();
          formData.append("chunk", item.chunk); //append传给服务器的名字叫chunk   值是item.chunk
          formData.append("filename", item.filename);
          return axios
            .post("/single3", formData, {
              headers: { "Content-Type": "multipart/form-data" },
            })
            .then((result) => {
              result = file.data;
              if (code === 0) {
                total += 1;
                this.partList.splice(index, 1);
              }
            });
        };
        requestList.push(fn);
      });
    },
  },
};

参考文章:http://blog.ncmem.com/wordpress/2023/09/23/%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e4%b9%8b-%e5%88%87%e7%89%87%e4%b8%8a%e4%bc%a0%e5%92%8c%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/

欢迎入群一起讨论

 

 

posted on 2023-09-23 19:05  Xproer-松鼠  阅读(47)  评论(0编辑  收藏  举报