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
时指定的格式。然后,您可以进一步处理数据或根据需要将其写入文件。
记录过程概述
记录流的过程很简单:
- 设置
MediaStream
或HTMLMediaElement
(以<audio>
或<video>
的元素的形式)作为媒体数据的来源。 - 创建一个
MediaRecorder
对象,指定源流和任何所需的选项(例如容器的 MIME 类型或其轨道的所需比特率)。 - 将
MediaRecorder.ondataavailable
设置为dataavailable
事件的事件处理程序;只要有数据可用,就会调用此方法。 - 一旦源媒体正在播放并且您已经准备好录制视频,请调用
MediaRecorder.start()
开始录制。 - 您的
dataavailable
事件处理程序在每次准备好数据时都会被调用;该事件有一个data
属性,其值为包含媒体数据的Blob
。您可以强制触发dataavailable
事件,从而向您提供最新的声音,以便您可以对其进行过滤、保存或其他任何操作。 - 当源媒体停止播放时,录制会自动停止。
- 您可以随时通过调用
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 Recording | 工作草案 | 初始定义 |
桌面浏览器兼容性
特性 | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
基础支持 | 47 | 79 | 251 | 不支持 | 36 | 不支持 |
MediaRecorder() 构造函数 | 47 | 79 | 25 | 不支持 | 36 | 不支持 |
audioBitsPerSecond | 49 | 79 | 71 | 不支持 | 36 | 不支持 |
error 事件 | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
ignoreMutedMedia | 49 — 57 | 不支持 | 未知 | 不支持 | 36 — 44 | 不支持 |
isTypeSupported | 47 | 79 | 25 | 不支持 | 36 | 不支持 |
mimeType | 49 47 — 492 | 79 | 253 | 不支持 | 36 | 不支持 |
ondataavailable | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
onerror | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
onpause | 49 | 79 | 65 | 不支持 | 36 | 不支持 |
onresume | 49 | 79 | 65 | 不支持 | 36 | 不支持 |
onstart | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
onstop | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
onwarning | 49 | 79 | 25 — 71 | 不支持 | 36 | 不支持 |
pause | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
requestData | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
resume | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
start | 47 | 79 | 25 | 不支持 | 36 | 不支持 |
state | 49 47 — 492 | 79 | 25 | 不支持 | 36 | 不支持 |
stop | 49 | 79 | 25 | 不支持 | 36 | 不支持 |
stream | 49 47 — 492 | 79 | 25 | 不支持 | 36 | 不支持 |
videoBitsPerSecond | 49 | 79 | 71 | 不支持 | 36 | 不支持 |
warning 事件 | 49 | 79 | 25 — 71 | 不支持 | 36 | 不支持 |
移动浏览器兼容性
特性 | Android | Chrome for Android | Edge mobile | Firefox for Android | IE mobile | Opera Android | iOS Safari |
---|---|---|---|---|---|---|---|
基础支持 | 47 | 47 | 未知 | 251 | 未知 | 36 | 不支持 |
MediaRecorder() 构造函数 | 47 | 47 | 未知 | 25 | 未知 | 36 | 不支持 |
audioBitsPerSecond | 49 | 49 | 未知 | 未知 | 未知 | 36 | 不支持 |
error 事件 | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
ignoreMutedMedia | 49 — 57 | 49 — 57 | 未知 | 未知 | 未知 | 36 — 44 | 不支持 |
isTypeSupported | 47 | 47 | 未知 | 25 | 未知 | 36 | 不支持 |
mimeType | 49 47 — 492 | 49 47 — 492 | 未知 | 25 | 未知 | 36 | 不支持 |
ondataavailable | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
onerror | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
onpause | 49 | 49 | 未知 | 65 | 未知 | 36 | 不支持 |
onresume | 49 | 49 | 未知 | 65 | 未知 | 36 | 不支持 |
onstart | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
onstop | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
onwarning | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
pause | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
requestData | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
resume | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
start | 47 | 47 | 未知 | 25 | 未知 | 36 | 不支持 |
state | 49 47 — 492 | 49 47 — 492 | 未知 | 25 | 未知 | 36 | 不支持 |
stop | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
stream | 49 | 49 47 — 492 | 未知 | 25 | 未知 | 36 | 不支持 |
videoBitsPerSecond | 49 | 49 | 未知 | 未知 | 未知 | 36 | 不支持 |
warning 事件 | 49 | 49 | 未知 | 25 | 未知 | 36 | 不支持 |
1. 在 Firefox 58 之前,在使用 getUserMedia()
获取的流上使用 code>MediaStream.addTrack(),然后尝试记录结果流将导致仅记录没有添加轨道的原始流(严重错误)。
2. 在 Chrome 49 之前,只支持视频,不支持音频。
3. 从 Firefox 71 开始, mimeType
的行为更加一致。例如,它现在即使在录制停止后也会返回媒体类型。