头图

Record screen using browser

Recently, there is a need to record the screen, which is similar to the operation tutorial of recording software to demonstrate to others. I searched the recording screen on the Internet, and most of the results need to be downloaded and installed, and there are charges or advertisements. I accidentally found a website that uses a browser to record screen online. Out of curiosity, I studied the implementation method, and completed a small work that can be used to share with everyone. You can click to view it .
The website address of the found online screen recording is SOOGIF. It requires you to register and log in to use the screen recording function, and after the recording is completed, you can only get a limited number of download opportunities at no cost. Therefore, I plan to make a similar application myself.

Web API interface

To achieve this function, there are two main interfaces used:

The details of the implementation are recorded below.

Populate basic page elements

If you are familiar with some web front-end knowledge, then you will be familiar with the following:

 <p>This example shows you the contents of the selected part of your display.
Click the Start Capture button to begin.</p>
<q>点击开始捕获按钮,选择你要捕获的窗口。</q>

<p>
<button id="start">开始捕获</button>&nbsp;
<button id="stop">停止捕获</button>
<button id="recordBtn">开始录制</button>
<button id="downloadBtn">下载</button>
</p>

<video id="video" autoplay></video>
<br>

<strong>Log:</strong>
<br>
<pre id="log"></pre>

Add simple styles:

 #video {
      border: 1px solid #999;
      width: 98%;
      max-width: 860px;
}
.error {
      color: red;
}
 .warn {
      color: orange;
}
.info {
      color: darkgreen;
}

Approximate appearance of the page

JavaScript handles click button logic

First get the elements on the page and declare the relevant variables:

 const startElem = document.getElementById("start");
const stopElem = document.getElementById("stop");
const videoElem = document.getElementById("video");
const logElem = document.getElementById("log");
const recordBtn = document.getElementById("recordBtn");
const downloadBtn = document.getElementById("downloadBtn");
let captureStream = null;
let mediaRecorder = null;
let isRecording = false;
let recordedBlobs = [];

Logic that handles clicking the start capture button:

 // Options for getDisplayMedia()
const displayMediaOptions = {
  video: {
    cursor: "always"
  },
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
    sampleRate: 44100
  }
};

async function startCapture(displayMediaOptions) {
  try {
    videoElem.srcObject = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
    captureStream = videoElem.srcObject
    dumpOptionsInfo();
  } catch(err) {
    console.error("Error: " + err);
  }
}

function dumpOptionsInfo() {
  const videoTrack = videoElem.srcObject.getVideoTracks()[0];
  console.info("Track settings:");
  console.info(JSON.stringify(videoTrack.getSettings(), null, 2));
  console.info("Track constraints:");
  console.info(JSON.stringify(videoTrack.getConstraints(), null, 2));
}

function stopCapture(evt) {
  let tracks = videoElem.srcObject.getTracks();
  tracks.forEach(track => track.stop());
  videoElem.srcObject = null;
  showMsg('用户停止了分享屏幕');
}

// Set event listeners for the start and stop buttons 给按钮添加监听事件
startElem.addEventListener("click", function(evt) {
  startCapture();
}, false);

stopElem.addEventListener("click", function(evt) {
  stopCapture();
}, false);

When the Start Capture button is clicked, the browser will pop up a page similar to the following:
capture
Select the browser page or window you want to record, or even the entire screen can be recorded.

When the window is selected and the share button is clicked, the data stream of the captured window will be synchronized to the video tag of our page and sampled in real time:
sample

At this point, we can record, and the logic of processing the start recording button is as follows:

 function startRecording() {
  
  const mimeType = getSupportedMimeTypes()[0];
  const options = { mimeType };

  try {
    mediaRecorder = new MediaRecorder(captureStream, options);
  } catch (e) {
    showMsg(`创建MediaRecorder出错: ${JSON.stringify(e)}`);
    return;
  }
  recordBtn.textContent = '停止录制';
  isRecording = true;
  downloadBtn.disabled = true;
  mediaRecorder.onstop = (event) => {
    showMsg('录制停止了: ' + event);
  };
  mediaRecorder.ondataavailable = handleDataAvailable;
  mediaRecorder.start();
  showMsg('录制开始 mediaRecorder: ' + mediaRecorder);
}

function handleDataAvailable(event) {
  console.log('handleDataAvailable', event);
  if (event.data && event.data.size > 0) {
    recordedBlobs.push(event.data);
  }
}

function stopRecord() {
  isRecording = false;
  mediaRecorder.stop();
  downloadBtn.disabled = false;
  recordBtn.textContent = "开始录制";
  recordedBlobs = []
}

Handle the download button logic:

 downloadBtn.addEventListener('click', () => {
  const blob = new Blob(recordedBlobs, { type: 'video/webm' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = '录屏_' + new Date().getTime() + '.webm';
  document.body.appendChild(a);
  a.click();
  setTimeout(() => {
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
  }, 100);
});

At this point, the demo of this screen recording is completed. The recorded file format is webm, you can open it in your browser.

Friends who need to use it immediately can also use the version I made directly, which has a better-looking UI. portal


web开发总结
不积跬步无以至千里
1 篇内容引用

纸上得来终觉浅,绝知此事要躬行

473 声望
27 粉丝
0 条评论
推荐阅读
onMounted is called when there is no active component 已解决
If you are using async setup(), make sure to register lifecycle hooks before the first await statement.

来了老弟阅读 125

在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 1.9k

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco18阅读 2k评论 2

你可能不需要JS!CSS实现一个计时器
CSS现在可不仅仅只是改一个颜色这么简单,还可以做很多交互,比如做一个功能齐全的计时器?样式上并不复杂,主要是几个交互的地方数字时钟的变化开始、暂停操作重置操作如何仅使用 CSS 来实现这样的功能呢?一起...

XboxYan20阅读 1.5k评论 1

封面图
「彻底弄懂」this全面解析
当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在 哪里被调用(调用栈)、函数的调用方法、传入的参数等信息。this就是记录的其中一个属性,会在 函数执行的过程中用到...

wuwhs17阅读 2.3k

封面图
用了那么久的 SVG,你还没有入门吗?
其实在大部分的项目中都有 直接 或 间接 使用到 SVG 和 Canvas,但是在大多数时候我们只是选择 简单了解 或 直接跳过,这有问题吗?没有问题,毕竟砖还是要搬的!

熊的猫16阅读 1.5k评论 2

封面图
学会这些 Web API 使你的开发效率翻倍
随着浏览器的日益壮大,浏览器自带的功能也随着增多,在 Web 开发过程中,我们经常会使用一些 Web API 增加我们的开发效率。本篇文章主要选取了一些有趣且有用的 Web API 进行介绍,并且 API 可以在线运行预览。C...

九旬12阅读 1.5k

封面图

纸上得来终觉浅,绝知此事要躬行

473 声望
27 粉丝
宣传栏