MediaStream Recording API

MediaStream Recording API 有时简称为Media Recording API 或者 MediaRecorder API, 与 Media Capture and Streams API 和 WebRTC 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 (en-US) 事件将会传给MediaRecorder. 你可以设置onerror (en-US)去监听 error 事件.

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

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()resume() (en-US) 方法暂停或者继续媒体源的录制.

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

检查潜在的输入源

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

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

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, 介绍了如何从 <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 Status Comment
MediaStream Recording Working Draft Initial definition

浏览器支持情况

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help! (en-US)

Feature Chrome Firefox (Gecko) Internet Explorer Microsoft Edge Opera Safari (WebKit)
Basic support 47.0 25.0 (25.0) 未实现 ? 未实现 未实现
Feature Android Android Webview Firefox Mobile (Gecko) Firefox OS IE Phone Opera Mobile Safari Mobile Chrome for Android
Basic support 未实现 47.0 25.0 (25.0) 1.3[1] 未实现 未实现 未实现 47.0

[1] The initial Firefox OS implementation only supported audio recording.

[2] To use MediaRecorder in Chrome 47 and 48, enable experimental Web Platform features from the chrome://flags page.

[3] Audio recording works in Chrome 49 and above; Chrome 47 and 48 only support video recording.

参阅