视频上传、预览、通过视频url获取第一帧(任意帧)

上传其实就是将你选择的文件转成file文件,我们拿到file文件之后再做处理。比如传到服务器,服务器返回一个fileId,我们下次需要反显的时候可以根据这个fileId去服务器拿对应的文件。

一、视频上传,预览功能

base64形式的文件可以直接作为视频的url,并且可以自动展示视频封面。
html:


<input
  type="file"
  accept="video/*"
  capture="camera"
  @change="preview1($event)"
>

<video
  v-if="videoUrl"
  :src="videoUrl"
  style="width:120px;height:120px;object-fit:cover;"
  @click="handleClicksVideo"
>video>

<van-dialog
  :show-cancel-button="false"
  :show-confirm-button="false"
  v-model="showVideoPlay"
  close-on-click-overlay
  theme="default"
  style="width:100%;border-radius:0;height:200px"
  @close="closeDialog"
>
  <video
    v-if="videoUrl"
    id="myVideo"
    :src="videoUrl"
    :disablePictureInPicture="true"
    controls
    controlslist="nodownload nofullscreen noremoteplayback noplaybackrate"
    style="width:100%;height:200px;object-fit: contain;"
  >video>
van-dialog>

js:

data() {
  return {
    videoUrl: '',
    videoId: '',
    showVideoPlay: false,
    video: null
  }
},
methods: {
	// 将获取到的上传的文件转成base64格式
	preview1(event) {
      let that = this
      let img = event.target.files[0]
      let reader = new FileReader()

      reader.readAsDataURL(img)
      reader.onload = function(e) {
        var dataBase64 = e.target.result
        console.log(dataBase64)
        that.videoUrl = dataBase64
      }
    },
	// 点击预览
    handleClicksVideo(file) {
      this.showVideoPlay = true
      this.$nextTick(() => {
        this.video = document.getElementById('myVideo')
        this.video.play()
      })
    },
    // 关闭弹窗
    closeDialog() {
      this.video.pause()
    },
    // 文件大小判断
    handlebefread(e) {
      if (e.size > 104857600) {
        Dialog.alert({
          message: '请重新上传100M以下的视频',
          theme: 'round-button'
        })
        return false
      }
      return true
    }
}

拓展1:通过视频url获取第一帧(是base64形式,直接作为图片的链接)


<img :src="CoverImg || ''">
// 获取上传的视频信息
getVideoDetail() {
  Ajax({
    url: ...,
    data: {...}
  }).then(async response => {
  	// 注意 async、await
  	// videoUrl_为请求到的视频链接
    this.CoverImg = await this.getVideoBase64(videoUrl_)
  })
},
// 截取视频第一帧作为封面图 然后转成base64
getVideoBase64(url, second = 2) {
  return new Promise(function(resolve) {
    let dataURL = ''
    const video = document.createElement('video')
    video.setAttribute('crossOrigin', 'anonymous') // 处理跨域
    video.setAttribute('src', url)
    video.setAttribute('preload', 'auto')
    // 静音操作,防止播放失败
  	video.setAttribute('muted', 'muted')
    video.addEventListener('loadeddata', async function() {
      const canvas = document.createElement('canvas')
      const width = video.videoWidth || 400 // canvas的尺寸和图片一样
      const height = video.videoHeight || 240 // 设置默认宽高为  400  240
      canvas.width = width
      canvas.height = height
      
      // 如果出现黑屏可以截取指定时间的画面,单位为【秒】
      if (second) {
        video.currentTime = second
        // 播放到当前时间的帧,才能截取到当前的画面
        await video.play()
        await video.pause()
      }
      
      canvas.getContext('2d').drawImage(video, 0, 0, width, height) // 绘制canvas
      dataURL = canvas.toDataURL('image/jpeg') // 转换为base64
      resolve(dataURL)
    })
  })
}

拓展2:base64转图片文件,然后传给后端,拿到图片链接直接作为video标签的poster的值来展示封面

<video controls :poster="CoverImg">
async aa() {
	// videoUrl_为请求到的视频链接
	const imgUrl = await this.getFileFromBase64(vedioUrl_, "kefu.jpeg")
	const fd1 = new FormData()
	//拿到图片文件请求后端接口获取图片链接
	fd1.append("Files", imgUrl);
	// 封面图
	this.CoverImg = await uploads(fd1)
}
// base64转图片
getFileFromBase64(base64URL, filename) {
  var arr = base64URL.split(","),
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], filename, { type: "image/png" });
},

你可能感兴趣的:(javascript,前端,java)