Skip to main content

MediaStream Recording API - 捕获媒体生成的数据,以进行分析、处理或保存

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. MediaRecorder.ondataavailable 设置为 dataavailable 事件的事件处理程序;只要有数据可用,就会调用此方法。
  4. 一旦源媒体正在播放并且您已经准备好录制视频,请调用 MediaRecorder.start() 开始录制。
  5. 您的 dataavailable 事件处理程序在每次准备好数据时都会被调用;该事件有一个 data 属性,其值为包含媒体数据的 Blob。您可以强制触发 dataavailable 事件,从而向您提供最新的声音,以便您可以对其进行过滤、保存或其他任何操作。
  6. 当源媒体停止播放时,录制会自动停止。
  7. 您可以随时通过调用 MediaRecorder.stop() 来停止录制。

注意: 包含录制媒体片段的单个 Blob 不一定可以单独播放。媒体需要在播放前重新组装。

如果在录制过程中出现任何问题,error 事件将发送到 MediaRecorder 。您可以通过设置 onerror 事件处理程序来监听 error 事件。

例如,我们使用 HTML Canvas 作为 MediaStream 的源,并在 9 秒后停止录制。

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

// 可选的每秒帧数参数。
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);
}

// 演示:9 秒后下载
setTimeout(event => {
console.log("stopping");
mediaRecorder.stop();
}, 9000);

检查和控制记录器状态

您还可以使用 MediaRecorder 对象的属性来确定录制过程的状态,及其 pause()resume() 方法来暂停和恢复源媒体的录制。

如果您需要或想要查看是否支持特定的 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.innerText = device.label;
item.value = device.deviceId;
menu.appendChild(item);
}
});
});

与此类似的代码可用于让用户限制他们希望使用的设备集。

想要查询更多的信息

要了解有关使用 MediaStream Recording API 的更多信息,请参阅 使用 MediaStream Recording API,其中显示了如何使用 API 录制音频剪辑。第二篇文章 录制媒体元素 描述了如何从 <audio><video> 元素接收流并使用捕获的流(在本例中,记录它并将其保存到本地磁盘)。

参考

BlobEvent

每次录制完一大块媒体数据时,它都会以 Blob 形式,通过 dataavailable 类型的 BlobEvent 将其交付给消费者。

MediaRecorder

实现 MediaStream Recording API 的主要接口。

MediaRecorderErrorEvent

表示 MediaStream Recording API 抛出的错误的接口。它的 error 属性是一个 DOMException 属性,它指定发生了错误。

规范

规范状态备注
MediaStream RecordingWorking Draft初始定义

桌面浏览器兼容性

特性ChromeEdgeFirefoxInternet ExplorerOperaSafari
基础支持4779251不支持3614
MediaRecorder() 构造函数477925不支持3614
audioBitrateMode8989不支持不支持75不支持
audioBitsPerSecond497971不支持3614.1
dataavailable 事件497925不支持3614
error 事件49279225不支持36214
isTypeSupported477925不支持3614
mimeType

49

47 — 493

79254不支持3614
pause497925不支持3614.1
pause 事件497965不支持3614.1
requestData497925不支持3614
resume497925不支持3614.1
resume 事件497965不支持3614.1
start477925不支持3614
start 事件497925不支持3614
state

49

47 — 493

7925不支持3614
stop497925不支持3614
stop 事件497925不支持3614
stream

49

47 — 493

7925不支持3614
videoBitsPerSecond497971不支持3614.1
warning 事件497925 — 71不支持36不支持

移动浏览器兼容性

特性AndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
基础支持4747未知251未知3614
MediaRecorder() 构造函数4747未知25未知3614
audioBitrateMode8989未知不支持未知63不支持
audioBitsPerSecond4949未知79未知3614.5
dataavailable 事件4949未知25未知3614
error 事件492492未知25未知36214
isTypeSupported4747未知25未知3614
mimeType

49

47 — 493

49

47 — 493

未知25未知3614
pause4949未知25未知3614.5
pause 事件4949未知65未知3614.5
requestData4949未知25未知3614
resume4949未知25未知3614.5
resume 事件4949未知65未知3614.5
start4747未知25未知3614
start 事件4949未知25未知3614
state

49

47 — 493

49

47 — 493

未知25未知3614
stop4949未知25未知3614
stop 事件4949未知25未知3614
stream49

49

47 — 493

未知25未知3614
videoBitsPerSecond4949未知79未知3614.5
warning 事件4949未知25未知36不支持

1. Before Firefox 58, using MediaStream.addTrack() on a stream obtained using getUserMedia(), then attempting to record the resulting stream would result in only recording the original stream without the added tracks (severe bug).

2. The interface for this event is a plain Event, not MediaRecorderErrorEvent. See bug 1250432.

3. Before Chrome 49, only video is supported, not audio.

4. 从 Firefox 71 开始, mimeType 的行为更加一致。例如,它现在即使在录制停止后也会返回媒体类型。