音视频录制前需要获取到流,使用 navigator.mediaDevices
来完成。
navigator.mediaDevices
MediaDevices
接口提供访问连接媒体输入的设备,如照相机和麦克风,以及屏幕共享等。它可以使你取得任何硬件资源的媒体数据。
简单介绍一下MediaDevices
API。
- 方法
名称 | 说明 |
---|---|
getDisplayMedia() | 提示用户选择显示器或显示器的一部分(例如窗口)以捕获为 MediaStream 以便共享或记录。返回解析为 MediaStream 的 Promise |
getUserMedia() | 在用户通过提示允许的情况下,打开系统上的相机或屏幕共享和/或麦克风,并提供 MediaStream 包含视频轨道和/或音频轨道的输入 |
官方示例如下:
"use strict";
// Put variables in global scope to make them available to the browser console.
var video = document.querySelector("video");
var constraints = (window.constraints = {
audio: false,
video: true,
});
var errorElement = document.querySelector("#errorMsg");
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
var videoTracks = stream.getVideoTracks();
console.log("Got stream with constraints:", constraints);
console.log("Using video device: " + videoTracks[0].label);
stream.onended = function () {
console.log("Stream ended");
};
window.stream = stream; // make variable available to browser console
video.srcObject = stream;
})
.catch(function (error) {
if (error.name === "ConstraintNotSatisfiedError") {
errorMsg(
"The resolution " +
constraints.video.width.exact +
"x" +
constraints.video.width.exact +
" px is not supported by your device.",
);
} else if (error.name === "PermissionDeniedError") {
errorMsg(
"Permissions have not been granted to use your camera and " +
"microphone, you need to allow the page access to your devices in " +
"order for the demo to work.",
);
}
errorMsg("getUserMedia error: " + error.name, error);
});
function errorMsg(msg, error) {
errorElement.innerHTML += "<p>" + msg + "</p>";
if (typeof error !== "undefined") {
console.error(error);
}
}
要实现web页面录制,需要请求获取音视频流的媒体许可,代码如下:
const button = document.querySelector("button");
button.addEventListener("click", async () => {
// 音视频都录制
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true
})
})
这样就哭呀通过button实现如下效果:
MediaRecorder
MediaRecorder
是 MediaStream Recording API 提供的用来进行媒体轻松录制的接口,他需要通过调用 MediaRecorder() 构造方法进行实例化。
简单介绍一下 MediaRecorder
API。
- 构造函数
名称 | 说明 |
---|---|
MediaRecorder() | 创建一个新的 MediaRecorder 对象,对指定的 MediaStream 对象进行录制,支持的配置项包括设置容器的 MIME 类型 (例如"video/webm" 或者 “video/mp4”) 和音频及视频的码率或者二者同用一个码率 |
- 配置项
名称 | 说明 |
---|---|
mimeType | 返回 MediaRecorder 对象创建时选择器选择的录制容器的 MIME type |
state | 返回录制对象 MediaRecorder 的当前状态 (闲置中,录制中或者暂停 ) (inactive , recording , or paused .) |
strem | 返回录制对象 MediaRecorder 创建时构造函数传入的 stream 对象 |
- 方法
名称 | 说明 |
---|---|
isTypeSupported() | 返回一个 Boolean 值,来表示设置的 MIME type 是否被当前用户的设备支持 |
start() | 开始录制媒体,这个方法调用时可以通过给 timeslice 参数设置一个毫秒值,如果设置这个毫秒值,那么录制的媒体会按照你设置的值进行分割成一个个单独的区块,而不是以默认的方式录制一个非常大的整块内容 |
pause() | 暂停媒体录制 |
resume() | 继续录制之前被暂停的录制动作 |
stop() | 停止录制。同时触发 dataavailable 事件,返回一个存储Blob内容的录制数据。之后不再记录 |
- 事件处理
名称 | 说明 |
---|---|
ondataavailable | 调用它用来处理 dataavailable 事件,该事件可用于获取录制的媒体资源 (在事件的 data 属性中会提供一个可用的 Blob 对象.) |
onstart | 用来处理 start 事件,该事件在媒体开始录制时触发 |
onpause | 用来处理 pause 事件,该事件在媒体暂停录制时触发 |
onresume | 用来处理 resume 事件,该事件在暂停后回复录制视频时触发 |
onstop | 用来处理 stop 事件,该事件会在媒体录制结束时、媒体流(MediaStream )结束时、或者调用 MediaRecorder.stop() 方法后触发 |
- 事件
Listen to these events using addEventListener()
or by assigning an event listener to the oneventname
property of this interface.
通过以上介绍,可以调用 MediaRecorder.isTypeSupported()
这个API来测试当前浏览器的支持情况。官方代码如下:
const types = [
"video/webm",
"audio/webm",
"video/webm;codecs=vp8",
"video/webm;codecs=daala",
"video/webm;codecs=h264",
"audio/webm;codecs=opus",
"video/mpeg",
];
for (const type of types) {
console.log(
`Is ${type} supported? ${
MediaRecorder.isTypeSupported(type) ? "Maybe!" : "Nope :("
}`,
);
}
返回结果如图:
返回值为 True
的情况下,此代码显示Maybe,原因是即使编码格式支持,但是如果没有足够的资源来支持录制和编码过程,录制仍可能失败。所以仅作为参考判断,仍需要自己写错误处理。
之后通过监听来进行下载操作,代码如下:
const chunks = [];
mediaRecorder.ondataavailable = e => chunks.push(e.data);
mediaRecorder.onstop = () => {
const blob = new Blob(chunks, { type: chunks[0].type });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "screen.webm";
a.click();
}
这样就实现了一个屏幕录制功能了,并且通过该方法实现了一个音视频下载的功能。