浏览器屏幕录制

您所在的位置:网站首页 chrome录制插件 浏览器屏幕录制

浏览器屏幕录制

2023-11-08 07:39| 来源: 网络整理| 查看: 265

最近听了组内小伙伴分享的屏幕录制的相关内容-MediaRecorder,然后成功的接入了某个内部项目中。

recorder.gif 今天跟大家分享一下如何利用MediaRecorder,几行代码实现屏幕录制的功能,以及实际场景下可能遇到的问题。

点我体验

MediaRecorder介绍

MediaRecorder 是 MediaStream Recording API 提供的用来进行媒体轻松录制的接口, 他需要通过调用 MediaRecorder() 构造方法进行实例化.

该接口对外暴露的方法和配置项也比较多,大家有兴趣的可以点这里查看

这里主要按照流程,来介绍一些常用的方法。

image.png

1、权限申请

// 获取用户屏幕录制的权限 const stream = await navigator.mediaDevices.getDisplayMedia({ video: true })

2、录制视频类型确认

// 确认当前环境所支持的屏幕录制文件类型 const mime = MediaRecorder.isTypeSupported('video/webm; codecs=vp9') ? 'video/webm; codecs=vp9' : 'video/webm'

3、实例化MediaRecorder

// 需要用到步骤1stream流和和步骤2的mimeType const mediaRecorder = new MediaRecorder(stream, { mimeType: mime })

3、事件监听

dataavailable 该事件在停止录制后触发(优先于onStop),可用于获取录制的媒体资源 (在事件的 data 属性中会提供一个可用的 Blob 对象) stop 用来处理 stop 事件, 该事件会在媒体录制结束时、媒体流(MediaStream)结束,触发dataavailable后触发。 // 用于存放录制的blob数据 const chunks = [] mediaRecorder.addEventListener('dataavailable', function (e) { chunks.push(e.data) }) mediaRecorder.addEventListener('stop', () => { const blob = new Blob(chunks, { type: chunks[0].type }) // 获取 可用的 url const url = URL.createObjectURL(blob) // 拿到临时录制文件路径后执行你的操作 // ... }

4、触发录制行为

mediaRecorder.start() 场景实战

本次应用场景是在一个内部的质量管理平台中,在提问题的步骤,通过屏幕录制来实现问题的描述,期间有遇到了一些常见的问题,跟大家分享下。

常规的富文本中粘贴图片的步骤,都是粘贴即上传,然后拿到一个url来显示,但是对于视频来说,录制完即上传,用户体验着实有点不好,并且存在资源浪费情况。

因此我们在保存的时候再去进行上传和替换。

上文提到,我们在onStop的回调中,可以拿到一个blob流,并生成一个临时路径,来供我们预览使用。

image.png

当我们保存的时候,我们需要做两件事:

1、把富文本内容中video标签src指向临时文件上传至我们自己的服务器,拿到一个真实url。

2、富文本描述中用真实的url替换掉对应的临时路径。

代码实现 export function backTraceNode(el) { if (!el?.children?.length) { return [el] } return [el, ...Array.from(el.children).map(backTraceNode)].flat() } // 1、从html字符串中提取出bolb文件临时路径 const getVideoListByHtml = (html) => { const dom = document.createElement('div') dom.innerHTML = html return backTraceNode(dom) .filter((item) => item.nodeName === 'VIDEO') .map((v) => v.src) } // 2、根据临时路径,生成相应的File const getFileFromBlobUrl = async (blobUrlList) => { const pList = list.map((url) => { return fetch(url) }) const data = await Promise.all(pList) const blobList = data.map((v) => v.blob()) const res = await Promise.all(blobList) return res.map(blob=>{ return new File([blob], 'video.webm', { type: 'video/webm' }) }) } // 3、文件上传并替换对应的url const replaceVideoUrl = (html, hashUrlMapList) => { const dom = document.createElement('div') dom.innerHTML = html const videoList = backTraceNode(dom).filter((item) => item.nodeName === 'VIDEO') videoList.forEach((el) => { el.src = 'https:' + findUrlByHash(el.src, hashUrlMapList) }) return dom.innerHTML } 注意事项 兼容性不友好,目前仅仅在Chrome中能够满足使用场景。其他浏览器有的不支持该API,有的不支持录制屏幕文件的类型。不过可以提前获取当前浏览器的支持程度,不满足的话,在交互层面设计一下就好,比如不支持该功能的话,隐藏掉或者给个提示语。 const isSupportRecorder = () => { const types = ['video/webm; codecs=vp9', 'video/webm'] const isTypeSupport = types.some((v) => MediaRecorder.isTypeSupported(v)) const isApiSupport = Boolean(navigator.mediaDevices) return isApiSupport && isTypeSupport } 出于安全性考虑,浏览器层面申请权限(navigator.mediaDevices),仅支持https或者localhost 富文本内容替换的时候如果存在多个临时文件,需要根据对应的名称hash来替换,否则可能会引起视频前后顺序错乱的问题。 参考文献 developer.mozilla.org/zh-CN/docs/… www.wangeditor.com/doc


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3