Vue中实现视频的分片上传

1、选择本地视频,获取视频实体

第一步::auto-upload="false";:on-change="videoSaveToUrl"

 <el-upload
          drag
          action
          :auto-upload="false"
          :on-change="videoSaveToUrl"
          :accept="'video/*'"
        >
 </el-upload>

第二步:在videoSaveToUrl方法中获取视频实体,并存放在data数据的this.video中

 videoSaveToUrl(event) {
      this.video = event.raw;
    },

2、单击“上传”按钮,触发分片上传方法

import { uploadByPieces } from "./JS/utils";  //引入uploadByPieces方法
processButtonClick() {
      uploadByPieces({
        file: this.video,//视频实体
        pieceSize: 5, //分片大小
        success: data => {
          console.log("分片上传视频成功");
        },
        error: e => {
          console.log("分片上传视频失败");
        }
      });
    }

3、分片上传方法(utils.js代码中的uploadByPieces方法)

第一步:获取分片上传过程中会使用到的变量

 // 上传过程中用到的变量
  let fileMD5 = ''// 总文件列表
  const chunkSize = pieceSize * 1024 * 1024 // 5MB一片
  const chunkCount = Math.ceil(file.size / chunkSize) // 总片数
  readFileMD5() // 开始执行代码

第二步:readFileMD5方法:首先获取文件的MD5值,并通过网络请求uploadCheckAxios来检查是否之前已上传过该视频(每个文件的MD5值是唯一的),如果已经上传过,则后台直接返回视频在服务器上的URL,如果没有上传则进行分片上传,调用readChunkMD5() 方法

  const readFileMD5 = () => {
    // 读取视频文件的md5
    console.log("获取文件的MD5值")
    let fileRederInstance = new FileReader()
    fileRederInstance.readAsBinaryString(file)
    fileRederInstance.addEventListener('load', e => {
      let fileBolb = e.target.result
      fileMD5 = md5(fileBolb)

      uploadCheckAxios({ "md5": fileMD5 }).then(res => {
        if (res.data.code == 0) {
          console.log("文件已被上传")
          console.log(res.data)
          success && success(res)
        }
        else { 
          console.log("文件未被上传,将分片上传")
          readChunkMD5() 
        }
      }).catch((e) => {
        console.log("文件合并错误")
        console.log(e)
      })

    })
  }

第三步:readChunkMD5() 方法:分片并上传,其中uploadChunk为上传方法

 // 针对每个文件进行chunk处理
  const readChunkMD5 = () => {
    // 针对单个文件进行chunk上传
    for (var i = 0; i < chunkCount; i++) {
      const { chunk } = getChunkInfo(file, i, chunkSize)
      console.log("总片数"+chunkCount)
      console.log("分片后的数据---测试:"+i)
      console.log(chunk)
      uploadChunk({ chunk, currentChunk: i, chunkCount })
    }
  }

// getChunkInfo方法获取每片视频
 const getChunkInfo = (file, currentChunk, chunkSize) => {
    let start = currentChunk * chunkSize
    let end = Math.min(file.size, start + chunkSize)
    let chunk = file.slice(start, end)
    return { start, end, chunk }
  }

第四步:uploadChunk方法:首先分片上传,上传完毕后调用后台合并接口

 const uploadChunk = (chunkInfo) => {
    let fetchForm = new FormData()
    fetchForm.append('chunk', chunkInfo.currentChunk)
    fetchForm.append('chunkSize', chunkSize)
    fetchForm.append('chunks', chunkInfo.chunkCount)
    fetchForm.append('file', chunkInfo.chunk)
    fetchForm.append('md5', fileMD5)
    fetchForm.append('name', file.name)
    uploadVideoChunkAxios(fetchForm).then(res => {
      console.log("分片上传返回信息:")
      console.log(res.data)
      if (res.data.code == 0) {
        if (chunkInfo.currentChunk < chunkInfo.chunkCount - 1) {
          console.log("文件分片上传成功")
        } else {
          // 当总数大于等于分片个数的时候
          if (chunkInfo.currentChunk >= chunkInfo.chunkCount - 1) {
            console.log("文件开始------合并成功")
            //调用合并接口,传参为视频文件的额MD5值以及名字
            mergeFileAxios({ "md5": fileMD5, "name": file.name }).then(res => {
            if (res.data.code == 0) {
                success && success(res)
                console.log("文件合并成功")
                 console.log(res.data.data.url)
               }
              else { console.log(res.data.msg) }
             }).catch((e) => {
               console.log("文件合并错误")
               console.log(e)
             })
          }
        }
      }
      else {
        console.log(res.data.msg)
      }
    }).catch((e) => {
      error && error(e)
    })
  }

4、utils.js的完整代码

import md5 from 'js-md5'
import { uploadVideoChunkAxios, mergeFileAxios, uploadCheckAxios } from '@/api/upload'
export const uploadByPieces = ({ file, pieceSize = 2, progress, success, error }) => {
  // if (!file || !file.length) return
  // 上传过程中用到的变量
  let fileMD5 = ''// 总文件列表
  const chunkSize = pieceSize * 1024 * 1024 // 5MB一片
  const chunkCount = Math.ceil(file.size / chunkSize) // 总片数
  // 获取md5
  const readFileMD5 = () => {
    // 读取视频文件的md5
    console.log("获取文件的MD5值")
    let fileRederInstance = new FileReader()
    fileRederInstance.readAsBinaryString(file)
    fileRederInstance.addEventListener('load', e => {
      let fileBolb = e.target.result
      fileMD5 = md5(fileBolb)
      uploadCheckAxios({ "md5": fileMD5 }).then(res => {
        if (res.data.code == 0) {
          console.log("文件已被上传")
          console.log(res.data)
          success && success(res)
        }
        else { 
          console.log("文件未被上传,将分片上传")
          readChunkMD5() 
        }
      }).catch((e) => {
        console.log("文件合并错误")
        console.log(e)
      })

    })
  }
  const getChunkInfo = (file, currentChunk, chunkSize) => {
    let start = currentChunk * chunkSize
    let end = Math.min(file.size, start + chunkSize)
    let chunk = file.slice(start, end)
    return { start, end, chunk }
  }
  // 针对每个文件进行chunk处理
  const readChunkMD5 = () => {
    // 针对单个文件进行chunk上传
    for (var i = 0; i < chunkCount; i++) {
      const { chunk } = getChunkInfo(file, i, chunkSize)
      console.log("总片数"+chunkCount)
      console.log("分片后的数据---测试:"+i)
      console.log(chunk)
      uploadChunk({ chunk, currentChunk: i, chunkCount })
    }
  }
  const uploadChunk = (chunkInfo) => {
    // progressFun()
    let fetchForm = new FormData()
    fetchForm.append('chunk', chunkInfo.currentChunk)
    fetchForm.append('chunkSize', chunkSize)
    fetchForm.append('chunks', chunkInfo.chunkCount)
    fetchForm.append('file', chunkInfo.chunk)
    fetchForm.append('md5', fileMD5)
    fetchForm.append('name', file.name)
    uploadVideoChunkAxios(fetchForm).then(res => {
      console.log("分片上传返回信息:")
      console.log(res.data)
      if (res.data.code == 0) {
        // success && success(res)
        if (chunkInfo.currentChunk < chunkInfo.chunkCount - 1) {
          console.log("分片上传成功")
        } else {
          // 当总数大于等于分片个数的时候
          if (chunkInfo.currentChunk >= chunkInfo.chunkCount - 1) {
            console.log("文件开始------合并成功")
            mergeFileAxios({ "md5": fileMD5, "name": file.name }).then(res => {
              if (res.data.code == 0) {
                 success && success(res)
                console.log("文件合并成功")
                 console.log(res.data.data.url)
               }
               else { console.log(res.data.msg) }
             }).catch((e) => {
               console.log("文件合并错误")
               console.log(e)
             })
          }
        }
      }
      else {
        console.log(res.data.msg)
      }
    }).catch((e) => {
      error && error(e)
    })
  }
  readFileMD5() // 开始执行代码
}

 

  • 8
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
视频分片上传是一种常见的大文件上传方式,可以有效地避免上传过程网络不稳定、服务器压力过大等问题。下面是使用Vue、Spring Boot和FFmpeg实现视频分片上传的大致流程: 1. 前端使用Vue编写上传组件,将视频文件进行分片上传到服务器。 2. 后端使用Spring Boot接收前端上传视频分片,并将分片存储到服务器上。 3. 在所有分片上传完成后,后端使用FFmpeg将分片合并成一个完整的视频文件。 下面是具体实现步骤: 前端: 1. 安装vue-upload-component组件,在Vue组件引入该组件。 2. 在Vue组件编写上传方法,将视频文件进行分片上传到服务器。分片的大小可以根据实际情况进行设置,一般为1MB ~ 2MB。 3. 在上传过程,可以实现进度条、暂停上传、继续上传等功能,以提升用户体验。 后端: 1. 使用Spring Boot编写接收上传分片的接口,将分片存储到服务器上。可以使用Spring Boot提供的MultipartFile类来接收前端上传的文件。 2. 在接收到所有分片后,使用FFmpeg将分片合并成一个完整的视频文件。可以使用FFmpeg的命令行工具,也可以使用FFmpeg的Java API。 3. 合并完成后,可以将视频文件存储到服务器的指定路径下,或者将视频文件存储到云存储。 综上所述,使用Vue、Spring Boot和FFmpeg实现视频分片上传可以有效地解决大文件上传过程遇到的问题,提升用户体验,并且保证视频文件的完整性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只如初见0706

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值