使用JavaScript实现一个录屏插件

 更新时间:2024年10月23日 09:57:09   作者:JYeontu  
不知道大家平时都是使用什么录屏软件呢,有没有想过只用JavaScript我们也可以快速实现一个录屏插件呢,感兴趣的小伙伴就跟随小编一起学习一下吧

准备工作

开始写代码前我们需要先了解一下以下几点:

1、getDisplayMedia

navigator.mediaDevices.getDisplayMedia() 是一种基于Web的API,它允许网站在获得用户同意的情况下,捕获用户的屏幕或屏幕的特定部分作为媒体流。这个API是Media Capture and Streams API的一部分,通常用于实现屏幕共享功能,例如远程协作、视频会议或直播。

基本用法

getDisplayMedia() 方法返回一个Promise,该Promise解析为一个MediaStream对象,其中包含屏幕捕获的数据。使用此方法的基本步骤如下:

  • 调用 getDisplayMedia() 并传入配置对象,指定所需的媒体类型和可选的约束条件。
  • 处理Promise解析后的MediaStream对象,例如将其用作MediaRecorder的源或显示在<video>元素中。
if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
  const displayMediaOptions = {
    video: {
      cursor: "always" // 捕获鼠标指针
    },
    audio: false // 不捕获音频
  };

  navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
    .then(stream => {
      // 屏幕捕获成功,'stream' 包含屏幕的媒体流
    })
    .catch(error => {
      // 捕获屏幕失败
      console.error("Error: ", error);
    });
}

重要特性

  • 用户授权:出于安全和隐私的考虑,浏览器要求用户明确授权才能进行屏幕捕获。
  • 异步操作getDisplayMedia() 是异步的,返回一个Promise对象。
  • 媒体类型:可以捕获视频和/或音频,具体取决于getDisplayMedia()调用中的配置选项。
  • 浏览器兼容性:不同的浏览器可能有不同的实现和支持程度,需要检查navigator.mediaDevices.getDisplayMedia是否存在。

安全和隐私

  • 屏幕捕获是一个敏感操作,因为它可能涉及到捕获用户的敏感信息。因此,浏览器会要求用户明确授权。
  • 网站在使用getDisplayMedia()时应该明确告知用户,并在获得用户同意后进行。

应用场景

  • 视频会议:用户可以共享他们的屏幕或应用程序窗口,以便在远程会议中展示内容。
  • 直播:游戏直播者可以共享他们的游戏画面。
  • 远程支持:技术支持人员可以请求访问用户的屏幕来帮助解决问题。

getDisplayMedia() 提供了一种强大的方式,允许Web应用以用户控制的方式捕获和使用屏幕内容。

2、快速开发一个插件

可以通过脚手架快速生成一个插件基本框架。

安装jyeontu脚手架

npm install jyeontu

使用脚手架快速创建新项目

jyeontu create

选择 Chrome 插件模板 即可

初始化

npm run init

打包

npm run build

插件开发

目标

1、在浏览器中页面右键菜单加上开始录屏按钮

2、点击开始录屏按钮后弹出新页面选择录取的屏幕

3、结束录屏后输出视频文件

功能实现

1、浏览器右键菜单添加按钮

const id = "screenRecording"; //generateRandomString(8);
chrome.contextMenus.create({
  title: "开始录屏", //菜单的名称
  id: id, //一级菜单的id
  contexts: ["page"], // page表示页面右键就会有这个菜单,如果想要当选中文字时才会出现此右键菜单,用:selection
});

2、监听右键菜单点击事件

这里直接借用百度首页做个中间页面来触发录屏事件

chrome.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId == id) {
    var createData = {
      url: "https://baidu.com?isStartMediaRecorder=1",
      // url: chrome.runtime.getURL("recorder.html"),
      type: "normal",
      top: 200,
      left: 300,
      width: 1300,
      height: 800,
    };
    // 创建(打开)一个新的浏览器窗口,可以提供大小、位置或默认 URL 等可选参数
    chrome.windows.create(createData);
  }
});

3、判断是否录屏弹窗

直接判断路径参数isStartMediaRecorder即可

localStorage.setItem("isMediaRecorderEnd", false);
const url = new URL(location.href);
const isStartMediaRecorder = url.searchParams.get("isStartMediaRecorder");
if (isStartMediaRecorder) {
  document.body.style.display = "flex";
  document.body.innerHTML = `<div
    style="
      font-size: large;
      margin: auto;
      font-weight: bold;
      text-align: center;
    "
  >
    录制中
  </div>`;
  startMediaRecorder();
}

4、开始录屏

function startRecorder(stream) {
  var mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")
    ? "video/webm; codecs=vp9"
    : "video/webm";
  var mediaRecorder = new MediaRecorder(stream, { mimeType: mime }); // 录制

  var chunks = [];
  mediaRecorder.addEventListener("dataavailable", function (e) {
    chunks.push(e.data);
  });

  // 监听用户取消屏幕共享
  stream.getTracks().forEach((track) => {
    track.addEventListener("ended", function (e) {
      console.log("轨道结束: ", e);
      // 用户取消屏幕共享,执行清理操作
      mediaRecorder.stop(); // 停止录制
    });
  });

  mediaRecorder.start(); // 手动启动录制
}
function startMediaRecorder() {
  navigator.mediaDevices
    .getDisplayMedia({
      video: true,
    })
    .then((stream) => {
      startRecorder(stream);
    })
    .catch((err) => {
      console.warn(err);
      localStorage.setItem("isMediaRecorderEnd", true);
    });
}

5、录屏结束

监听录屏结束事件,并使用a标签将录制视频下载到本地。

function getFormattedCurrentTime() {
  const now = new Date(); // 获取当前时间
  const year = now.getFullYear(); // 年份
  const month = (now.getMonth() + 1).toString().padStart(2, "0"); // 月份,加1因为月份是从0开始的
  const day = now.getDate().toString().padStart(2, "0"); // 日期
  const hours = now.getHours().toString().padStart(2, "0"); // 小时
  const minutes = now.getMinutes().toString().padStart(2, "0"); // 分钟
  const seconds = now.getSeconds().toString().padStart(2, "0"); // 秒
  return `${year}${month}${day}${hours}${minutes}${seconds}`;
}

mediaRecorder.addEventListener("stop", function () {
  var blob = new Blob(chunks, { type: "video/webm" }); // 确保Blob的MIME类型正确
  var url = URL.createObjectURL(blob);
  var a = document.createElement("a");
  a.href = url;
  a.download = getFormattedCurrentTime() + "-video.webm";
  a.click();
  setTimeout(() => {
    localStorage.setItem("isMediaRecorderEnd", true);
  }, 200);
});

插件使用

下载

下载地址:gitee.com/zheng_yongtao/chrome-plug-in/blob/master/screenRecording/screenRecording.zip

安装

下载解压后导入chrome:chrome://extensions/

选择解压后的文件夹即可

到此这篇关于使用JavaScript实现一个录屏插件的文章就介绍到这了,更多相关JavaScript录屏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Javascript之旅 对象的原型链之由来

    Javascript之旅 对象的原型链之由来

    本人是Javascript菜鸟,下面是前几天学习Javascript的旅程心得,希望对和我一样的入门者有点用,也希望高手批评指正。
    2010-08-08
  • 移动端手指放大缩小插件与js源码

    移动端手指放大缩小插件与js源码

    这篇文章主要介绍了移动端手指放大缩小插件与js源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • 前端常用字符串/数组操作方法实例(含相关手撕)

    前端常用字符串/数组操作方法实例(含相关手撕)

    前端开发必备的10个JavaScript对象数组操作技巧,涵盖创建、遍历、筛选、转换、排序、统计、去重、合并、更新和分页等核心场景,这篇文章主要介绍了前端常用字符串/数组操作方法的相关资料,需要的朋友可以参考下
    2026-03-03
  • CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法

    CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法

    这篇文章主要介绍了CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法,设计javascript操作菜单的弹出与关闭的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-05-05
  • webpack5 常用插件使用问题小结

    webpack5 常用插件使用问题小结

    webpack 是一个模块打包器,这篇文章主要介绍了webpack5 常用插件使用问题小结,每次打包完都需要手动删除掉dist文件目录,使用CleanWebpackPlugin就可自动清除dist目录,感兴趣的朋友跟随小编一起看看吧
    2024-02-02
  • js实现拖动滑块效果

    js实现拖动滑块效果

    这篇文章主要为大家详细介绍了js实现拖动滑块效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 关于Javascript作用域链的八点总结

    关于Javascript作用域链的八点总结

    其实吧,关于作用域链相关的文章我也看了不少,但是我一直也没能做一个详细的总结,今天把我看到的一些东西,结合自己的想法,总结成以下8个点
    2013-12-12
  • 很酷的javascript loading效果代码

    很酷的javascript loading效果代码

    很不错的loading效果代码,方便学习loading的朋友测试与学习
    2008-06-06
  • 微信小程序云开发之使用云存储

    微信小程序云开发之使用云存储

    这篇文章主要为大家详细介绍了微信小程序云开发之使用云存储,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • JavaScript获取多个数组的交集简单实例

    JavaScript获取多个数组的交集简单实例

    这篇文章介绍了JavaScript获取多个数组的交集简单实例,有需要的朋友可以参考一下
    2013-11-11

最新评论