vue 超简单 oss分片上传文件 大文件上传阿里云

本次上传视频使用的uniapp开发,需要安装oss插件

只需要两步:第一步选择文件,第二部保存上传

1、先写界面,点击选择要上传的视频文件的按钮

代码如下:

javascript 复制代码
<input ref="fileInput" type="file" accept=".mp3,.wav,.mp4,.mov,.m4a,.aac,.ogg" style="display: none"
          @change="handleFileChange" />

handleFileChange方法内容如下:

javascript 复制代码
async handleFileChange(event) {
        const selectedFiles = event.target.files
        if (!selectedFiles || selectedFiles.length === 0) return
        const file = selectedFiles[0]
        // 重置input,允许再次选择相同文件
        event.target.value = null
        // 处理每个文件
        // 检查文件类型
        if (file.type.startsWith('audio/wav') && file.type.startsWith('audio/mp3') && file.type.startsWith(
            'video/mp4')) {
          this.$message.warning('不支持的文件类型:请上传音频或视频格式为WAV的文件。') // i18n: 不支持的文件类型: {type}。请上传音频或视频文件。
          return
        }
        // 检查文件大小 (100MB)
        // if (file.size > 100 * 1024 * 1024) {
        //   this.$message.warning('文件大小超过限制 (最大10MB)')
        //   return
        // }
        // 创建预览URL,声音试听 本地文件
        const previewUrl = URL.createObjectURL(file)
        // 当前选择的文件
        this.upLoadMediaFile = {
          name: file.name,
          type: file.type,
          size: file.size,
          file: file,
          previewUrl: previewUrl,
          duration: 0, // 总时长
          loading: true, // 显示加载状态
          currentTime: 0 // 当前播放的长度
        }

        // 获取媒体文件时长
        await this.getMediaDuration(file, this.upLoadMediaFile)


        // 隐藏上传页面 ,显示 试听 页面
        this.showUpLoad = false
        this.showCloneListen = true
      },

// 获取媒体文件时长
      async getMediaDuration(file, fileObj) {
        const that = this
        // 根据文件类型创建不同的媒体元素
        this.cloneMedia = file.type.startsWith('audio/') ?
          new Audio() :
          document.createElement('video')
        this.cloneMedia.src = URL.createObjectURL(file)
        // 设置事件监听器
        this.cloneMedia.addEventListener('loadedmetadata', () => {
          // 获取到时长后更新文件对象
          fileObj.duration = this.cloneMedia.duration
          that.cloneViceCloneDuration = parseInt(fileObj.duration)
          that.radioProDuration = that.formatToMinSec(that.cloneViceCloneDuration)
          // 判断文件时长
          if (this.cloneViceCloneDuration > 5 && this.audioType == "0") {
            this.$message.warning(this.$t('uploadAudio.basicVersionDurationLimit')) // 原文:基础版音频,要求控制音频时长在5秒以内
            this.upLoadMediaFile = null;
            return
          }
          if (this.cloneViceCloneDuration < 15 && this.audioType == "1") {
            this.$message.warning(this.$t(
              'uploadAudio.highFidelityDurationLimit')) // 原文:高保真音频,要求控制音频时长在15秒以上,请放慢语速
            this.upLoadMediaFile = null;
            return
          }
          that.orignlaDuration = this.cloneMedia.duration
          fileObj.loading = false
        })

        this.cloneMedia.addEventListener('error', (e) => {
          fileObj.loading = false
          this.cloneMedia = null
          URL.revokeObjectURL(this.cloneMedia.src)
        })
        // 媒体播放进度
        this.cloneMedia.addEventListener('timeupdate', (e) => {
          if (this.cloneMedia) {
            fileObj.currentTime = this.cloneMedia.currentTime
            that.radioProCurrent = that.formatToMinSec(fileObj.currentTime)
            // 这里可以添加您的自定义逻辑
            that.cloneViceCurrentTime = parseInt(fileObj.currentTime)
            if (that.orignlaDuration) {
              that.orgPercentage = parseInt(100 * this.cloneMedia.currentTime / that.orignlaDuration)
            }
          }
        })
        this.cloneMedia.addEventListener('ended', () => {
          this.pauseAudioStatus()
        })
        // 声音播放完成
        this.cloneMedia.addEventListener('pause', () => {
          this.pauseAudioStatus()
        })
        // 加载元数据
        this.cloneMedia.load()
      },
2、上传保存到oss

其中await getStsACS(params);根据自己的需求获取对应的阿里云临时平时

javascript 复制代码
async setAss() {
        if (!this.upLoadMediaFile) {
          this.$message.warning(this.$t('uploadAudio.pleaseUploadAudio')) // 原文:请上传音频
          return
        }
        const loading = this.$loading({
          lock: true,
          text: 'Loading',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        let that = this;
        // that.showLoading(this.$t('drawvoiceclone.submitting')) // i18n: 正在提交...
        let tmpFile = this.upLoadMediaFile;
        let tmpName = tmpFile.name + "";
        let lastName = tmpName.substring(tmpFile.name.indexOf("."), tmpName.length);
        let name = 's' + that.random_string(6) + '_' + new Date().getTime() + lastName;
        const params = {
          sourceType: "1.1",
          userId: that.userInfo.userId
        }
        let response = await getStsACS(params);
        if (response.code == 0) {
          let responseData = response.data
          //成功
          name = responseData.keyPrefix ? responseData.keyPrefix + name : name
          this.client = new OSS({
            region: responseData.region ? responseData.region : 'oss-cn-shanghai', // 替换为你的实际区域
            accessKeyId: responseData.AccessKeyId, // 替换为你的实际 AccessKeyId
            accessKeySecret: responseData.AccessKeySecret, // 替换为你的实际 AccessKeySecret
            stsToken: responseData.SecurityToken, // 替换为你的实际 SecurityToken
            bucket: responseData.bucket ? responseData.bucket :
            'wakebaoai', // 替换为你的实际存储空间名称oss-cn-shanghai.aliyuncs.com
          });
          // const file = this.getFileFromPath(tmpFile.previewUrl); //blob 数据格式
          const file = tmpFile.file; //blob 数据格式
          // const file = tmpFile.previewUrl;
          const options = {
            progress: (p) => {},
            parallel: 4,
            partSize: 1024 * 1024,
            mime: tmpFile.type, //'video/mp4'
          };
          // 分片上传
          await this.client.multipartUpload(name, file, options);
          var savePath = (responseData.url ? responseData.url : that.aliUrl) + "/" + name
         
          //将阿里云路径 保存到数据库------提交
          that.submitAudio(savePath, loading);
        } else {
          that.isOperating = false;
          this.$message(response.message)
        }
      },

就这么简单!

相关推荐
Cutecat_14 小时前
视频字幕处理工具横向:提取模式 vs 编辑模式,该如何选择
android·前端·ios·语音识别
dsyyyyy110114 小时前
JavaScript变量
开发语言·javascript·ecmascript
qq_4221525714 小时前
PDF 加水印工具怎么选?2026 年文档版权保护方案对比
前端·pdf·github
kyriewen15 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
brucelee18615 小时前
OpenClaw 浏览器控制(Chrome MCP)完整教程
前端·chrome
ct97816 小时前
React 状态管理方案深度对比
开发语言·前端·react
胡志辉的博客16 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖16 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty16 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
AI焦点16 小时前
跨越协议鸿沟:Tool Use状态机从Anthropic到OpenAI兼容体系的适配要点
前端·人工智能