首页 > 其他分享 >原生JS实现视频截图

原生JS实现视频截图

时间:2023-11-14 14:56:57浏览次数:36  
标签:原生 截图 const image toBlob canvas JS video blob

视频截图效果预览

视频截图效果

利用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文件信息,本文也想重点介绍这种方法的使用

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

参数 类型 是否必传 说明
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对象

那么剩下的就是要将此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.result
    console.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 = 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)

标签:原生,截图,const,image,toBlob,canvas,JS,video,blob
From: https://www.cnblogs.com/Marco-hui/p/17831577.html

相关文章

  • 表格数据拖拽排序 sortable.js
    需求拖拽表格的行数据,实现排序。问题拖拽后调用接口,但视图没变,还是原来的顺序场景:拖拽表格行数据后,tableDataArr中数据的orderNum值会改变,实现拖拽换序。期望情况:页面根据更改后的orderNum重新排序。实际情况:接口数据变了,但是页面行数据没有改变。也就是说,页面没有实现......
  • 成品直播源码推荐,原生button按钮css去掉默认样式
    成品直播源码推荐,原生button按钮css去掉默认样式button{border:none;margin:0;padding:0;outline:none;border-radius:0;line-height:normal;}button::after{  border:none;}​以上就是成品直播源码推荐,原生button按钮css去掉默认样式,更多内容欢迎关注之后的文章 ......
  • app直播源代码,JS 替换日期的横杠为斜杠
    app直播源代码,JS替换日期的横杠为斜杠例如1:   vardt="2010-01-05";      vardt=dt.replace("-","/");    //只替换第一个“-”:2010/01-05  alert(dt); ​例如2:   vardt="2010-01-05";     vardt=dt.replace(/-/g,"/&q......
  • 银行转账p图手机软件,实现回执单截图生成,用Swing或JavaFX实现
    其实总体用了很少的代码,就是模版图+框架代码实现,模版也是网上的,非常多总体实现的原理还是绘图功能,捕捉用户输入。用户界面(UI):我们可以使用Swing或JavaFX来创建一个窗口界面,允许用户输入所需的信息。数据处理:应用程序将需要处理用户输入,并将这些信息转换成回执单的格式。生......
  • 原生JS上传大文件分片
    上传大文件分片是一种常见的上传方式,可以有效地避免上传过程中出现网络中断等问题导致的上传失败。下面是一个使用原生JS实现上传大文件分片的示例代码: javascript//定义上传文件的分片大小constCHUNK_SIZE=1024*1024;//1MB//获取文件的MD5值functiongetFi......
  • VSCode 中 Json 文件介绍
    VisualStudioCode官方文档1.Json配置文件EditingJSONwithVisualStudioCodesettings.json分类defaultsettings.json:只读格式,相当于官方的参考文档;settings.json:自定义形式,优先级大于默认的settings.json文件,ctrl+shift+o查看默认提供的格式,而后自定......
  • js:React中使用classnames实现按照条件将类名连接起来
    参考文档https://www.npmjs.com/package/classnameshttps://github.com/JedWatson/classnames安装npminstallclassnames示例importclassNamesfrom"classnames";//字符串合并console.log(classNames("foo","bar"));//foobar//对象合并console.lo......
  • js:可选链运算符(?.)和空值合并运算符(??)
    文档:可选链运算符(?.)https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining空值合并运算符(??)https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing目录1、可选链运算符(?.)2、空值合并运算......
  • 基于React使用swiperjs实现竖向滚动自动轮播
    很多文章,都只提供了js部分,包括官方的文档也只有js部分,如果css设置不正确,会导致轮播图不自动播放。使用的swiper版本:v11.0.3文档https://swiperjs.com/get-startedhttps://swiperjs.com/react实现效果使用vite创建react应用pnpmcreatevitereact-app--templatereact完整依赖pac......
  • js运行机制
    区分进程和线程线程和进程区分不清,是很多新手都会犯的错误,没有关系。这很正常。先看看下面这个形象的比喻:进程是一个工厂,工厂有它的独立资源工厂之间相互独立线程是工厂中的工人,多个工人协作完成任务工厂内有一个或多个工人工人之间共享空间再完善完善概念:工......