原生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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/193005.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷粒商城项目-环境配置

安装vegrant 2.2.18 注意vritual box&#xff08;6.1.30&#xff09;和vegrant版本兼容 初始化和创建虚拟机 vagrant init centos/7 vagrant up连接虚拟机 vegrant ssh解决vagrant up速度过慢问题 https://app.vagrantup.com/centos/boxes/7/versions/2004.01直接下载对应镜像…

8年经验之谈 —— 记一次接口压力测试与性能调优!

经验总结 1. 如果总的CPU占用率偏高&#xff0c;且基本都被业务线程占用时&#xff0c;CPU占用率过高的原因跟JVM参数大小没有直接关系&#xff0c;而跟具体的业务逻辑有关。 2. 当设置JVM堆内存偏小时&#xff0c;GC频繁会导致业务线程停顿增多&#xff0c;TPS下降&#xff…

Actipro Software WPF Controls 23.1.3

Actipro Software WPF Controls v23.1.3 Actipro Software 为 Microsoft 提供软件组件和 .NET 平台。它位于克利夫兰&#xff0c;重点主要是提供高质量的用户界面软件组件以及客户的过程&#xff0c;以便他们有能力信任&#xff0c;以便为用户应用程序添加强大的功能。自 .NET…

【算法与数据结构】491、LeetCode递增子序列

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题和【算法与数据结构】78、90、LeetCode子集I&#xff0c; II中90.子集II问题有些类似&#xff0c;…

基于单片机微波炉加热箱系统设计

**单片机设计介绍&#xff0c; 基于单片机微波炉加热箱系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的微波炉加热箱系统是一种智能化的厨房电器设备&#xff0c;利用单片机控制技术实现自动加热和定时等功能…

Hadoop的概述

1、Hadoop的发展史&#xff1a; Google首先发布三篇文章&#xff1a;GFS(Google File System)、Mapreduce&#xff08;计算引擎&#xff09;、Bigtable &#xff0c;随着时间的推移&#xff1a; hadoop1.0与2.0 的区别是在2.0的版本中出现了yarn&#xff0c;主要是负责资源的调…

解决Qt5.13.0无MySQL驱动问题

一、前言 由于Qt5.12.3是最后提供mysql数据库插件的版本&#xff0c;往后的版本需要自行编译对应的mysql数据库插件&#xff0c;官方安装包不再提供。使用高版本的Qt就需要自行编译mysql驱动。 若没有编译在QT中调用Qsqldatabase库连接mysql时&#xff0c;提示出现如下问题&a…

基于51单片机PCF8591数字电压表LCD1602液晶显示设计( proteus仿真+程序+设计报告+讲解视频)

基于 51单片机PCF8591数字电压表LCD1602液晶设计 ( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus7.8及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0060 51单片机PCF8591数字电压表LCD1602液晶设计 1.主要功…

Using Definition View 使用定义视图

You use Definition view to create definitions within a defined hierarchical structure, in which nodes represent the definitions. A node is the visual representation of a section, step, or action that you can select, collapse,modify, and so on. 您可以使用“…

kubernetes集群编排——istio

官网&#xff1a;https://istio.io/latest/zh/about/service-mesh/ 部署 [rootk8s2 ~]# tar zxf istio-1.19.3-linux-amd64.tar.gz [rootk8s2 ~]# cd istio-1.19.3/[rootk8s2 istio-1.19.3]# export PATH$PWD/bin:$PATH demo专为测试准备的功能集合 [rootk8s2 istio-1.19.3]# i…

【Java】若依的使用代码生成及字典的使用

一、导言 1、介绍 若依管理系统是一款基于Java语言开发的开源管理系统。它采用了Spring Boot框架&#xff0c;使得开发更加快速和高效。同时&#xff0c;它还集成了MyBatis Plus&#xff0c;进一步简化了数据库操作。若依管理系统的界面简洁美观&#xff0c;且支持多语言&#…

Promise 重写 (第一部分)

学习关键语句&#xff1a; promise 重写 写在前面 重新学习了怎么重写 promise &#xff0c; 我觉得最重要的就是要有思路&#xff0c;不然有些 A 规范是完全想不到的 开始 重写函数的过程中, 最重要的是有思路 我们从哪里获取重写思路? 从正常的代码中 我们先看正常的代码…

阿里云国际站:应用实时监控服务

文章目录 一、阿里云应用实时监控服务的概念 二、阿里云应用实时监控服务的优势 三、阿里云应用实时监控服务的功能 四、写在最后 一、阿里云应用实时监控服务的概念 应用实时监控服务 (Application Real-Time Monitoring Service) 作为一款云原生可观测产品平台&#xff…

基于Rabbitmq和Redis的延迟消息实现

1 基于Rabbitmq延迟消息实现 支付时间设置为30&#xff0c;未支付的消息会积压在mq中&#xff0c;给mq带来巨大压力。我们可以利用Rabbitmq的延迟队列插件实现消息前一分钟尽快处理 1.1定义延迟消息实体 由于我们要多次发送延迟消息&#xff0c;因此需要先定义一个记录消息…

应用协议安全:Rsync-common 未授权访问.

应用协议安全&#xff1a;Rsync-common 未授权访问. Rsync 是 Linux 下一款数据备份工具&#xff0c;支持通过 rsync 协议、ssh 协议进行远程文件传输。其中 rsync 协议默认监听 873 端口&#xff0c;如果目标开启了 rsync 服务&#xff0c;并且没有配置 ACL 或访问密码&#…

delete 与 truncate 命令的区别

直接去看原文 原文链接:【SQL】delete 与 truncate 命令的区别_truncate和delete的区别-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- 1. 相同点 二者都能删除表中的数据…

uniapp插件开发

安装android studio&#xff1a;安装目录下bin下的此文件&#xff0c;是用来修改分配给android studio的占用内存。 Android 11足够用。 创建新项目&#xff1a; 目录结构介绍&#xff1a; UI组件介绍&#xff1a;在设计程序界面时可以使用可视化拖拽的方式&#xff0c;没有必要…

【Apifox】国产测试工具雄起

在开发过程中&#xff0c;我们总是避免不了进行接口的测试&#xff0c; 而相比手动敲测试代码&#xff0c;使用测试工具进行测试更为便捷&#xff0c;高效 今天发现了一个非常好用的接口测试工具Apifox 相比于Postman&#xff0c;他还拥有一个非常nb的功能&#xff0c; 在接…

Maven 的 spring-boot-maven-plugin 红色报错

1、想要处理此情况&#xff0c;在工具下面加上指定的版本号。 2、给自己的maven的setting文件加工一下。 <mirrors><!--阿里云镜像1--><mirror><id>aliyunId</id><mirrorOf>central</mirrorOf><name>aliyun maven</name>…

数据存储和内存对齐

校内课复习笔记 非数值数据表示 在计算机中&#xff0c;只有01序列&#xff0c;这串01序列是什么意思&#xff0c;由人为定义。 西文字符 在ASCII码中&#xff0c;通过一个65的偏移量&#xff0c;使得一部分无符号数指向A-Za-z。 在C语言中&#xff0c;通过char类型的转换规范…