当前位置: 首页 > backend >正文

视频抽帧并保存blob

视频抽帧

/***  @description 获取文件中的每一帧*  @param { File } file*  @param { Number } time 每一帧的时间间隔(单位:秒)*  @param { Boolean } isUseInterval 是否使用间隔 为false只会获取这一帧*  @returns { Map }*  @example await captureFrame({ file, 20  }) ==> Map { blob => {url:blobUrl,time:20},blob => {url:blobUrl,time:40} }*/
export async function captureFrame({ file, time = 0, isUseInterval = true }) {const map = new Map()try {if (!file) {throw new Error('file is required')}if (!file.file) {throw new Error('file.file is required')}if (!file.file.type.includes('video')) {throw new Error('file.file.type must be video')}const video = document.createElement('video')video.muted = truevideo.autoplay = truevideo.src = URL.createObjectURL(file.file)await new Promise((resolve) => video.oncanplay = resolve)const canvas = document.createElement('canvas')canvas.width = video.videoWidthcanvas.height = video.videoHeightfunction _clearCanvas() {canvas.getContext('2d')?.clearRect(0, 0, canvas.width, canvas.height);}function _drawImage() {canvas.getContext('2d')?.drawImage(video, 0, 0, canvas.width, canvas.height)}function _destroyVideoAndCanvas() {video.remove()canvas.remove()}function getBlob() {return new Promise((resolve) => {canvas.toBlob((blob) => resolve(blob));})}if (!isUseInterval) {video.currentTime = timeawait new Promise((resolve) => {video.onseeked = resolve;});_drawImage();const blob = await getBlob();map.set(blob, {url: URL.createObjectURL(blob),})_clearCanvas();} else {// 产生多帧的blobfor (let i = 0; i < video.duration; i += time) {video.currentTime = iawait new Promise((resolve) => {video.onseeked = resolve;});_drawImage();const blob = await getBlob();map.set(blob, {url: URL.createObjectURL(blob),time: i});_clearCanvas();}}_destroyVideoAndCanvas();} catch (error) {console.error('Error capturing frame:', error)}return map
}
http://www.xdnf.cn/news/6764.html

相关文章:

  • 第二十六天打卡
  • 数据备份与恢复方案
  • 7. 进程控制-进程替换
  • WebGIS开发智慧机场项目实战(2)
  • 前端学习(4)—— JavaScript(基础语法)
  • 循环嵌套与枚举算法
  • C41-为什么要用指针
  • 后端框架(3):Spring(1)
  • 【技术原理】ELK技术栈的历史沿革与技术演进
  • Linux——一键部署应用脚本
  • 方法区与元空间解析
  • 软件架构风格系列(2):面向对象架构
  • (网络文件系统)N
  • 本地部署Scratch在线编辑器
  • Ngrok 配置:实现 Uniapp 前后端项目内网穿透
  • Recycling Krylov Subspace 方法解释与开源实现
  • 【Arthas实战】常见使用场景与命令分享
  • 电子电路:电容在电子电路中到底发挥着什么作用?
  • Unity 批量将图片从默认类型改为Sprite类型
  • 数字金融发展对商业银行信用风险的影响研究(stata分析范文)
  • 描述性统计图表
  • HC32L190 ADC采集
  • firewall防火墙
  • 前端方法的总结及记录
  • 隧道结构安全在线监测系统解决方案
  • 探秘雷克赛恩生产基地:解码国产投影技术深耕之路
  • 动态规划-63.不同路径II-力扣(LeetCode)
  • 操作系统知识总结
  • 丝杆升降机最大载荷的工程力学解析与选型实践
  • 懒汉式单例模式的线程安全实现