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

原生JS实现视频截图

视频截图效果预览

视频截图效果

利用Canvas进行截图

要用原生js实现视频截图,可以利用canvas的绘图功能 ctx.drawImage,只需要获取到视频标签,就可以通过drawImage把视频当前帧图像绘制在canvas画布上。

const video = document.querySelector('video')
const canvas = document.createElement('canvas')
const w = video.videoWidth
const h = video.videoHeight
canvas.width = w
canvas.height = h
const ctx = canvas.getContext('2d')
ctx.drawImage(video, 0, 0, w, h)

接下来,需要把画布转化为图片,canvas提供了两个2D转换为图片的方法:canvas.toDataURL()canvas.toBlob()

canvas.toDataURL(mimeType, qualityArgument)方法

toDataURL可以把图片转换成base64格式的图片,是一个同步方法,使用很简单,在上面已经绘制好画布的基础上,只需要下面一行代码就可以获取到当前视频帧的截图了

const imageUrl = canvas.toDataURL("image/png")
console.log(imageUrl)

toDataURL生成的base64图片
可以看到,它最终生成了一个很长字符串的base64图片地址。

canvas.toBlob(callback, mimeType, qualityArgument)方法

这个方法相比上一个方法的优点是它是异步的,所以有一个callback回调,这个callback回调方法默认的第一个参数就是转换好的blob文件信息,本文也想重点介绍这种方法的使用

先说明一下这个方法的三个参数:

参数类型是否必传说明
callbackFunctiontoBlob()方法执行成功后的回调方法,支持一个参数,表示当前转换的Blob对象
mimeTypeString表示需要转换的图像的mimeType类型。默认值是image/png,还可以是image/jpeg,甚至image/webp(前提浏览器支持)等
qualityArgumentNumber表示转换的图片质量。范围是0到1。由于Canvas的toBlob()方法转PNG是无损的,因此,此参数默认是没有效的,除非,指定图片mimeType是image/jpeg或者image/webp,此时默认压缩值是0.92

使用写法如下:

canvas.toBlob((blob) => {console.log(blob)
}, 'image/png', 0.92)

可以看到方法执行得到的是当前转换的Blob对象
Blob对象
那么剩下的就是要将此Blob对象进一步转化为可供img显示的图片地址。

将Blob对象转化为图片地址

下面介绍三种方法进行转化:

方式一: 通过URL.createObjectURL()方法将Blob转化为URL
canvas.toBlob((blob) => {const imageUrl = URL.createObjectURL(blob)console.log(1, imageUrl)
}, 'image/jpeg', 1)

如下图所示,转化得到的是一个bold流的图片地址。

blob流图片地址

方式二: 通过FileReader将Blob转化为DataURL
canvas.toBlob((blob) => {const reader = new FileReader()reader.readAsDataURL(blob)reader.onload = () => {const imageUrl = reader.resultconsole.log(2, imageUrl)}
}, 'image/webp', 1)

如下图所示,转化得到的是一个base64的图片地址。

base64图片地址

方式三: 通过ajax将Blob上传到服务器
canvas.toBlob((blob) => {const formData = new FormData()formData.append('file', blob) // 这里的'file'是接口接收参数的字段名,需要根据实际情况改变const xhr = new XMLHttpRequest()xhr.onload = () => {const imageUrl = JSON.parse(xhr.responseText).data // 接口回调参数,需要根据实际情况处理console.log(3, imageUrl)}xhr.open('POST', '/api/upload', true) // '/api/upload'是上传接口,需要根据实际情况改变xhr.send(formData)
}, 'image/webp', 1)

由此就会将图片上传到你的文件服务器里,最终可以得到一个你自己文件服务器下对应的图片地址。

toBlob()方法的兼容

首先,toBlob()方法IE9浏览器不支持,因为Blob数据格式IE10+才支持。

然后,对于IE浏览器,toBlob()的兼容性有些奇怪,IE10浏览器支持ms私有前缀的toBlob()方法,完整方法名称是msToBlob()。而IE11+,toBlob()方法却不支持。

但是,我们可以基于toDataURL()方法进行polyfill,性能相对会差一些,JavaScript代码如下:

if (!HTMLCanvasElement.prototype.toBlob) {Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {value: function (callback, type, quality) {var canvas = thissetTimeout(function() {var binStr = atob( canvas.toDataURL(type, quality).split(',')[1] )var len = binStr.lengthvar arr = new Uint8Array(len)for (var i = 0; i < len; i++) {arr[i] = binStr.charCodeAt(i)}callback(new Blob([arr], { type: type || 'image/png' }))})}})
}

注意事项

使用外部链接播放视频的话需要在视频标签上设置允许跨域的处理,添加属性crossOrigin='anonymous'即可,

<video className="videoTag" crossOrigin='anonymous' controls><source src="https://www.w3school.com.cn/example/html5/mov_bbb.mp4" type='video/mp4' />
</video>

或者,在js里处理

const video = document.querySelector(".videoTag")
video.setAttribute('crossOrigin', 'anonymous')
video.load()

否则会报以下错误:
跨域报错

完整封装示例

最后,给出一个利用toBlob进行视频截图,最终获取base64图片地址的封装方法,代码示例如下:

function getBase64ByVideo(video) {const canvas = document.createElement("canvas")const w = video.videoWidthconst h = video.videoHeightcanvas.width = wcanvas.height = hreturn new Promise((resolve, reject) => { // 由于toBlob方法是异步的,所以这里用Promiseconst ctx = canvas.getContext('2d')ctx.drawImage(video, 0, 0, w, h)canvas.toBlob((blob) => {// 通过FileReader将Blob转化为DataURLconst reader = new FileReader()reader.readAsDataURL(blob)reader.onload = () => {const imageUrl = reader.resultresolve(imageUrl)}}, 'image/webp', 1) // 根据需要可以自行配置这里的两个参数})
}

调用方法:

const videoTag = document.querySelector(".videoTag")
const dataUrl = await getBase64ByVideo(videoTag)

相关文章:

原生JS实现视频截图

视频截图效果预览 利用Canvas进行截图 要用原生js实现视频截图&#xff0c;可以利用canvas的绘图功能 ctx.drawImage&#xff0c;只需要获取到视频标签&#xff0c;就可以通过drawImage把视频当前帧图像绘制在canvas画布上。 const video document.querySelector(video) con…...

前端Rust二进制/wasm全平台构建流程简述

前言 开门见山&#xff0c;现代前端 Rust 构建基本分三大类&#xff0c;即 构建 .wasm 、构建 .node 二进制 、构建 swc 插件。 入门详见 《 前端Rust开发WebAssembly与Swc插件快速入门 》 。 对于单独开发某一类的流程&#xff0c;在上述参考文章中已有介绍&#xff0c;但对于…...

加解密算法相关技术详解

文章目录 简介工作机制加解密对称密钥算法非对称密钥算法 数字信封数字签名数字证书技术对比 推荐阅读 简介 随着网络技术的飞速发展&#xff0c;网络安全问题日益重要&#xff0c;加解密技术是网络安全技术中的核心技术&#xff0c;是最常用的安全保密手段。 加密&#xff1…...

Clickhouse学习笔记(13)—— Materialize MySQL引擎

该引擎用于监听 binlog 事件&#xff0c;类似于canal、Maxwell等组件 ClickHouse 20.8.2.3 版本新增加了 MaterializeMySQL 的 database 引擎&#xff0c;该 database 能映射到 MySQL中的某个database &#xff0c;并自动在ClickHouse中创建对应ReplacingMergeTree。 ClickHous…...

《QT从基础到进阶·二十四》按钮组QButtonGroup,单选框QRadioButton和多选框QCheckBox

1、按钮组QButtonGroup 如果有多个单选按钮&#xff0c;可以统一放进一个按钮组。 图中有三个单选按钮放进了一个QGroupBox,并且设置了水平布局&#xff0c;现在要将这三个单选按钮放进一个按钮组&#xff0c;之前的想法是先把三个按钮加入按钮组&#xff0c;再把按钮组放进QG…...

Ansible--playbook剧本

目录 一、playbook&#xff1a; playbook的组成&#xff1a; palybook的编写注意事项 二、playbook的编写格式&#xff08;示例&#xff09; 2.1 编写yaml文件 2.2 定义、引用变量 2.3 指定远程主机sudo切换用户 2.4 when条件判断 2.5 迭代 2.6 Templates 模块 2.7 tags 模…...

MacOS下VMware Fusion配置静态IP

前言 在虚拟机安装系统后&#xff0c;默认是通过DHCP动态分配的IP&#xff0c;这会导致每次重启虚拟机ip都可能会改变&#xff0c;使用起来会有很多不便。 配置静态IP 查看主机网关地址 cat /Library/Preferences/VMware\ Fusion/vmnet8/nat.conf 查看主机DNS&#xff0c;m…...

三、机器学习基础知识:Python常用机器学习库(中文文本分析相关库)

文章目录 1、Jieba库1.1 主要函数1.2 词性标注1.3 关键词提取 2、WordCloud库2.1 常见参数2.2 词云绘制 文本分析是指对文本的表示及其特征的提取&#xff0c;它把从文本中提取出来的特征词进行量化来表示文本信息&#xff0c;经常被应用到文本挖掘以及信息检索的过程当中。 1、…...

Nginx 使用笔记大全(唯一入口)

Linux服务器因为Nginx日志access.log文件过大项目无法访问 项目处于运行状态下无法访问&#xff0c;第一步查看磁盘状态 1、查看磁盘状态 df -h 2、查找100M以上的文件 find / -size 100M |xargs ls -lh 3、删除文件 rm -rf /usr/local/nginx/logs/access.log 4、配置nginx.…...

数据结构-二叉排序树(建立、查找、修改)

二叉排序树概念 二叉排序树是动态查找表的一种&#xff0c;也是常用的表示方法。 其中&#xff0c;它具有如下性质&#xff1a; 1.若它的左子树非空&#xff0c;则其左子树的所有节点的关键值都小于根节点的关键值。 2.若它的右子树非空&#xff0c;则其右子树的所有节点的…...

Linux 性能优化之使用 Tuned 配置优化方案

写在前面 考试整理相关笔记博文内容涉及 Linux tuned 调优工具的简单认知调优配置文件的简单说明&#xff0c;自定义调优方案介绍理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff…...

Day02_《MySQL索引与性能优化》

文章目录 一、SQL执行顺序二、索引简介1、关于索引2、索引的类型Btree 索引Btree 索引 三、Explain简介四、Explain 详解1、id2、select_type3、table4、type5、possible_keys6、key7、key_len8、ref9、rows10、Extra11、小案例 五、索引优化1、单表索引优化2、两表索引优化3、…...

(只需三步)Vmvare tools安装教程,实现与windows互通复制粘贴与文件拖拽

首先确保Ubuntu是联网的&#xff0c;如果连不上网可以参考我的这个联网教程&#xff0c;也很简单 &#xff08;只需三步&#xff09;虚拟机上vm的ubuntu不能联上网怎么办-CSDN博客 第一步&#xff1a;卸载之前的tools,确保没有残留 sudo apt-get autoremove open-vm-tools 第…...

Android自定义控件:一款多特效的智能loadingView

先上效果图&#xff08;如果感兴趣请看后面讲解&#xff09;&#xff1a; 1、登录效果展示 2、关注效果展示 1、【画圆角矩形】 画图首先是onDraw方法&#xff08;我会把圆代码写上&#xff0c;一步一步剖析&#xff09;&#xff1a; 首先在view中定义个属性&#xff1a;priv…...

C语言之初阶指针

一、指针&#xff1a; 其实按照我的理解&#xff0c;当我们写c语言程序的时候&#xff0c;创建的变量&#xff0c;数组等都要在内存上开辟空间。而每一个内存都有一个唯一的编号&#xff0c;这个编号也被称为地址编号&#xff0c;就相当于&#xff0c;编号地址指针。 二、指针…...

MongoDB基础知识~

引入MongoDB&#xff1a; 在面对高并发&#xff0c;高效率存储和访问&#xff0c;高扩展性和高可用性等的需求下&#xff0c;我们之前所学习过的关系型数据库(MySql,sql server…)显得有点力不从心&#xff0c;而这些需求在我们的生活中也是随处可见的&#xff0c;例如在社交中…...

41. 缺失的第一个正数

给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,0] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;nums [3…...

数据结构—数组栈的实现

前言&#xff1a;各位小伙伴们我们前面已经学习了带头双向循环链表&#xff0c;数据结构中还有一些特殊的线性表&#xff0c;如栈和队列&#xff0c;那么我们今天就来实现数组栈。 目录&#xff1a; 一、 栈的概念 二、 栈的实现 三、 代码测试 栈的概念&#xff1a; 栈的概念…...

AI大模型低成本快速定制秘诀:RAG和向量数据库

文章目录 1. 前言2. RAG和向量数据库3. 论坛日程4. 购票方式 1. 前言 当今人工智能领域&#xff0c;最受关注的毋庸置疑是大模型。然而&#xff0c;高昂的训练成本、漫长的训练时间等都成为了制约大多数企业入局大模型的关键瓶颈。 这种背景下&#xff0c;向量数据库凭借其独特…...

Please No More Sigma(构造矩阵)

Please No More Sigma 给f(n)定义如下&#xff1a; f(n)1 n1,2; f(n)f(n-1)f(n-2) n>2; 给定n&#xff0c;求下式模1e97后的值 Input 第一行一个数字T&#xff0c;表示样例数 以下有T行&#xff0c;每行一个数&#xff0c;表示n。 保证T<100&#xff0c;n<100000…...

Taotoken的TokenPlan套餐如何实现更经济的模型调用

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken的TokenPlan套餐如何实现更经济的模型调用 1. 理解TokenPlan的计费模式 在模型应用开发过程中&#xff0c;成本的可预测性…...

本地柴油发电机组排行2023年最新榜单

柴油发电机是通过燃烧柴油驱动发动机&#xff0c;进而发电的设备&#xff0c;广泛应用于电力中断或无电网地区。1. 柴油发电机的核心工作原理是什么&#xff1f;柴油发电机是一种将化学能转化为电能的设备&#xff0c;其核心是柴油发动机与交流发电机的组合。当柴油在发动机内燃…...

Rydberg原子量子门实现原理与优化技术

1. Rydberg原子平台中的量子门实现基础1.1 Rydberg原子特性与量子计算优势Rydberg原子是指外层电子被激发到高主量子数能级的原子态&#xff0c;这类原子具有三个关键特性使其成为量子计算的理想平台&#xff1a;强偶极-偶极相互作用&#xff1a;当两个原子同时处于Rydberg态时…...

PentestGPT实战部署指南:AI驱动的渗透测试工作流落地

1. 这不是另一个“AI安全”的概念玩具&#xff0c;而是一套能真正跑起来的渗透测试辅助工作流“PentestGPT”这个名字刚在GitHub上出现时&#xff0c;我第一反应是点开又关掉——过去三年里&#xff0c;我见过太多打着“AI渗透”旗号的项目&#xff1a;有的只是把ChatGPT API封…...

从CTF题看RSA安全:为什么你的密钥不能‘共享素数’?

从CTF实战看RSA密钥安全&#xff1a;那些年我们踩过的坑 在网络安全竞赛和实际渗透测试中&#xff0c;RSA算法的错误实现方式往往成为突破的关键点。本文将通过典型CTF赛题案例&#xff0c;揭示五种常见RSA实现漏洞背后的数学原理和安全启示&#xff0c;帮助开发者在实际项目中…...

PCL 法向量夹角剔除错误匹配点对【2026最新版】

目录 一、 算法简介 1、主要函数 2、参考文献 二、 代码实现 三、 结果展示 四、 参考链接 博客长期更新,本文最新更新时间为:2026年5月24日。代码在PCL1.15.1中测试通过 一、 算法简介 在三维点云配准中,对应点(correspondence)的准确性直接决定了配准算法的精度和鲁棒性…...

学习日志(三)【php语法学习,iscc校赛wp】

1. 任务 1.1.1.1.1.1. 知识部分 rce看【之前的笔记&#xff1f;】php的知识点学习继续jwt token好像是比赛的题目考察内容&#xff0c;我看看php伪协议 1.1.1.1.1.2. 题目 参加iscc比赛【五一】rce题目 1.1.1.1.1.3. 环境配置 把vscode搞好&#xff0c;上学期没有把Php配…...

机器学习在射电天文数据分类中的应用:以MIGHTEE巡天SFG/AGN分类为例

1. 项目概述&#xff1a;当机器学习遇见深空射电巡天在射电天文学领域&#xff0c;我们正经历一场数据洪流。以MeerKAT望远镜阵列主导的MIGHTEE巡天项目为例&#xff0c;其在COSMOS天区的一次早期科学数据释放&#xff0c;就在不到1平方度的天区内探测到了超过6000个射电源。传…...

对比按量计费与Token Plan套餐的实际成本差异

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 对比按量计费与Token Plan套餐的实际成本差异 在构建和运营基于大模型的应用时&#xff0c;成本控制是一个核心的工程考量。Taotok…...

PrivacyGuard实战:基于实证差分隐私的机器学习模型隐私审计框架

1. 项目概述与核心价值在过去的几年里&#xff0c;我亲眼见证了机器学习模型从实验室走向银行、医疗、社交网络等各个敏感领域的全过程。模型性能的每一次飞跃都令人兴奋&#xff0c;但随之而来的隐私泄露事件也一次次为我们敲响警钟。一个在医疗数据上训练出的诊断模型&#x…...