MediaStream Recording API
Baseline 广泛可用 *
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 类型或其轨道的所需比特率)。 - 将
ondataavailable设置为dataavailable事件的处理程序;每当有可用数据时,都会调用此处理程序。 - 一旦源媒体开始播放,并且您已准备好录制视频,请调用
MediaRecorder.start()开始录制。 - 您的
dataavailable事件处理程序会在每次有数据准备好供您使用时被调用;该事件有一个data属性,其值是一个包含媒体数据的Blob。您可以强制触发一个dataavailable事件,从而将最新的声音传递给您,以便您可以对其进行过滤、保存或其他操作。 - 源媒体停止播放时,录制会自动停止。
- 您可以通过调用
MediaRecorder.stop()随时停止录制。
注意:包含录制媒体切片的单个 Blob 不一定能单独播放。需要先将媒体重新组合才能播放。
如果在录制过程中发生任何错误,将向 MediaRecorder 发送一个 error 事件。您可以通过设置 onerror 事件处理程序来监听 error 事件。
在此示例中,我们使用 HTML Canvas 作为 MediaStream 的源,并在 9 秒后停止录制。
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> 元素中。
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-
每次录制完一块媒体数据后,它都会通过类型为
dataavailable的BlobEvent以Blob形式传递给消费者。 MediaRecorder-
实现 MediaStream Recording API 的主要接口。
MediaRecorderErrorEvent已弃用 非标准-
表示 MediaStream Recording API 抛出错误的接口。其
error属性是一个DOMException,指定了发生的错误。
示例
基本视频录制
<button id="record-btn">Start</button>
<video id="player" src="" autoplay controls></video>
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 |
浏览器兼容性
加载中…
另见
- Media Capture and Streams API 首页
MediaDevices.getUserMedia()- simpl.info MediaStream Recording 演示,作者:Sam Dutton
- HTML5 的 Media Recorder API 在 Chrome 和 Firefox 中的应用
- Safari 和 Edge 的 MediaRecorder polyfill
- TutorRoom:使用 getUserMedia 和 MediaStream Recording API 进行 HTML 视频捕获/播放/下载(GitHub 源代码)
- 高级媒体流录制器示例
- OpenLang:使用 MediaDevices 和 MediaStream Recording API 进行视频录制的 HTML 视频语言实验室 Web 应用程序(GitHub 源代码)
- Safari Technology Preview 73 已提供 MediaStream Recorder API