0
点赞
收藏
分享

微信扫一扫

VUE前端实现视频截图并上传到服务器


做视频上传的时候有时候需要上传预览图,后端一般可以用FFMPEG来实现,前端也可以直接截图,这个功能不需要后台实现,VUE前端利用canvas画图,然后转换Base64就可以完成。

1.前端代码

<el-form-item label="视频地址" required prop="videoURL">
        <el-upload
          :action="uploadURL"
          :show-file-list="true"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleUploadvideo"
          :headers="headerObj"
          name="img"
        >
          <video
            v-if="formData.videoURL"
            style="width:300px"
            :src="formData.videoURL"
            crossOrigin="Anonymous"
            controls
          />
          <i v-else class="el-icon-plus avatar-uploader-icon" />
        </el-upload>
        <div class="tips">
          只能上传MP4格式文件,文件不能超过50M,您可以拖动视频进度条截取自己需要的截图
        </div>
      </el-form-item>
      <el-form-item label="">
        <el-button @click="cutPicture">
          截图上传图片封面
        </el-button>
        <canvas id="myCanvas" style="display: none" />
      </el-form-item>
      <el-form-item label="图片地址" required prop="imgURL">
        <el-upload
          :action="uploadURL"
          :show-file-list="true"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
          :on-success="handleUpload"
          :headers="headerObj"
          name="img"
        >
          <el-image
            v-if="formData.imgURL"
            style="width: 115px; height: 60px"
            :src="formData.imgURL"
          />
          <i v-else class="el-icon-plus avatar-uploader-icon" />
        </el-upload>
        <div class="tips">
          只能上传jpg/png格式文件,文件不能超过500kb
        </div>
      </el-form-item>

2.TS脚本

methods: {
    // 截取当前帧的图片
    cutPicture() {
      if (this.formData.videoURL.length === 0) {
        this.$message.error('请先上传视频!点击截图后再操作!')
        return false
      }

      var video = document.querySelector('video')
      const canvas = document.getElementById('myCanvas') // 获取 canvas 对象
      const ctx = canvas.getContext('2d') // 绘制2d
      video.crossOrigin = 'anonymous' // 解决跨域问题,也就是提示污染资源无法转换视频
      video.currentTime = 2 // 第N帧
      video.oncanplay = () => {
        canvas.width = video.clientWidth // 获取视频宽度
        canvas.height = video.clientHeight // 获取视频高度
        // 利用canvas对象方法绘图
        ctx.drawImage(video, 0, 0, video.clientWidth, video.clientHeight)
      }
      // 转换成base64形式
      var oGrayImg = canvas.toDataURL('image/jpeg')// 截取后的视频封面
      const file = this.getFileByBase64(oGrayImg)
      console.log('imgfilename', file)
      const formData = new FormData() // 创建一个form类型的数据
      formData.append('img', file)
      // axios请求,将截图传给后端API
      this.loadUploadPhoto(formData).then((res) => {
        console.log(res) //  处理成功的函数 相当于success
      })
        .catch((error) => {
          console.log(error) //  错误处理 相当于error
        })
    },
    //   base64 转 file----------------------begin
    getFileByBase64(data) {
      const blobData = this.dataURLtoBlob(data)
      return this.blobToFile(blobData)
    },
    // 1,先将base64转换为blob
    dataURLtoBlob(dataurl) {
      const arr = dataurl.split(',')
      const mime = arr[0].match(/:(.*?);/)[1]
      const bstr = atob(arr[1])
      let n = bstr.length
      const u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new Blob([u8arr], {
        type: mime
      })
    },
    // 2,再将blob转换为file
    blobToFile(theBlob, fileName) {
      theBlob.lastModifiedDate = new Date() // 文件最后的修改日期
      theBlob.name = fileName // 文件名
      return new File([theBlob], fileName, {
        type: theBlob.type,
        lastModified: Date.now()
      })
    },
    //   base64 转 file--------------------------end
    handlePictureCardPreview() {},
    handleRemove() {},
    handleUpload(data) {
      console.log(data)
      if (data.code === 200) {
        this.$message({
          type: 'success',
          message: '图片上传成功'
        })
        console.log('文件上传成功后,图片名=' + data.data.url)
        this.formData.imgURL = data.data.url
      } else {
        this.$message({
          type: 'error',
          message: '错误:' + data.msg
        })
      }
    },
    handleUploadvideo(data) {
      if (data.code === 200) {
        this.$message({
          type: 'success',
          message: '视频上传成功'
        })
        console.log('文件上传成功后,视频名=' + data.data.url)
        this.formData.videoURL = data.data.url
        console.log(this.formData)
      } else {
        this.$message({
          type: 'error',
          message: '错误:' + data.msg
        })
      }
    },
    // 封装截图上传
    async loadUploadPhoto(file) {
      await UploadPhoto(file).then((res) => {
        console.log('截图上传', res)
        if (res.data.code === 200) {
          this.$message({
            type: 'success',
            message: '添加截图上传成功'
          })
          console.log('截图文件上传成功后,文件名=' + res.data.data.url)
          this.formData.imgURL = res.data.data.url
        } else {
          this.$message.error('截图上传失败' + res.data.msg)
        }
      })
    },

举报

相关推荐

0 条评论