兼容处理

微信浏览器使用 WeixinJSBridge.invoke('getNetworkType',()=>{})解决视频无法加载的问题
解决ios微信会自动黑屏(全屏播放)video.setAttribute('playsinline', 'true')
默认视频加载处理等待50毫秒,通过rgb颜色判断图片区域是否都是黑色,如果是黑色修改视频进度条重试(iphoneXRMax ios17会有问题)
export function getVideoBase64 (url: string, picWidth = 1280) {
  let retryCount = 0
  // 第一秒
  const secs = 1
  return new Promise<string>(function (resolve, reject) {
    let dataURL = ''
    const video = document.createElement('video')
    video.setAttribute('crossOrigin', 'anonymous')// 处理跨域
    video.setAttribute('autoplay', 'true')
    video.setAttribute('muted', 'true')
    // 解决ios微信会自动黑屏(全屏播放)
    video.setAttribute('playsinline', 'true')
    video.setAttribute('src', url)
    video.addEventListener('error', e => {
      console.log('video-error', e)
    })
    video.style.cssText = 'position: static;z-index:-99; top: -9999px;' +
      ' left: -9999px; width: 1px;' +
      ' display: none; visibility: hidden;' +
      ' opacity:0;pointer-event:none' +
      ''
    // video.style.cssText = 'position:fixed;z-index:9999;top:0;left:0;width:70%;'
    video.controls = true
    document.body.append(video)
    console.log('video url', url)
    if (
      typeof WeixinJSBridge === 'object' &&
        typeof WeixinJSBridge.invoke === 'function'
    ) {
      // 微信环境先获取网络状态才能loadeddata
      WeixinJSBridge.invoke('getNetworkType', {}, () => {
        //
        console.log('wx video play')
        video.play()
      })
    }

    video.addEventListener('loadedmetadata', function () {
      console.log('video', 'loadeddata')
      // 改变第一秒,解决黑屏问题
      video.currentTime = Math.min(
        Math.max(0, (secs < 0 ? video.duration : 0) + secs),
        this.duration
      )
    })
    video.addEventListener('error', e => {
      console.log('video error', e)
    })
    video.addEventListener('seeked', () => {
      console.log('video', 'seeked')
      video.pause()
      setTimeout(() => {
        video.pause()
        const canvas = document.createElement('canvas')
        // 宽度缩放
        const ratio = picWidth / video.videoWidth
        const width = video.videoWidth * ratio
        // canvas的尺寸和图片一样
        const height = video.videoHeight * ratio
        canvas.width = width
        canvas.height = height
        const ctx = canvas.getContext('2d')!
        ctx.drawImage(video, 0, 0, width, height) // 绘制canvas
        const imgData = ctx.getImageData(0, 0, width * 0.3, height * 0.3)
        const imgArr = imgData.data
        const colorCount = Math.ceil(imgArr.length / 4)
        let blackCount = 0
        for (let i = 0; i < imgArr.length; i += 4) {
          const r = imgArr[i]
          const g = imgArr[i + 1]
          const b = imgArr[i + 2]
          const a = imgArr[i + 3]
          // https://developer.aliyun.com/article/1532134
          const brightness = (r * 299 + g * 587 + b * 114) / 1000
          if (brightness > 125 || a < 0.4) {
            // black
            blackCount++
          }
        }
        console.log('blackCount', blackCount, 'colorCount', colorCount, 'blackRate',
          blackCount / colorCount
        )
        if (blackCount / colorCount >= 0.8) {
          if (retryCount >= 30) {
            return reject('视频黑屏重试过多')
          }
          // 黑色大于80%,重新获取
          console.log('black retry next 0.1s', video.currentTime + 0.1, 'retry', retryCount++)
          video.currentTime += 0.1
          return
        }

        dataURL = canvas.toDataURL('image/jpeg') // 转换为base64
        resolve(dataURL)
        video.remove()
      }, 50)
    })
  })
}

丿有点丶小情绪丨
14 声望1 粉丝