MediaStream Recording API

Baseline 廣泛可用 *

此特性已得到良好支援,可在多種裝置和瀏覽器版本上使用。自 2021 年 4 月起,所有瀏覽器均已支援此特性。

* 此特性的某些部分可能存在不同級別的支援。

MediaStream Recording API(有時也稱為 Media Recording APIMediaRecorder API)與 Media Capture and Streams APIWebRTC API 密切相關。MediaStream Recording API 可以捕獲由 MediaStreamHTMLMediaElement 物件生成的資料,用於分析、處理或儲存到磁碟。使用起來也異常簡單。

概念與用法

MediaStream Recording API 由一個主要介面 MediaRecorder 組成,該介面負責將 MediaStream 的資料提供給您進行處理。資料透過一系列 dataavailable 事件傳遞,這些資料已是建立 MediaRecorder 時指定的格式。然後,您可以根據需要進一步處理資料或將其寫入檔案。

錄製流程概述

錄製流的過程很簡單:

  1. 設定一個 MediaStreamHTMLMediaElement(以 <audio><video> 元素的形式)作為媒體資料來源。
  2. 建立一個 MediaRecorder 物件,指定源流和任何所需的選項(例如容器的 MIME 型別或其軌道的所需位元率)。
  3. ondataavailable 設定為 dataavailable 事件的處理程式;每當有可用資料時,都會呼叫此處理程式。
  4. 一旦源媒體開始播放,並且您已準備好錄製影片,請呼叫 MediaRecorder.start() 開始錄製。
  5. 您的 dataavailable 事件處理程式會在每次有資料準備好供您使用時被呼叫;該事件有一個 data 屬性,其值是一個包含媒體資料的 Blob。您可以強制觸發一個 dataavailable 事件,從而將最新的聲音傳遞給您,以便您可以對其進行過濾、儲存或其他操作。
  6. 源媒體停止播放時,錄製會自動停止。
  7. 您可以透過呼叫 MediaRecorder.stop() 隨時停止錄製。

注意:包含錄製媒體切片的單個 Blob 不一定能單獨播放。需要先將媒體重新組合才能播放。

如果在錄製過程中發生任何錯誤,將向 MediaRecorder 傳送一個 error 事件。您可以透過設定 onerror 事件處理程式來監聽 error 事件。

在此示例中,我們使用 HTML Canvas 作為 MediaStream 的源,並在 9 秒後停止錄製。

js
const canvas = document.querySelector("canvas");

// Optional frames per second argument.
const stream = canvas.captureStream(25);
const recordedChunks = [];

console.log(stream);
const options = { mimeType: "video/webm; codecs=vp9" };
const mediaRecorder = new MediaRecorder(stream, options);

mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();

function handleDataAvailable(event) {
  console.log("data-available");
  if (event.data.size > 0) {
    recordedChunks.push(event.data);
    console.log(recordedChunks);
    download();
  } else {
    // …
  }
}
function download() {
  const blob = new Blob(recordedChunks, {
    type: "video/webm",
  });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  document.body.appendChild(a);
  a.style = "display: none";
  a.href = url;
  a.download = "test.webm";
  a.click();
  URL.revokeObjectURL(url);
}

// demo: to download after 9sec
setTimeout((event) => {
  console.log("stopping");
  mediaRecorder.stop();
}, 9000);

檢查和控制錄製器狀態

您還可以使用 MediaRecorder 物件的屬性來確定錄製過程的狀態,並使用其 pause()resume() 方法來暫停和恢復源媒體的錄製。

如果您需要或想檢查特定 MIME 型別是否受支援,這也是可能的。只需呼叫 MediaRecorder.isTypeSupported() 即可。

檢查潛在的輸入源

如果您的目標是錄製攝像頭和/或麥克風輸入,您可能希望在開始構造 MediaRecorder 之前檢查可用的輸入裝置。為此,您需要呼叫 navigator.mediaDevices.enumerateDevices() 來獲取可用媒體裝置列表。然後,您可以檢查該列表並識別潛在的輸入源,甚至可以根據所需的條件過濾列表。

在此程式碼片段中,enumerateDevices() 用於檢查可用的輸入裝置,找到音訊輸入裝置,並建立 <option> 元素,然後將這些元素新增到代表輸入源選擇器的 <select> 元素中。

js
navigator.mediaDevices.enumerateDevices().then((devices) => {
  devices.forEach((device) => {
    const menu = document.getElementById("input-devices");
    if (device.kind === "audioinput") {
      const item = document.createElement("option");
      item.textContent = device.label;
      item.value = device.deviceId;
      menu.appendChild(item);
    }
  });
});

可以使用類似的程式碼讓使用者限制他們希望使用的裝置集。

瞭解更多資訊

要了解更多關於使用 MediaStream Recording API 的資訊,請參閱 使用 MediaStream Recording API,其中介紹瞭如何使用該 API 錄製音訊片段。第二篇文章 錄製媒體元素 描述瞭如何從 <audio><video> 元素接收流,並使用捕獲的流(在此案例中,將其錄製並儲存到本地磁碟)。

介面

BlobEvent

每次錄製完一塊媒體資料後,它都會透過型別為 dataavailableBlobEventBlob 形式傳遞給消費者。

MediaRecorder

實現 MediaStream Recording API 的主要介面。

MediaRecorderErrorEvent 已棄用 非標準

表示 MediaStream Recording API 丟擲錯誤的介面。其 error 屬性是一個 DOMException,指定了發生的錯誤。

示例

基本影片錄製

html
<button id="record-btn">Start</button>
<video id="player" src="" autoplay controls></video>
js
const recordBtn = document.getElementById("record-btn");
const video = document.getElementById("player");

let chunks = [];
let isRecording = false;
let mediaRecorder = null;

const constraints = { video: true };

recordBtn.addEventListener("click", async () => {
  if (!isRecording) {
    // Acquire a recorder on load
    if (!mediaRecorder) {
      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      mediaRecorder = new MediaRecorder(stream);
      mediaRecorder.addEventListener("dataavailable", (e) => {
        console.log("data available");
        chunks.push(e.data);
      });
      mediaRecorder.addEventListener("stop", (e) => {
        console.log("onstop fired");
        const blob = new Blob(chunks, { type: "video/ogv; codecs=opus" });
        video.src = window.URL.createObjectURL(blob);
      });
      mediaRecorder.addEventListener("error", (e) => {
        console.error("An error occurred:", e);
      });
    }
    isRecording = true;
    recordBtn.textContent = "Stop";
    chunks = [];
    mediaRecorder.start();
    console.log("recorder started");
  } else {
    isRecording = false;
    recordBtn.textContent = "Start";
    mediaRecorder.stop();
    console.log("recorder stopped");
  }
});

規範

規範
MediaStream Recording

瀏覽器相容性

另見