【JSAPI】媒体录制

2022/03/08 22:50:04

本文章介绍一些与媒体录制(音视频)相关的内容,包括:获取设备权限的 MediaDevices API、媒体流 MediaStream、控制媒体录制的 MediaRecorder API 和录制媒体的流程。

MediaDevices 媒体设备接口

MediaDevices 接口提供访问连接媒体输入的设备,如照相机和麦克风,以及屏幕共享等。它可以使你取得任何硬件资源的媒体数据。

MediaDevices 的功能集成在 navigator.mediaDevices 中。

用 MediaDevices 成功获取授权时会得到一个 MediaStream,里面包含了请求的媒体类型的轨道。可以用 MediaRecorder 进行操作。

事件

devicechange

每当媒体设备(例如相机,麦克风或扬声器)连接到系统或从系统中移除时,devicechange 事件就会被发送到 MediaDevices 实例。

navigator.mediaDevices.ondevicechange = function (event) {
  console.log(event);
};

方法

MediaDevices.enumerateDevices()

获取有关系统中可用的媒体输入和输出设备的一系列信息。

返回一个 promise,then 中包含设备信息。

navigator.mediaDevices.enumerateDevices().then((res) => {
  console.log(res);
});

MediaDevices.getSupportedConstraints()

返回一个对象,该对象指明了 MediaStreamTrack 接口支持的可约束的属性。

let SupportedConstraints = navigator.mediaDevices.getSupportedConstraints();

MediaDevices.getDisplayMedia()

提示用户选择显示器或显示器的一部分(例如窗口)以捕获为 MediaStream 以便共享或记录。返回解析为 MediaStream 的 Promise。

取消时触发 catch, 成功时 then 中包含一个 MediaStream。

navigator.mediaDevices
  .getDisplayMedia()
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });

MediaDevices.getUserMedia(constraints)

注意:此方法只能在 https 中使用,在 http 中会静默失败。

在用户通过提示允许的情况下,打开系统上的相机或屏幕共享和/或麦克风,并提供 MediaStream 包含视频轨道和/或音频轨道的输入。

参数为一个对象,需要说明要请求的设备权限。

返回一个 promise,than 中包含一个 MediaStream。

navigator.mediaDevices
  .getUserMedia({ video: true, audio: true })
  .then((res) => {
    console.log(res);
  })
  .catch((err) => {
    console.log(err);
  });

MediaRecorder 录制器接口

MediaRecorder 是用来进行媒体录制的接口, 它需要通过调用 new MediaRecorder() 构造方法实例化一个录制器对象。

构造函数

new MediaRecorder(MediaStream, options)

创建一个新的 MediaRecorder 对象,二参为可配置项。

如果视频和/或音频的比特率没有指定,视频默认采用的比特率是 2.5Mbps,但音频的默认比特率并不固定,音频的默认比特率根据采样率和轨道数自适应。

完整配置如下:

mediaRecorder = new MediaRecorder(mediaStream, {
  mimeType: "video/webm; codecs=vp9", // 返回 MediaRecorder 对象创建时选择器选择的录制容器的 MIME type
  audioBitsPerSecond: "", // 指定音频的比特率。
  videoBitsPerSecond: "", // 指定视频的比特率。
  bitsPerSecond: "", // 指定音频和视频的比特率。 此属性可以用来指定上面两个属性。 如果上面两个属性只有其中之一和此属性被指定,则此属性可以用于设定另外一个属性。
});

静态方法

MediaRecorder.isTypeSupported()

返回一个 Boolean 值,来表示设置的 MIME type 是否被当前用户的设备支持。

MediaRecorder.isTypeSupported("video/webm");

实例属性

MediaRecorder.mimeType

返回 MediaRecorder 对象创建时选择器选择的录制容器的 MIME type

MediaRecorder.state

返回录制对象 MediaRecorder 的当前状态,可能的状态有:闲置中(inactive)、录制中(recording)、暂停(paused)。

MediaRecorder.stream

返回录制器对象 MediaRecorder 创建时构造函数传入的 MediaStream 对象。

MediaRecorder.ignoreMutedMedia

用以指定 MediaRecorder 是否录制无声的输入源,默认值是 false。

如果这个属性是 false,录制器对象 MediaRecorder 会录制无声的音频或者黑屏的视频。

MediaRecorder.videoBitsPerSecond

返回视频采用的编码比率,它可能和构造函数的设置比率不同,(if it was provided)。

MediaRecorder.audioBitsPerSecond

返回音频采用的编码比率,它可能和构造函数的设置比率不同,(if it was provided)。

实例方法

MediaRecorder.pause()

暂停媒体录制。

MediaRecorder.resume()

继续录制之前被暂停的录制动作。

MediaRecorder.start()

开始录制媒体。

MediaRecorder.stop()

停止录制。同时触发 dataavailable 事件,之后不再记录。

事件

这些事件都需要绑定在 MediaRecorder 实例上。

MediaRecorder.ondataavailable

该事件可用于获取录制的媒体资源(在事件的 data 属性中会提供一个可用的 Blob 对象)。

MediaRecorder.onpause

暂停时触发。

MediaRecorder.onresume

从暂停中恢复录制时触发。

MediaRecorder.onstart

开始录制时触发。

MediaRecorder.onstop

停止录制时触发。

MediaRecorder.onerror

发生错误时触发。

获取录制数据

通过监听 MediaRecorder 实例的 ondataavailable 事件获取数据,事件对象中的 data 属性即录制的数据(blob)。

mediaRecorder.ondataavailable = function (e) {
  blobData = e.data;
};

MediaStream 媒体流

MediaStream 接口是一个媒体内容的流。一个流包含几个轨道,比如视频和音频轨道。

MediaStreamopen in new window

录制过程概述

记录一个流的过程是非常容易的:

  1. 建立一个 MediaStream 或者 HTMLMediaElement (以 <audio><video> 元素的形式) 来充当媒体数据的源。
  2. 创建一个 MediaRecorder 对象,指定源(MediaStream)以及配置项 (录制器的 MIME 类型或它轨道所需的比特率)。
  3. 设置 MediaRecorder.dataavailable 事件处理函数(实例),会在数据可利用时候调用。
  4. 使用 MediaRecorder.start() 开始录制。
  5. 调用 MediaRecorder.stop 方法结束录制,自动触发 MediaRecorder.dataavailable 事件。
  6. MediaRecorder.dataavailable 的事件对象中有一个 data 属性,它的值为已录制媒体的 Blob 数据。

参考

MediaRecorderopen in new window

MediaDevicesopen in new window

MediaStream Recording APIopen in new window