当前位置: 首页 > 工具软件 > Simple-Log > 使用案例 >

simple-uploader/vue-uploader分片上传视频——vue3

施琦
2023-12-01

一、template标签内容

                <uploader
                  style="margin-left: 10px"
                  :options="optionsV.optionsV"
                  @file-success="onFileSuccess"
                  @file-added="onFileAdded"
                  class="uploader-example"
                  :auto-start="auto"
                  :fileStatusText="status"
                  ref="uploadList"
                >
                  <uploader-unsupport></uploader-unsupport>
                  <uploader-drop>
                    <uploader-btn :attrs="{ accept: Object.type }">
                       上传视频
                    </uploader-btn>
                  </uploader-drop>
                  <uploader-list
                    id="shi"
                    class="uploaderList"
                    style="width: 240px">
                  </uploader-list>
                </uploader>

二、script标签里 :options="optionsV.optionsV"

const optionsV = reactive({
  optionsV: {
    target: "/api/mobilehome/up/upload",
    testChunks: false,
    chunkSize: 1024 * 1024 * 2, //1MB
    simultaneousUploads: 3, //并发上传数
    checkChunkUploadedByResponse: (chunk, message) => {
      let obj = JSON.parse(message);
      if (obj.isExist) {
        //它为true的时候标明文件已经存在了
        statusTextMap.success = "秒传文件";
        return true;
      }
      return (obj.uploaded || []).indexOf(chunk.offset + 1) >= 0;
    },
  },
});

三、script标签里  @file-success="onFileSuccess"

const onFileSuccess = async (rootFile, file, response, chunk) => {
  //
  let reader = new FileReader();
  reader.readAsDataURL(file.file);
  reader.onload = (e) => {
    // cVideoPreview.value = reader.result; //应该是上传的地址
  };

  // 视频唯一标识
  const video_identifier = reactive({
    value: "",
  });
  const fileSize = reactive({
    value: "",
  });
  // 获取视频时长
  let url = URL.createObjectURL(file.file);
  // console.log(url)
  let audioEle = new Audio(url);
  // console.log(audioEle)
  audioEle.addEventListener("loadedmetadata", () => {
    // 视频时长值的获取要等到这个匿名函数执行完毕才产生
    var result = audioEle.duration; //得到时长为秒,小数,182.36
    result = parseInt(audioEle.duration);
    // console.log(result)
    cVideoTime.value = result; //存放视频时长
    // console.log(this.video_time)
  });
  let resp = JSON.parse(response);
  if (resp.code === 0 && resp.merge === false) {
    // console.log('上传成功,不需要合并')
    console.log(resp);
    cVideoPreview.value = resp.filePath;
    message.success("视频上传成功");
    checkShow.value = true;
    //uploaderSuccessShow.value = false;
    console.log(status);
  } else {
    let { data } = await axios.post("/mobilehome/up/upload?action=merge", {
      filename: file.name, //文件名称
      identifier: file.uniqueIdentifier, //文件唯一标识
      totalSize: file.size, //文件文大小
      totalChunks: chunk.offset + 1, //文件总分片数
    });
    console.log(data);
    if (data.code === 0) {
      console.log(data);
      cVideoPreview.value = data.filePath;
      video_identifier.value = file.uniqueIdentifier;
      fileSize.value = file.size;
      // console.log('上传成功')
      message.success("视频上传成功");
      checkShow.value = true;
      // uploaderSuccessShow.value = false;
    } else {
      message.success("视频上传失败");
      // uploaderSuccessShow.value = false;
      CloseShow.value = true;
    }
    // catch((error) => {
    //   console.log(error);
    //   alert(error);
    // });
  }
};

 四、script标签里 @file-added="onFileAdded"

const onFileAdded = (file) => {
   computeMD5(file);
};

五、上边函数中的computeMD5(file)

const computeMD5 = (file) => {
  let blobSlice =
      File.prototype.slice ||
      File.prototype.mozSlice ||
      File.prototype.webkitSlice,
    chunkSize = 2097152, //2MB
    chunks = Math.ceil(file.size / chunkSize),
    currentChunk = 0,
    spark = new SparkMD5.ArrayBuffer(),
    fileReader = new FileReader();

  let time = new Date().getTime();

  file.cmd5 = true; //文件状态为“计算md5...”

  fileReader.onload = (e) => {
    spark.append(e.target.result); // Append array buffer
    currentChunk++;

    if (currentChunk < chunks) {
      console.log(
        `第${currentChunk}分片解析完成, 开始第${
          currentChunk + 1
        } / ${chunks}分片解析`
      );
      loadNext();
    } else {
      console.log("finished loading");
      let md5 = spark.end(); //得到md5
      console.log(
        `MD5计算完成:${file.name} \nMD5:${md5} \n分片:${chunks} 大小:${
          file.size
        } 用时:${new Date().getTime() - time} ms`
      );
      spark.destroy(); //释放缓存
      file.uniqueIdentifier = md5; //将文件md5赋值给文件唯一标识
      console.log(md5);
      console.log(file.uniqueIdentifier);

      file.cmd5 = false; //取消计算md5状态
      file.resume(); //开始上传
      auto.value = true; //文件计算完成开始上传
    }
  };

  fileReader.onerror = () => {
    console.warn("oops, something went wrong.");
    file.cancel();
  };

  let loadNext = () => {
    let start = currentChunk * chunkSize,
      end = start + chunkSize >= file.size ? file.size : start + chunkSize;
    fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
  };

  loadNext();
};

六、script标签里 :auto-start="auto"

// 文件添加后是否立即上传,默认不,分片完成之后变为true
const auto = ref(false);

六、script标签里 :fileStatusText="status"

const status = reactive({
  success: "已成功",
  error: "已失败",
  uploading: "加载中",
  paused: "暂停",
  waiting: "请稍等",
});

七、script中的 ref="uploadList"

// 清空上传列表
const uploadList = ref("uploadList");

八、点击上传视频

// 点击上传视频
const addModalVidel = () => {
  addVisibleVideo.value = true;
  formState.username = ""; //输入的名字清空
  uploadVideoShow.value = false; //展示视频的地方清空
  auto.value = false;
//利用原生js获取要清空的列表
  var ul = document.getElementById("shi");
  if (uploadList.value.$el.firstElementChild.firstElementChild) {
    //uploadList.value.$el.firstElementChild.firstElementChild.remove()
    // ul.firstElementChild.firstElementChild.style.width = "0";
    // ul.firstElementChild.firstElementChild.style.height = "0";
    ul.firstElementChild.firstElementChild.remove();//移除之前上传的视频列表
  }
};

九、点击提交按钮

const onFinish = async (values) => {
  let fd = new FormData();
  fd.append("name", formState.username);//视频名字
  fd.append("file_url", cVideoPreview.value);//视频文件
  fd.append("video_time", cVideoTime.value); //视频时长
  // fd.append('md5',video_identifier.value)
  // fd.append('filesize',fileSize.value)
  let { data } = await axios.post(`/mobilehome/materialcenter/center_add`, fd);
  console.log(data);
  if (data.code == 0) {
    message.success(data.msg);
    getTableList();//更新列表
    addVisibleVideo.value = false;//上传视频弹框消失
  } else {
    message.error(data.msg);
  }
};

 类似资料: