MediaStream Recording API

MediaStream Recording API 有时简称为 Media Recording API 或者 MediaRecorder API,与媒体捕捉与媒体流 APIWebRTC API 密切相关。MediaStream Recording API 使得捕获通过 MediaStream 或者HTMLMediaElement 对象产生的用于分析、加工或者保存到硬盘的数据成为可能。它也非常容易让人们使用。

基本概念

MediaStream Recording API 由一个主接口MediaRecorder组成,这个接口负责的所有工作是从MediaStream获取数据并将其传递给你进行处理。数据通过一系列 dataavailable 事件传递,这些数据已经成为你创建 MediaRecorder 时所声明的格式。然后,你可以进一步处理数据,或者根据需要将其写入文件。

录制过程概述

记录一个流的过程是非常容易的:

  1. 建立一个 MediaStream或者HTMLMediaElement (以 <audio><video> 元素的形式) 来充当媒体数据的源。
  2. 创建一个 MediaRecorder 对象,指定源以及任何有需求的选项 (比如容器的 MIME 类型或它轨道所需的比特率).
  3. dataavailable 事件设置MediaRecorder.ondataavailable 事件处理函数; 会在数据可利用时候调用。
  4. 一旦媒体源播放,你已经准备好录制,使用 MediaRecorder.start() (en-US) 开始录制。
  5. dataavailable 事件处理函数正如你所愿的在每次数据准备好时调用; 这个事件有一个值为包含媒体数据的Blob 类型的 data 属性。你可以强制 dataavailable 事件发生,因此会给你传递最新的声音以至于可以让你过滤、保存或者做一些其他的事情。
  6. 当源媒体停止播放时候,录制自动结束。
  7. 你可以随时结束录制通过使用 MediaRecorder.stop() (en-US).

备注: 单单使用包含已经录制好媒体切片的Blobs 将大可不能单独播放。媒体在重放之前需要重新组装。

如果在录制过程中出错,error 事件将会传给MediaRecorder. 你可以设置onerror (en-US)去监听 error 事件。

例子中,我们使用 Canvas 作为MediaStream的源,在 9 秒后停止录音。

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

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

console.log(stream);
var options = { mimeType: "video/webm; codecs=vp9" };
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() {
  var blob = new Blob(recordedChunks, {
    type: "video/webm",
  });
  var url = URL.createObjectURL(blob);
  var a = document.createElement("a");
  document.body.appendChild(a);
  a.style = "display: none";
  a.href = url;
  a.download = "test.webm";
  a.click();
  window.URL.revokeObjectURL(url);
}

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

检查 and 控制记录器的状态

你也可以使用 MediaRecorder 对象的属性去决定录制过程的状态,用 pause() (en-US)resume() (en-US) 方法暂停或者继续媒体源的录制。

如果你需要检查一个特殊的 MIME 类型是否被支持,使用MediaRecorder.isTypeSupported().

检查潜在的输入源

如果你的目标是记录摄像头或麦克风输入,你可能希望在构建 MediaRecorder 之前检查可用的输入设备。这时,你需要调用 navigator.mediaDevices.enumerateDevices() 来得到可使用的媒体设备。你可以检查此列表,发现潜在的设备,甚至在有需要的时候过滤掉设备。

在这块代码中,enumerateDevices() 被用来检查可利用的设备,找到那些音频输入设备,创建<option> 元素,之后添加到<select>元素,代表输入源选择器 .

js
navigator.mediaDevices.enumerateDevices().then(function (devices) {
  devices.forEach(function (device) {
    let menu = document.getElementById("inputdevices");
    if (device.kind == "audioinput") {
      let item = document.createElement("option");
      item.innerHTML = device.label;
      item.value = device.deviceId;
      menu.appendChild(item);
    }
  });
});

类似的代码可以用来让用户限制他们希望使用的设备。

更多信息

更多关于 MediaStream Recording API 的使用,查看 Using the MediaStream Recording API, 这个显示了如何使用 API 来记录音频剪辑。另一篇文章,Recording a media element (en-US), 介绍了如何从 <audio><video> 元素 接收信息流和如何使用接收到的信息流(这个案例中,接收、存到硬盘)。

参考

BlobEvent (en-US)

Each time a chunk of media data is finished being recorded, it's delivered to consumers in Blob form using a BlobEvent (en-US) of type dataavailable.

MediaRecorder

The primary interface that implements the MediaStream Recording API.

MediaRecorderErrorEvent (en-US)

The interface that represents errors thrown by the MediaStream Recording API. Its error (en-US) property is a DOMException that specifies that error occurred.

规范

Specification
MediaStream Recording

浏览器兼容性

BCD tables only load in the browser

参阅