获取视频第一帧,作为封面图

需求

移动端需要显示上传的视频,视频第一帧作为封面图,ios端支持且兼容性好,安卓端显示延迟2s左右,优化体验,上传时需要生成封面图。

上代码

export function getVideoBase64 (url: string) {
  url = handleFilePath(url)// 通过代理方式,支持跨域
  return new Promise(function (resolve, reject) {
    let dataURL = ''
    let video = document.createElement('video')
    video.setAttribute('crossOrigin', 'anonymous')// 处理跨域,需要服务器支持跨域
    video.setAttribute('src', url)
    video.setAttribute('preload', 'auto')
    video.setAttribute('width', '688px')
    video.setAttribute('height', '400px')
    video.setAttribute('style', 'object-fit:scale-down')
    video.addEventListener('loadeddata', async function () {
      let canvas:any = document.createElement('canvas')
      let width = video.width // canvas的尺寸和图片一样
      let height = video.height
      canvas.width = width
      canvas.height = height
      canvas.getContext('2d').drawImage(video, 0, 0, width, height) // 绘制canvas
      dataURL = canvas.toDataURL('image/jpeg') // 转换为base64
      let file = dataURLtoFile(dataURL, '封面图.jpg') // 转成file
      let { data } = await uploadFile({ file: file, type: 'jokefooww' })// 上传视频
      resolve(data.url)
    })
  })
}

// 对附件链接进行处理,使之同源,支持设置 download
export function handleFilePath (path:string) {
  let res = /^https?://[a-zA-Z-]+.XXXX.com/(.+)$/.exec(path)
  let url = res ? res[1] : path
  return `/fileapi/${url}`
}

// 将base64转换为blob,直接转file浏览器兼容问题
export function dataURItoBlob (base64Data:any) {
  let byteString
  if (base64Data.split(',')[0].indexOf('base64') >= 0) { byteString = atob(base64Data.split(',')[1]) } else { byteString = unescape(base64Data.split(',')[1]) }
  let mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0]
  let ia = new Uint8Array(byteString.length)
  for (let i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i)
  }
  return new Blob([ia], { type: mimeString })
};

// 将blob转换为file
function dataURLtoFile (dataurl: string, filename: string) {
  // 获取到base64编码
  const arr = dataurl.split(',')
  // 将base64编码转为字符串
  const bstr = window.atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n) // 创建初始化为0的,包含length个元素的无符号整型数组
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], filename, {
    type: 'image/jpeg'
  })
}
原文地址:https://www.cnblogs.com/zzghk/p/14504556.html