跳转到内容

视频提取画面帧

刀刀
0字
0分钟
2026/8/16

Canvas 视频提取画面帧思路

视频提取画面帧主要操作是拿到视频的画面后,把画面画到 Canvas 上, Canvas 可以拿到文件对象 Bloburl 。而 Canvas 不能直接画一个文件,需要使用 video 这类多媒体元素画到 Canvas 内。

所以,整体思路如下:

  1. 根据选择的文件,放到 video
  2. 定格到某一帧
  3. video 画到 Canvas
  4. 导出

Canvas 视频提取画面帧工具函数

此时写一个工具函数,获取视频文件和帧,返回一个包含 bloburl 的对象。

该函数主要做以下操作:

  1. 创建一个 video 标签
  2. 通过 URL.createObjectURL 获取 object url 。以 blob: 为前缀,复制粘贴到新的网页打开就能看到视频
  3. video 定格在某个时间,以及让其自动播放。直接设置自动播放可能会播放失败,因为要考虑到不同浏览器的限制,设置静音播放可以在全部浏览器播放成功
  4. 画到 Canvas 。画的时机要在视频能够开始播放后再画,并且添加一个定时器,否则有可能失败,导致画面帧白屏
  5. 通过 toBlob 方法转为 Blobreturn 返回 Bloburl
js
const box = ref(null)

const drawVideo = (vdo) => {
  return new Promise((resolve) => {
    const cvs = document.createElement('canvas')
    const ctx = cvs.getContext('2d')
    cvs.width = vdo.videoWidth
    cvs.height = vdo.videoHeight
    ctx.drawImage(vdo, 0, 0, cvs.width, cvs.height)
    cvs.toBlob((blob) => {
      resolve({
        blob,
        url: URL.createObjectURL(blob),
      })
    })
  })
}

const captureImg = (frame) => {
  const img = document.createElement('img')
  img.src = frame
  box.value.appendChild(img)
}

/**
 * 获取视频画面帧
 * @params vdoFile: 视频文件
 * @params time: 第几帧
 * @return 返回blob和url
 */
const captureFrame = (vdoFile, time = 0) => {
  return new Promise((resolve) => {
    const vdo = document.createElement('video')
    vdo.currentTime = time // 视频定格
    vdo.muted = true // 静音播放
    vdo.autoplay = true // 视频自动播放
    vdo.oncanplay = () => {
      setTimeout(async () => {
        const res = await drawVideo(vdo)
        resolve(res)
      }, 1000)
    }
    vdo.src = URL.createObjectURL(vdoFile) // 把object url赋值给video标签的src,blob:为前缀,复制粘贴到新的网页打开就能看到视频
  })
}

const onChangeFn = async (e) => {
  if (!e) return
  const file = e.target.files[0]
  for (let i = 0; i < 10; i++) {
    const res = await captureFrame(file, (i + 50) * 1)
    captureImg(res.url)
  }
}

后续也可以通过循环获取多个画面帧。

Canvas 视频提取画面帧拓展

之所以使用 URL.createObjectURL 而不是转为 base64 ,是因为如果视频文件过大,要全部转为 base64 的话,会很耗时。

Canvas 总体效果

跳转预览:点击跳转

贡献者

The avatar of contributor named as duyidao duyidao
The avatar of contributor named as v_duyilin v_duyilin
The avatar of contributor named as 平安喜乐 平安喜乐
The avatar of contributor named as 刀刀 刀刀

页面历史

刀刀博客累计访客 人;文档累计访问量共