Loading

JS实现视频截图

截图原理:

文件上传,将视频绘制到canvas中进行截图

贴代码

base64 转成文件

下面需要用到

export const dataURLtoFile = ({
  dataURL = "",
  filename = ""
}: {
  dataURL: string
  filename: string
}) => {
  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 File([u8arr], filename, { type: mime })
}

 

将视频绘制到canvas上

后面会用到

function drawVideoToCanvas({
  videoElement,
  filename
}: {
  filename: string
  videoElement: HTMLVideoElement
}): Promise<{ file: Blob; url: string }> {
  return new Promise(resolve => {
    const canvas = document.createElement("canvas")
    const ctx = canvas.getContext("2d")
    canvas.width = videoElement.videoWidth
    canvas.height = videoElement.videoHeight
    if (!ctx) {
      return new Error("ctx is not defined!")
    }
    ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height)
    const dataURL = canvas.toDataURL("image/png")
    const file = dataURLtoFile({
      dataURL,
      filename
    })
    const url = URL.createObjectURL(file) // 实现本地预览
    resolve({
      file,
      url
    })
  })
}

 

播放视频,图片截取

export function captureFrame({
  file,
  time = 0,
  filename = "screenshot.png"
}: {
  file: Blob
  time?: number
  filename?: string
}): Promise<{ file: Blob; url: string }> {
  return new Promise(resolve => {
    // 因为dom节点没有渲染到浏览器,视频播放到指定的时间就会停止播放
    const videoElement = document.createElement("video")
    videoElement.currentTime = time // 设置截取的帧时间
    // 自动播放存在兼容性问题,设置静音解决自动播放在不同浏览器的兼容性问题
    videoElement.muted = true
    videoElement.autoplay = true
    videoElement.src = URL.createObjectURL(file)
    videoElement.oncanplay = async function () {
      const flame = await drawVideoToCanvas({ filename, videoElement })
      resolve(flame)
    }
  })
}

 

下面是react代码示例

const Example28 = () => {
  return (
    <div>
      <input
        type="file"
        onChange={event => {
          const [file] = event.target.files || []
          captureFrame({ file, time: 1 }).then(data => {
            console.log(data)
            const IMG = new Image()
            IMG.src = data.url
            IMG.width = 200
            document.body.append(IMG)
          })
        }}
      />
    </div>
  )
}

export default Example28

 

示例截图

 

posted @ 2024-07-04 18:55  冯叶青  阅读(1)  评论(0编辑  收藏  举报