纯js实现录屏并保存视频到本地的尝试

前言:先了解下:navigator.mediaDevices,mediaDevices 是 Navigator 只读属性,返回一个 MediaDevices 对象,该对象可提供对相机和麦克风等媒体输入设备的连接访问,也包括屏幕共享。
const media = navigator.mediaDevices;

通过原型链可以查找到一些方法,如下图所示:通过打印如下:

其中 getDisplayMedia 方法来获取用户的屏幕分享或屏幕捕获流,通常用于制作屏幕录像或视频会议等应用。

navigator.mediaDevices.getDisplayMedia({video: true,
});

在这段代码中,请求获取包含视频流的媒体许可,并将其存储在名为 stream 的变量中,以便后续使用。这个流可以用于在网页上显示屏幕共享或进行其他媒体处理操作。

又因为该方法是异步的,我们要编写如下代码:

<body><button>共享屏幕</button><script>const button = document.querySelector("button");button.addEventListener("click", async () => {const stream = await navigator.mediaDevices.getDisplayMedia({video: true,});});</script>
</body>

通过点击 button 按钮后会如下图所示效果:

这个时候 stream 流我们是拿到了。 

                                        MediaRecorder

MediaRecorder 是一个 Web API,用于在浏览器中进行媒体录制,主要用于录制音频和视频。它允许你从不同的来源,例如麦克风、摄像头、屏幕共享或其他媒体元素,捕获音频和视频数据,并将其保存为文件或进行实时流媒体传输。通过调用 MediaRecorder.isTypeSupported() 方法会判断其 MIME 格式能否被客户端录制。它支持的类型主要有以下几种方式:

const types = ["video/webm","audio/webm","video/webm;codecs=vp8","video/webm;codecs=daala","video/webm;codecs=h264","audio/webm;codecs=opus","video/mpeg",
];

通过这种方式来查看当前浏览器是否支持该类型,如下代码所示:

const mime = MediaRecorder.isTypeSupported("video/webm;codecs=h264")? "video/webm;codecs=h264": "video/webm";

结果如下图所示:

const mediaRecorder = new MediaRecorder(stream, { mimeType: mime });

在这段代码里面,执行 new 关键字实例化 MediaRecorder 对象。该对象的结构如下图所示:

我们可以通过监听它的事件来进行不同的操作,如下代码所示:

const chunks = [];
mediaRecorder.addEventListener("dataavailable", function (e) {chunks.push(e.data);
});mediaRecorder.addEventListener("stop", () => {const blob = new Blob(chunks, { type: chunks[0].type });const url = URL.createObjectURL(blob);const a = document.createElement("a");a.href = url;a.download = "video.webm";a.click();
});

接下来我们来看看段代码的详细步骤:

  • dataavailable 事件的监听器。当 MediaRecorder 有可用的音频/视频数据块时,它会触发此事件。在这里,每当数据可用时,将数据块(e.data)添加到 chunks 数组中。这是为了在录制完成后将这些数据块合并成一个完整的媒体文件。

  • stop 事件的监听器。当录制停止时,MediaRecorder 会触发此事件。

  • const blob = new Blob(chunks, { type: chunks[0].type });:使用 Blob 构造函数将 chunks 数组中的数据块合并成一个二进制对象(Blob 对象)。chunks[0].type 用于指定 Blob 的媒体类型,通常是 WebM。

  • const url = URL.createObjectURL(blob);使用 URL.createObjectURL 方法将 Blob 对象转换为一个临时 URL。这个 URL 可以用于创建下载链接。通过这个 url 传递给新创建的 a 元素用于下载功能。

  • a.click() 通过模拟点击超链接来触发下载操作。用户将看到一个下载对话框,允许他们保存录制的媒体文件

这样就实现了一个屏幕录制功能了,并且通过该方法实现了一个音视频下载的功能。

完整代码

该功能的完整代码如下所示:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><button>共享屏幕</button><script>const button = document.querySelector("button");button.addEventListener("click", async () => {const stream = await navigator.mediaDevices.getDisplayMedia({video: true,});const mime = MediaRecorder.isTypeSupported("video/webm;codecs=h264")? "video/webm;codecs=h264": "video/webm";const mediaRecorder = new MediaRecorder(stream, { mimeType: mime });const chunks = [];mediaRecorder.addEventListener("dataavailable", function (e) {chunks.push(e.data);});mediaRecorder.addEventListener("stop", () => {const blob = new Blob(chunks, { type: chunks[0].type });const url = URL.createObjectURL(blob);const a = document.createElement("a");a.href = url;a.download = "video.webm";a.click();});mediaRecorder.start();});</script></body>
</html>

完整效果如下图所示:

你也可以直接在其他任何一个页面,将 js 代码修改一下,然后直接复制粘贴到控制台上,并点击页面,如下所示:

diff

-const button = document.querySelector("button");
-button.addEventListener("click", async () => {...
})+const body = document.body;
+body.addEventListener("click", async () => {....
})

 紧接着将代码复制粘贴到浏览器控制台上面,并点击页面的空白处:

	const body = document.body;body.addEventListener("click", async () => {const stream = await navigator.mediaDevices.getDisplayMedia({video: true,});const mime = MediaRecorder.isTypeSupported("video/webm;codecs=h264")? "video/webm;codecs=h264": "video/webm";const mediaRecorder = new MediaRecorder(stream, { mimeType: mime });const chunks = [];mediaRecorder.addEventListener("dataavailable", function (e) {chunks.push(e.data);});mediaRecorder.addEventListener("stop", () => {const blob = new Blob(chunks, { type: chunks[0].type });const url = URL.createObjectURL(blob);const a = document.createElement("a");a.href = url;a.download = "video.mp4";a.click();});mediaRecorder.start();});

通过这种方式就实现了一种屏幕录制或者屏幕分享的功能了。 

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

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

相关文章

【刷题】DFS

DFS 递归&#xff1a; 1.判断是否失败终止 2.判断是否成功终止&#xff0c;如果成功的&#xff0c;记录一个成果 3.遍历各种选择&#xff0c;在这部分可以进行剪枝 4.在每种情况下进行DFS&#xff0c;并进行回退。 199. 二叉树的右视图 给定一个二叉树的 根节点 root&#x…

深度学习之十二(图像翻译AI算法--UNIT(Unified Neural Translation))

概念 UNIT(Unified Neural Translation)是一种用于图像翻译的 AI 模型。它是一种基于生成对抗网络(GAN)的框架,用于将图像从一个域转换到另一个域。在图像翻译中,这意味着将一个风格或内容的图像转换为另一个风格或内容的图像,而不改变图像的内容或语义。 UNIT 的核心…

IDEA2022 Git 回滚及回滚内容恢复

IDEA2022 Git 回滚 ①选择要回滚的地方&#xff0c;右键选择 ②选择要回滚的模式 ③开始回滚 ④soft模式回滚的内容会保留在暂存区 ⑤输入git push -f &#xff0c;然后重新提交&#xff0c;即可同步远程 注意观察IDEA右下角分支的标记&#xff0c;蓝色代表远程内容未同步到本…

数据结构 / day06 作业

1.下面的代码打印在屏幕上的值是多少? /下面的代码打印在屏幕上的值是多少?#include "stdio.h"int compute_data(int arr[], unsigned int len) {long long int result 0;if(result len)return arr[0];resultcompute_data(arr,--len);printf("len%d, res…

elementui中table进行表单验证

<el-form :model"ruleForm" ref"ruleForm" class"demo-ruleForm"><el-table :data"ruleForm.tableDataShou" border style"width: 100%;"><el-table-column type"index" label"序号" wi…

【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能

文章目录 ⭐⭐⭐Spring核心源码分析自定义Spring框架⭐⭐⭐一、Spring使用回顾二、Spring核心功能结构1、Spring核心功能2、bean概述 三、Spring IOC相关接口分析1、BeanFactory解析2、BeanDefinition解析3、BeanDefinitionReader解析4、BeanDefinitionRegistry解析5、创建容器…

伪集群配置

编辑core-site 配置core-site 配置hdfs-site 将以下的文件配置进去 启动一下hadoop产生tmp文件 产生这个叫namenode的文件并格式化 回到~目录 再配置以下信息 配置以下信息 重启文件 再重新格式化配置namenode 再启动一下&#xff0c;然后jps看看&#xff0c;出现这样就…

java后端自学总结

自学总结 MessageSource国际化接口总结 MessageSource国际化接口 今天第一次使用MessageSource接口,比较意外遇到了一些坑 messageSource是spring中的转换消息接口&#xff0c;提供了国际化信息的能力。MessageSource用于解析 消息&#xff0c;并支持消息的参数化和国际化。 S…

运维知识点-openResty

openResty 企业级实战——畅购商城SpringCloud-网站首页高可用解决方案-openRestynginxlua——实现广告缓存测试企业级实战——畅购商城SpringCloud-网站首页高可用解决方案-openRestynginxlua——OpenResty 企业级实战——畅购商城SpringCloud-网站首页高可用解决方案-openRes…

优化器原理——权重衰减(weight_decay)

优化器原理——权重衰减&#xff08;weight_decay&#xff09; weight_decay的作用 原理解析 实验观察 在深度学习中&#xff0c;优化器的 weight_decay 参数扮演着至关重要的角色。它主要用于实现正则化&#xff0c;以防止模型过拟合。过拟合是指模型在训练数据上表现优异&…

从意义中恢复,而不是从数据包中恢复

从书报&#xff0c;录放机&#xff0c;电视机到智能手机&#xff0c;vr 眼镜&#xff0c;所有学习的&#xff0c;娱乐的工具或玩具&#xff0c;几乎都以光声诉诸视听&#xff0c;一块屏幕和一个喇叭。 视觉和听觉对任何动物都是收发信息的核心&#xff0c;诉诸视觉和听觉的光和…

机器学习笔记 - 3D数据的常见表示方式

一、简述 从单一角度而自动合成3D数据是人类视觉和大脑的基本功能,这对计算机视觉算法来说是比较难的。但随着LiDAR、RGB-D 相机(RealSense、Kinect)和3D扫描仪等3D传感器的普及和价格的降低,3D 采集技术的最新进展取得了巨大飞跃。与广泛使用的 2D 数据不同,3D 数据具有丰…

[node] Node.js 中Stream流

[node] Node.js 中Stream流 什么是 Stream流操作从流中读取数据写入流管道流链式流 什么是 Stream Stream 是一个抽象接口&#xff0c;Node 中有很多对象实现了这个接口。例如&#xff0c;对http 服务器发起请求的request 对象就是一个 Stream&#xff0c;还有stdout&#xff…

(C++)复写零--双指针法

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://le…

ESP32-Web-Server 实战编程- 使用 AJAX 自动更新网页内容

ESP32-Web-Server 实战编程- 使用 AJAX 自动更新网页内容 概述 什么是 AJAX &#xff1f; AJAX Asynchronous JavaScript and XML&#xff08;异步的 JavaScript 和 XML&#xff09;。 AJAX 是一种用于创建快速动态网页的技术。 传统的网页&#xff08;不使用 AJAX&#…

Linux 进程(一)

1 操作系统 概念&#xff1a;任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。笼统的理解&#xff0c;操作系统包括 内核&#xff08;进程管理&#xff0c;内存管理&#xff0c;文件管理&#xff0c;驱动管理&#xff09; 其他程序&#xff08;例…

linux安装docker(脚本一键安装配置docker)

1、创建脚本 vi initDocker.sh #安装前先更新yum&#xff0c;防止连接镜像失败 yum -y update#卸载系统之前的docker&#xff08;可选择&#xff0c;我这里直接注释了&#xff09; #yum remove docker docker-client docker-client-latest docker-common docker-latest docke…

Go 谈论了解Go语言

一、引言 Go的历史回顾 Go语言&#xff08;通常被称为Go或Golang&#xff09;由Robert Griesemer、Rob Pike和Ken Thompson在2007年开始设计&#xff0c;并于2009年正式公开发布。这三位设计者都曾在贝尔实验室工作&#xff0c;拥有丰富的编程语言和操作系统研究经验。Go的诞生…

Wordpress自动定时发布怎么开通-Wordpress怎么自动发布原创文章

在当今数字化时代&#xff0c;博客已经成为许多人分享观点、经验和知识的重要平台。然而&#xff0c;对于博主们来说&#xff0c;每天按时发布一篇又一篇的文章可能是一项具有挑战性的任务。为了解决这个问题&#xff0c;一些创新的工具应运而生&#xff0c;其中包括WordPress的…

vuepress-----4、侧边栏

# 4、侧边栏 # 自动生成侧栏 如果你希望自动生成一个仅仅包含了当前页面标题&#xff08;headers&#xff09;链接的侧边栏&#xff0c;你可以通过 YAML front matter 来实现&#xff1a; --- sidebar: auto ---你也可以通过配置来在所有页面中启用它&#xff1a; // .vuep…