当前位置: 首页 > news >正文

JS实现OSS断点续传

先说场景:

用户上传一个视频,但可能因为网络波动或视频较大浏览器的处理偶尔出错,导致上传失败或中断时,可以点击重试,自动接着刚刚上传到的位置继续上传,这就是断点续传。

实现效果:

页面结构:

第一部分:

上传进度提示:上传中+进度条,上传成功,上传失败+重试

<div class="loading" v-if="progressShow"><div class="progress-demo"><div class="progress-content"><div class="progress-content-des"><div class="progress-content-des-title" v-if="uploadRes === 0">上传中</div><div class="progress-content-des-title" v-else-if="uploadRes === 1"><tiny-icon-successful /><div style="color: #09aa71;">上传成功</div></div><div class="progress-content-des-title" v-else-if="uploadRes === 2"><tiny-icon-fail /><div style="color: #f56c6c;">上传失败</div><tiny-button type="success" @click="artUploadRetry(checkpoint, upload_file)">重试</tiny-button></div><div class="progress-content-des-title" v-else>上传进度</div></div><tiny-progress class="progress" type="line" :percentage="percentage" :stroke-width="12" /></div></div>
</div>

 样式部分可以根据实际情况进行调整,这里不过多赘述:

.progress-demo {display: flex;
}.progress-content {flex: 1;
}.progress-content-des {display: flex;justify-content: space-between;margin-bottom: 8px;
}.progress-content-des-title {display: flex;align-items: center;justify-content: left;height: 20px;line-height: 20px;font-size: 14px;
}.progress :deep(.tiny-progress__text) {font-size: 12px !important;
}.tiny-icon-successful {fill: #09aa71;margin-right: 4px;
}.tiny-icon-fail {fill: #f56c6c;margin-right: 4px;
}

第二部分:

上传按钮,视频预览

<tiny-button @click="uploadArt" :disabled="uploadDisabled">作品上传</tiny-button><div v-if="video_url" class="video-preview-container"><video class="preview-video" controls :src="video_url" />
</div>

变量定义:

const percentage = ref(0)
const uploadRes = ref(4)
const uploadDisabled = ref(false)
const video_url = ref('')
let checkpoint = null

核心函数:

第一部分:

设置oss上传的入参,checkpoint为断点,partSize为分片大小,parallel为并发数: 

const commonUpload = async (c_p, file) => {try {uploadRes.value = 0return await client.multipartUpload(object_name, file, {parallel: 2,partSize: 1024 * 1024,checkpoint: c_p,timeout: 120000,progress: (per, cp, res) => {percentage.value = Number((per * 100).toFixed(2))checkpoint = cp}})} catch (err) {console.log(err)uploadRes.value = 2uploadDisabled.value = falsereturn null}
}

第二部分:

视频上传校验及上传进度展示(代码关键位置可查看注释)

const uploadArt = () => {const inputFile = document.createElement('input')inputFile.type = 'file'inputFile.accept = 'video/*'inputFile.multiple = falseinputFile.addEventListener('change', async (event) => {const files = event.target.filesif (!files || files.length === 0) returnconst file = files[0]if (!file.name.endsWith('.mp4') && !file.name.endsWith('.mov')) {Modal.message({status: 'error',message: '请上传.mov或.mp4格式的视频!',duration: 3000})return}if (file.size > 300 * 1024 * 1024) {Modal.message({status: 'error',message: '视频不能大于300MB!',duration: 3000})return}upload_file.value = file // 存储当前这个文件,为了后面断点续传使用filevideo_url.value = '' // 重置视频地址progressShow.value = trueuploadDisabled.value = trueuploadRes.value = 0 // 重置视频上传状态percentage.value = 0 // 重置进度条状态checkpoint = null // 重置断点const ext = file.name.split('.').pop()await getToken(ext) // 获取桶信息const res = await commonUpload(checkpoint, file) // 调用OSS上传if(res) {video_url.value = window.sessionStorage.getItem("video_url") // 这里是从OSS处获取存储到sessionStorage里面的(后端返回的数据)uploadRes.value = 1uploadDisabled.value = false} else {uploadRes.value = 2uploadDisabled.value = false}});inputFile.click();
}

关于代码中,getToken()和OSS的封装在前面的文章有提到,文章地址:

实现视频分片上传 OSS_delphi7如何将视频上传到oss-CSDN博客 

这里对这部分代码进行贴图:

第三部分:

重试函数:通过存储的断点位置调用 commonUpload 继续上传,这里不要再次调用getToken(),因为会重新获取到桶信息,用之前的才可以继续上传,否则会导致与之前的桶信息不一致而报错。

const artUploadRetry = async (c_p, file) => {const res = await commonUpload(c_p, file)if(res) {video_url.value = window.sessionStorage.getItem("video_url")uploadRes.value = 1uploadDisabled.value = false} else {uploadRes.value = 2uploadDisabled.value = false}
}

其他一:

这里如果想测试上传失败,可以用浏览器自带的网络限制,可以自定义网速:

 

点击 Add 即可自定义,填写内容如下:

其他二:

如果是上传图片或者其他小文件,没用到 OSS,也想给用户展示上传进度,可以写一个方法:

const getTimer = () => {uploadRes.value = 0percentage.value = 0process.value = setInterval(() => {if (percentage.value < 95) {percentage.value += 5} else {clearInterval(process.value)}}, 1000)
}

在小于95%之前会每秒+5%, 在上传的方法中,获取到上传成功结果之后将 percentage.value = 100 即可,如果上传失败不需要将 percentage.value = 0。比如:

相关文章:

  • 实战设计模式之模板方法模式
  • 手机号段数据库的作用
  • MySQL 索引优化(Explain执行计划) 详细讲解
  • 【Oracle APEX开发小技巧12】
  • Elasticsearch集群手动分片分配指南:原理与实践
  • 大模型在脑梗塞后遗症风险预测及治疗方案制定中的应用研究
  • Codeforces EDU Round 179 A~D
  • 仿真每日一练 | ABAQUS连接单元的应用——螺栓预紧力
  • 关于Web安全:8. Web 攻击流量分析与自动化
  • 学习笔记(26):线性代数-张量的降维求和,简单示例
  • Halcon透视矩阵
  • 学习笔记(25):线性代数,矩阵-矩阵乘法原理
  • 【Android】Android Studio项目代码异常错乱问题处理(2020.3版本)
  • AOSP (Android11) 集成Google GMS三件套
  • 服务器信任质询
  • Ubuntu Cursor升级成v1.0
  • 黑龙江云前沿服务器租用:便捷高效的灵活之选​
  • Linux容器篇、第二章_01Ubuntu22 环境下 KubeSphere 容器平台高可用搭建全流程
  • 矩阵和向量范数的区别分析
  • 【案例分享】如何借助JS UI组件库DHTMLX Suite构建高效物联网IIoT平台
  • 银医网站建设方案/北京seo网站推广
  • 京东网站建设策略/微信怎么做推广
  • 怎么做分销平台/优化防控举措
  • 免费做代理的网站/齐三seo顾问
  • 国外做地铁设计的公司网站/网络营销专业是干嘛的
  • wordpress mathjax/厦门关键词排名seo