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

可以看到,它最终生成了一个很长字符串的base64图片地址。
canvas.toBlob(callback, mimeType, qualityArgument)方法
这个方法相比上一个方法的优点是它是异步的,所以有一个callback回调,这个callback回调方法默认的第一个参数就是转换好的blob文件信息,本文也想重点介绍这种方法的使用。
先说明一下这个方法的三个参数:
| 参数 | 类型 | 是否必传 | 说明 |
|---|---|---|---|
| callback | Function | 是 | toBlob()方法执行成功后的回调方法,支持一个参数,表示当前转换的Blob对象 |
| mimeType | String | 否 | 表示需要转换的图像的mimeType类型。默认值是image/png,还可以是image/jpeg,甚至image/webp(前提浏览器支持)等 |
| qualityArgument | Number | 否 | 表示转换的图片质量。范围是0到1。由于Canvas的toBlob()方法转PNG是无损的,因此,此参数默认是没有效的,除非,指定图片mimeType是image/jpeg或者image/webp,此时默认压缩值是0.92 |
使用写法如下:
canvas.toBlob((blob) => {
console.log(blob)
}, 'image/png', 0.92)
可以看到方法执行得到的是当前转换的Blob对象

那么剩下的就是要将此Blob对象进一步转化为可供img显示的图片地址。
将Blob对象转化为图片地址
下面介绍三种方法进行转化:
方式一: 通过URL.createObjectURL()方法将Blob转化为URL
canvas.toBlob((blob) => {
const imageUrl = URL.createObjectURL(blob)
console.log(1, imageUrl)
}, 'image/jpeg', 1)
如下图所示,转化得到的是一个bold流的图片地址。

方式二: 通过FileReader将Blob转化为DataURL
canvas.toBlob((blob) => {
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = () => {
const imageUrl = reader.result
console.log(2, imageUrl)
}
}, 'image/webp', 1)
如下图所示,转化得到的是一个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 = this
setTimeout(function() {
var binStr = atob( canvas.toDataURL(type, quality).split(',')[1] )
var len = binStr.length
var 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.videoWidth
const h = video.videoHeight
canvas.width = w
canvas.height = h
return new Promise((resolve, reject) => { // 由于toBlob方法是异步的,所以这里用Promise
const ctx = canvas.getContext('2d')
ctx.drawImage(video, 0, 0, w, h)
canvas.toBlob((blob) => {
// 通过FileReader将Blob转化为DataURL
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = () => {
const imageUrl = reader.result
resolve(imageUrl)
}
}, 'image/webp', 1) // 根据需要可以自行配置这里的两个参数
})
}
调用方法:
const videoTag = document.querySelector(".videoTag")
const dataUrl = await getBase64ByVideo(videoTag)
原生JS实现视频截图的更多相关文章
- js实现视频截图,视频批量截图,canvas实现
截取视频的某一时间的图像并保存 利用canvas的绘画能力画出视频某一帧的视频画面, 获得到图像之后转换成base64图像, 再利用a标签的实现自动保存到本地 html代码 <!DOCTYPE ...
- js获取视频截图
参考:https://segmentfault.com/q/1010000006717959问题:a.获取的好像是第一帧的图?第一帧为透明图时,获取的个透明图片b.得先加载视频到video,做视频上传 ...
- 【转载】用原生JS和html5进行视频截图并保存到本地
支持并尊重原创!原文地址:http://www.cnblogs.com/xieshuxin/p/6731637.html <!doctype html> <html> < ...
- 用原生JS和html5进行视频截图并保存到本地
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- canvas与html5实现视频截图功能
这段时间一直在研究canvas,突发奇想想做一个可以截屏视频的功能,然后把图片拉去做表情包,哈哈哈哈哈哈~~ 制作方法: 1.在页面中加载视频 在使用canvas制作这个截图功能时,首先必须保证页面上 ...
- 原生js写的一个弧形菜单插件
弧形菜单是一种半弧式或者全弧形菜单,是一种不同于传统横向或者竖向菜单形式的菜单.最近在网上看到好多人写出了这种效果,于是也尝试自己写了一个. 实现方式:原生态js 主要结构: 1.参数合并 var d ...
- 原生js+css实现重力模拟弹跳系统的登录页面
今天小颖把之前保存的js特效视频看了一遍,跟着视频敲了敲嘻嘻,用原生js实现一个炫酷的登录页面.怎么个炫酷法呢,看看下面的图片大家就知道啦. 效果图: 不过在看代码之前呢,大家先和小颖看看css中的o ...
- Java Web 中使用ffmpeg实现视频转码、视频截图
Java Web 中使用ffmpeg实现视频转码.视频截图 转载自:[ http://www.cnblogs.com/dennisit/archive/2013/02/16/2913287.html ...
- python的前后端分离(一):django+原生js实现get请求
一.django新建项目和应用 参考:https://segmentfault.com/a/1190000016049962#articleHeader2 1.创建项目 django-admin st ...
- JavaScript:原生JS实现Facebook实时消息抓捕
基础知识准备: HTML5给我们提供了一个新的对象叫作:MutationObserver.为了兼容,还有WebKitMutationObserver.MozMutationObserver,挂靠在wi ...
随机推荐
- python-多继承构造函数声明问题
背景 有场景分别定义两组逻辑,随后有统一入口做基类属性的整合 其中两组逻辑的积累构造函数定义入参不同 设计类继承图如: 实际的使用方式抽象为[使用] 小节 实际开发过程中遇到问题 先说结论 pytho ...
- Unity的IPreprocessShaders:深入解析与实用案例
Unity IPreprocessShaders Unity IPreprocessShaders是Unity引擎中的一个非常有用的功能,它可以让开发者在编译Shader时自定义哪些操作需要被执行.这 ...
- 从redis未授权访问到获取服务器权限
从redis未授权访问到获取服务器权限 好久没写博客了,博客园快荒芜了.赶紧再写一篇,算是一个关于自己学习的简要的记录把. 这里是关于redis未授权访问漏洞的一篇漏洞利用: 首先是redis,靶场搭 ...
- windows访问linux分区文件
正常情况下,linux可以访问windows系统的文件,而要想在windows下访问linux文件,需要借助第三方软件. 常用的有以下几款: 1.Linux Reader 2.Ext2 IFS 3.E ...
- AI绘画工具MJ新功能有点东西,小白也能轻松一键换装
先看最终做出来的效果 直接来干货吧.Midjourney,下面简称MJ 1.局部重绘功能来袭 就在前两天,MJ悄咪咪上线了这个被众人期待的新功能:局部重绘. 对于那些追求创新和个性化的设计师来说,局部 ...
- 【python技巧】替换文件中的某几行
[python技巧]替换文件中的某几行 1. 背景描述 最近在写一个后端项目,主要的操作就是根据用户的前端数据,在后端打开项目中的代码文件,修改对应位置的参数,因为在目前的后端项目中经常使用这个操作, ...
- CodeIgniter 视图篇
什么是视图 简单来说,一个视图其实就是一个 Web 页面,或者页面的一部分,像页头.页脚.侧边栏等. 实际上,视图可以很灵活的嵌在另一个视图里,然后这个视图再嵌在另一个视图里,等等, 如果你想使用这种 ...
- SpringBoot 后端配置 Https 教程
以阿里云为例子 1. 申请 SSL 证书 1. 注册域名 打开阿里云官网,搜索域名 点击域名注册,输入域名,点击搜索 选择心仪的域名,点击购买,打钱 进入域名控制台,进行实名认证 2. 申请 SSL ...
- Modbus转profinet网关连接1200PLC在博图组态与英威腾驱动器通讯程序案例
Modbus 转 profinet 网关连接 1200PLC 在博图组态与英威腾驱动器通讯程序案例 本案例给大家介绍由兴达易控 modbus 转 profinet 网关连接 1200PLC 在博图软件 ...
- 关于wake on lan远程唤醒主机的问题,长时间关机无法远程唤醒
英特尔在年初发布了几款低功耗的CPU,国内厂商在迷你主机领域纷纷搭载新款CPU,卖的火爆.之前关注过迷你主机这块,于是,我也入手一个迷你主机玩玩,买的是板载N100的迷你主机.使用过程中会涉及到如何远 ...