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

视频抽帧并保存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.dtcms.com/a/193774.html

相关文章:

  • 用户现场不支持路由映射,如何快速将安防监控EasyCVR视频汇聚平台映射到公网?
  • 分布式锁: Redisson红锁(RedLock)原理与实现细节
  • TC8:SOMEIP_ETS_029-030
  • R语言如何解决导出pdf中文不显示的问题
  • 【C++】 —— 笔试刷题day_30
  • 现在环保方面有什么新的技术动态
  • Python - 爬虫;Scrapy框架之items,Pipeline管道持久化存储(二)
  • 云计算与大数据进阶 | 26、解锁云架构核心:深度解析可扩展数据库的5大策略与挑战(上)
  • 主流数据库运维故障排查卡片式速查表与视觉图谱
  • 25-05-16计算机网络学习笔记Day1
  • SQLMesh 增量模型从入门到精通:5步实现高效数据处理
  • 基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
  • OceanBase 的系统变量、配置项和用户变量有何差异
  • 捌拾伍- 量子傅里叶变换 (3)
  • 数据结构进阶:AVL树与红黑树
  • C++23:ranges::iota、ranges::shift_left和ranges::shift_right详解
  • JavaScript性能优化实战(10):前端框架性能优化深度解析
  • 嵌入式EasyRTC音视频实时通话SDK在工业制造领域的智能巡检/AR协作等应用
  • 医学影像系统性能优化与调试技术:深度剖析与实践指南
  • sqli-labs靶场29-31关(http参数污染)
  • maven和npm区别是什么
  • CVPR2025 | 首个多光谱无人机单目标跟踪大规模数据集与统一框架, 数据可直接下载
  • 中文分词与数据可视化02
  • k8s监控方案实践补充(二):使用kube-state-metrics获取资源状态指标
  • mac中加载C++动态库文件
  • 6 任务路由与负载均衡
  • Linux进程信号(一)之信号的入门
  • Redis + ABP vNext 构建分布式高可用缓存架构
  • flutter缓存网络视频到本地,可离线观看
  • RabbitMQ ④-持久化 || 死信队列 || 延迟队列 || 事务