JavaScript 屏幕錄製 API 學習

使用屏幕錄製API

前端屏幕錄製?截屏?網頁生成圖片?幀圖?說到錄屏,我一開始想到的是前面這些詞。大體的想法是持續的生成當前頁面的截圖,而後把這些幀圖再合併成一個視頻文件。前端頁面生成圖片咱們應該比較熟悉的是 html2canvas。另外也有一些現成的庫可使用來進行屏幕的錄製, RecordRTC上就有不少屏幕錄製的實現。有聲音(Audio)、視頻(Video)、屏幕(Screen)的錄製;有針對canvas的錄製等等,一共有三十多個示例。這裏主要想簡單的講一講原生的 Screen Capture API。參見: Using the Screen Capture API

1、屏幕內容的捕獲

navigator.mediaDevices.getDisplayMedia()css

該方法會返回一個promise, 該promise會resolve當前屏幕內容的實時數據流。html

使用 async / await 實現以下:前端

async function startCapture(displayMediaOptions) {
  let captureStream = null;

  try {
    captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
  } catch(err) {
    console.error("Error: " + err);
  }
  return captureStream;
}

使用 promise 的方式實現以下:web

function startCapture(displayMediaOptions) {
 let captureStream = null;

 return navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
    .catch(err => { console.error("Error:" + err); return null; });
}

咱們在獲取屏幕數據的時候有可能會獲取到一些敏感信息,全部在使用getDisplayMedia的時候,爲了安全考慮,會彈出一個選擇框,然用戶本身選擇須要共享那一部分的內容。能夠共享當前屏幕,也能夠共享其餘的應用窗口和瀏覽器的其餘標籤頁。canvas

Screen Capture API

2、參數配置:
咱們在上面的實現中能夠看到, 傳遞給startCapture函數的參數爲displayMediaOptions。這個參數是用於配置返回數據流的。數據形式以下:promise

const displayMediaOptions = {
  video: {
    cursor: "never"
  }, // 視頻信息的設置
  audio: false, // 是否包含音頻信息
  logicalSurface: false, // 設置是否包含所選屏幕外區域的一些信息
};

開能夠針對音視頻作詳細的配置:瀏覽器

const gdmOptions = {
  video: {
    cursor: "always" // 始終顯示鼠標信息
  },
  // audio 配置信息是可選的
  audio: {
    echoCancellation: true, 
    noiseSuppression: true,
    sampleRate: 44100
  } 
}

3、示例

HTML:安全

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Screen Record</title>
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
    <p>This example shows you the contents of the selected part of your display.
    Click the Start Capture button to begin.</p>
    <p><button id="start">Start Capture</button>&nbsp;<button id="stop">Stop Capture</button></p>
    <video id="video" autoplay></video>
    <br>
    <strong>Log:</strong>
    <br>
    <pre id="log"></pre>
    <script src="./js/index.js"></script>
</body>
</html>

CSS:服務器

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

JS:websocket

const videoElem = document.getElementById("video");
const logElem = document.getElementById("log");
const startElem = document.getElementById("start");
const stopElem = document.getElementById("stop");
// Options for getDisplayMedia()
const displayMediaOptions = {
  video: {
    cursor: "never"
  },
  audio: false
};
// Set event listeners for the start and stop buttons
startElem.addEventListener("click", function(evt) {
  startCapture();
}, false);
stopElem.addEventListener("click", function(evt) {
  stopCapture();
}, false);
console.log = msg => logElem.innerHTML += `${msg}<br>`;
console.error = msg => logElem.innerHTML += `<span class="error">${msg}</span><br>`;
console.warn = msg => logElem.innerHTML += `<span class="warn">${msg}<span><br>`;
console.info = msg => logElem.innerHTML += `<span class="info">${msg}</span><br>`;

async function startCapture() {
  logElem.innerHTML = "";

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

function stopCapture(evt) {
  let tracks = videoElem.srcObject.getTracks();

  tracks.forEach(track => track.stop());
  videoElem.srcObject = null;
}

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));
}

效果以下:

圖片描述

點擊Start Capture 以後選擇須要共享的部分就能夠共享以下的內容:

圖片描述

點擊Stop Capture便可˙中止錄製共享。這個例子只是調取接口獲取到當前分享屏幕的數據流,並經過video的形式顯示出來。咱們在拿到數據流信息這個,能夠把這些信息上傳到服務器,生成相應的視頻文件。也能夠結合websocket之類的處理方式,實現實時的屏幕共享功能。

相關文章
相關標籤/搜索