• vue2视频video循环渲染卡顿


    在这里插入图片描述

    视频多个一起播放卡顿,所以播放一个其他禁止播放
    https://www.h5w3.com/145650.html

    大视频分段上传

    //组件
    <!-- 视频分段上传 -->
    <script lang="ts" setup>
    import { ElMessage } from 'element-plus'
    import SparkMD5 from 'spark-md5'
    import { checkFileMd5, uploadShortVideo, videoUpload } from '@/api/common'
    const fileList = ref([])
    const loading = ref(false)
    const chunkSize = ref(0) //分片大小
    
    const emit = defineEmits(['getUrl'])
    
    const uploadFile = async (File) => {
      const file = File.target.files[0] // 文件
      const fileSize = File.target.files[0].size // 文件大小
      const fileName = File.target.files[0].name //文件名称
    
      let duration: number = 0
      const url = URL.createObjectURL(file)
      const filelement = new Audio(url)
      filelement.addEventListener('loadedmetadata', function (_event) {
        file.duration = filelement.duration
        duration = filelement.duration // 得到视频或音频的时长,单位秒
      })
      console.log('视频或音频的时长,单位秒', file)
    
      // 文件小于50MB短视频上传
      if (fileSize < 50 * 1024 * 1024) {
        const formData = new FormData()
        formData.append('file', file)
        shortUpload(formData, file)
        return
      }
      loading.value = true
      let chunkSize = 3 * 1024 * 1024 // 分片大小
      let chunkCount = Math.ceil(fileSize / chunkSize) // 分片数量
      let fileMd5 = await getFileMd5(file, chunkCount, chunkSize)
    
      if (chunkSize > fileSize) {
        // 文件过小就一片
        chunkCount = 1
      }
      const checkForm = new FormData()
      checkForm.append('fileName', File.target.files[0].name)
      checkForm.append('md5', fileMd5.toString())
      //通过秒传接口获取每片大小
      checkUpload(checkForm).then(async (res: any) => {
        if (res.chunkSize) {
          const num = res.chunkSize / 1024 / 1024
          chunkSize = num * 1024 * 1024
          chunkCount = Math.ceil(fileSize / chunkSize) // 分片数量
          fileMd5 = await getFileMd5(file, chunkCount, chunkSize)
          shardingUpload(chunkCount, chunkSize, file, fileMd5, res.missChunkList)
          loading.value = false
        } else {
          ElMessage.error('请重新上传')
          loading.value = false
        }
      })
    }
    
    // 获取Md5
    const getFileMd5 = (file: File, chunkCount: number, chunkSize: number) => {
      return new Promise((resolve, reject) => {
        const blobSlice = File.prototype.slice
        const chunks = chunkCount
        let currentChunk = 0
        const spark = new SparkMD5.ArrayBuffer()
        const fileReader = new FileReader()
        fileReader.onload = (e) => {
          spark.append(e.target?.result)
          currentChunk++
          if (currentChunk < chunks) {
            loadNext()
          } else {
            const md5 = spark.end()
            resolve(md5)
          }
        }
        fileReader.onerror = (e) => {
          reject(e)
        }
        function loadNext() {
          const start = currentChunk * chunkSize
          let end = start + chunkSize
          if (end > file.size) {
            end = file.size
          }
          fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
        }
        loadNext()
      })
    }
    
    // 短视频上传
    const shortUpload = (formData, file) => {
      uploadShortVideo(formData).then((res) => {
        const url = res.data.urlPrefix + '/' + res.data.urlPath
        ElMessage.success('上传成功')
        emit('getUrl', { url: url, file: file })
      })
    }
    
    // 校验视频格式,是否上传
    const checkUpload = (formatData) => {
      return new Promise((resolve, reject) => {
        checkFileMd5(formatData).then((res) => {
          if (!res.data.formatVerification) {
            ElMessage.error('视频格式不符')
            reject('视频格式不符')
            return
          }
          if (res.data.statusValue === 100) {
            ElMessage.error('视频已存在')
            reject('视频已存在')
            return
          }
          if (res.data.statusValue === 101 || res.data.statusValue === 102) {
            resolve({
              chunkSize: res.data.chunkSize,
              missChunkList: res.data.missChunkList,
            })
          }
        })
      })
    }
    
    //上传分片
    const shardingUpload = (
      chunkCount,
      chunkSize,
      file,
      fileMd5,
      missChunkList,
    ) => {
      const arr = []
      loading.value = true
      for (let i = 0; i < chunkCount; i++) {
        const start = i * chunkSize //分片开始
        const end = Math.min(file.size, start + chunkSize) // 分片结束
        const _chunkFile = file.slice(start, end) // 分片文件
        file.filename = file.name
    
        const formdata = new FormData()
        formdata.append('chunks', chunkCount.toString())
        formdata.append('file', _chunkFile, file.name)
        formdata.append('fileName', file.name)
        formdata.append('md5', fileMd5.toString())
    
        // 如果部分上传判断哪些片段未上传
        if (missChunkList) {
          missChunkList.includes(String(i)) &&
            formdata.append('chunk', i.toString())
          // missChunkList.includes(String(i)) && arr.push(i)
        } else {
          formdata.append('chunk', i.toString())
        }
        videoUpload(formdata)
          .then((res) => {
            if (res.data.flagLast) {
              ElMessage.success('上传成功')
            }
            loading.value = false
          })
          .catch(() => {
            loading.value = false
          })
      }
    }
    </script>
    <template>
      <div>
        <div v-loading="loading" class="upload-btn">
          <label
            :for="'uploadInput'"
            class="el-button file-btn el-button--primary el-button--medium"
            style="display: flex; align-items: center"
            >{{ '上传视频' }}</label
          >
          <input
            id="uploadInput"
            ref="uploadInput"
            accept="video/*"
            type="file"
            class="el-upload__input"
            @change="uploadFile"
          />
        </div>
      </div>
    </template>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    //使用
    <VideoUploadSection @getUrl="getUrl" />
    // 获取视频的地址
      const getUrl = (data) => {
        const obj = {
          videoName: viAddState.form.videoName,
          originalName: data.file.name,
          videoUrl: data.url,
          videoDuration: data.file.duration
        }
        viAddState.fileInfo = obj
        console.log(obj)
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    常用的JVM配置参数说明
    jvm调优经验总结
    【C语言进阶】动态内存管理及柔性数组
    刷题记录:牛客NC51180Accumulation Degree
    机器学习之机器如何学习
    R语言使用nnet包的multinom函数构建无序多分类logistic回归模型、使用summary函数获取模型汇总统计信息
    Tensorflow图像识别 Tensorflow手写体识别(二)
    zk的watch机制使用及原理分析
    CSS结构选择器的使用
    golang leetcode算法小抄
  • 原文地址:https://blog.csdn.net/qq_41820599/article/details/126409522