惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tailwind CSS Blog
月光博客
月光博客
爱范儿
爱范儿
罗磊的独立博客
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
aimingoo的专栏
aimingoo的专栏
D
DataBreaches.Net
F
Full Disclosure
博客园 - 司徒正美
小众软件
小众软件
D
Docker
大猫的无限游戏
大猫的无限游戏
O
OpenAI News
T
Threatpost
Engineering at Meta
Engineering at Meta
Cisco Talos Blog
Cisco Talos Blog
Google DeepMind News
Google DeepMind News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Y
Y Combinator Blog
H
Help Net Security
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Cisco Blogs
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
博客园 - 聂微东
A
Arctic Wolf
T
Threat Research - Cisco Blogs
U
Unit 42
NISL@THU
NISL@THU
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 【当耐特】
T
Troy Hunt's Blog
PCI Perspectives
PCI Perspectives
Webroot Blog
Webroot Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
AWS News Blog
AWS News Blog
The Last Watchdog
The Last Watchdog
Last Week in AI
Last Week in AI
V
Vulnerabilities – Threatpost
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
腾讯CDC
V
V2EX
A
About on SuperTechFans
Know Your Adversary
Know Your Adversary
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 冯叶青

OpenAI vs Anthropic API 对比:响应体、请求体、消息格式与工具调用 GitHub Actions 自动部署流程 Git分支自动合并脚本:基于时间戳的冲突解决方案 Next.js lingui.js 多语言自动提取翻译键 - ats-node React实现短信验证码输入组件 Next.js 中优雅地使用 Lottie 动画 Next.js 路由参数更新最佳实践:从 replaceState 到 nextReplaceState Jenkins构建时SWR模块导入报错解决方案 解决 Jenkins 环境下 Lingui 构建报错 "btoa is not defined" git 提交 实现大图自动压缩功能 React lingui.js 多语言自动提取翻译键 - ast node html2canvas 解决截图空白问题 react 实现前端发版监测 JS根据文件名获取文件类型 JS获取本机IP地址 适用于react、vue菜单格式化工具函数 git 内容提交 实现大图拦截功能 next.js 利用中间件(middleware.ts)实现PC与移动路由无缝切换 Android生成签名文件及对apk进行签名 JS-SDK 配置,实现微信分享功能
JS实现视频截图
冯叶青 · 2024-07-04 · via 博客园 - 冯叶青

截图原理:

文件上传,将视频绘制到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

示例截图