vue实现视频上传[项目笔记]

4,391 阅读2分钟

项目需求

用户在选择视频后,跳转到bgm选择页面,选择bgm后,再将视频连同其他参数bgm信息/视频描述等同一上传到服务器。

需求分析

视频选择和bgm选择在两个不同页面之间进行,并且是在选择视频之后跳转到bgm选择页面。

  • 因此,在跳转到bgm选择页面时,应该携带关于视频的参数。
  • 在选定bgm后,将视频信息和bgm等其他信息统一post到服务器。

遇见的问题

  • 在跳转到bgm页面时,应该怎么将视频信息传递过去?
  • 视频信息是一个相对比较大的文件,可以直接将视频参数放到query参数吗?

思路一

在解决这个问题时,我有两个思路:

  • 在选择视频后,我们可以获取到文件的内容,然后利用URL.createObejctUrl(new Blob([file.content])),生成一个blob-url。然后将这个blob-url传递给bgm选择页面。然后,bgm选择页面再向blob-url发起请求,获得文件内容。用这种方式避免了query参数体积过大的问题。

具体流程如下图


    页面A[视频选择]                           页面B[bgm选择]
        选择文件                                提交视频/bgm等信息到服务器
            ⬇                                       ⬆
            ⬇                                       ⬆
        获取file对象                             获取文件对象后,同其他参数一起放到formdata中
            ⬇                                       ⬆
            ⬇                                       ⬆
        根据file.content生成Blob对象            向这个`blob-url`发起请求
            ⬇                                       ⬆
            ⬇                                       ⬆
        根据Blob对象生成`blob-url`➡➡➡➡➡➡➡得到blob-url

具体实现代码如下:

...
<uploader :after-read="afterSelected" :max-size="524288000">
    <button class="upload_video_btn">上传视频</button>
</uploader>
...

// 选择视频后的回调函数
afterSelected(file) {
    // 生成blob对象,并根据blob对象生成blob-url
      const url = URL.createObjectUrl(new Blob([file.content]))
      this.$router.push({
        path:'/chooseBgm',
        query:{
          name:file.file.name,
          url
        }
      })
    }
//跳转到bgm选择页面后的逻辑
//1.获取视频内容
upload(){
    let data = await axios.get(this.$route.query.url)
    data = data.data
    let formdata = new FormData() // 上传视频涉及到文件上传,所以需要使用formdata
    formdata.append(data,data)
    formdata.append(name,this.$route.query.name)
    ...//加入其他信息 比如 bgm 实现描述等,在这里省略
   uploadVideo(formdata,{
    headers:{ // 因为涉及到文件上传,这个头部内容不能少
       "Content-Type": "multipart/form-data"
    }
   }).then((val)=>{
    console.log(val.data.message);
   })
}

思路二

直接将文件内容放到query参数或者params参数中,虽然简单粗暴了点,导致参数体积庞大,但还是很有效的。

 afterSelected(file) {
      this.$router.push({
        path:'/chooseBgm',
        query:{
          name:file.file.name,
          content:file.content
        }
      })
    }

bgm选择页面的逻辑跟上面一毛一样...

从上面的描述中可以看出,两种方式都不够优雅。要么参数体积庞大,要么多了网络请求...希望大神能有别的方法,还望不吝赐教!

通过这个需求,我学习到了

  • 如何使用Blob对象实现大文件分片上传
  • 关于blob的使用
  • 关于formdata的一些知识点