MediaRecorder API 简介

在网络上,我们可以捕捉来自用户的摄像头,麦克风媒体流和甚至桌面。我们可以使用这些媒体流通过 WebRTC进行实时视频聊天,并且通过MediaRecorder API,我们还可以直接在 Web 浏览器中记录和保存用户的音频或视频。

为了探索 MediaRecorder API,让我们使用 HTML、CSS 和 JavaScript 构建一个简单的录音机应用程序。

入门

要构建这个应用程序,我们只需要一个文本编辑器和一个支持 MediaRecorded API的浏览器。在撰写本文时,支持的浏览器包括 Firefox、Chrome 和 Opera。还将此 API 引入 Edge 和 Safari 的工作正在进行中。

首先,创建一个文件夹并保存这个 HTML 文件和这个 CSS 文件,让我们开始工作。确保它们位于同一文件夹中,并且 CSS 文件名为web-recorder-style.css. 在浏览器中打开 HTML 文件,您应该看到以下内容:

MediaRecorder API 简介_第1张图片

现在让我们来看看 MediaRecorder API。

媒体记录器 API

要开始使用 MediaRecorder API,您需要一个 MediaStream。您可以从 aelement获取一个,也可以通过调用getUserMedia来捕获用户的相机和麦克风。一旦你有了一个流,你就可以MediaRecorder用它初始化它,然后你就可以开始录制了。

在记录期间,该MediaRecorder对象将发出dataavailable带有记录数据的事件作为事件的一部分。我们将侦听这些事件并整理数组中的数据块。录制完成后,我们会将块数组重新绑定到一个Blob对象中。我们可以通过在对象上调用start和来控制录音的开始和结束。stopMediaRecorder

让我们看看它的实际效果。

获取用户媒体

我们将首先连接一些 UI 并使用第一个按钮访问用户的麦克风流。在

接下来,我们将检查浏览器是否支持我们正在编写的代码。如果不是,我们将向页面显示错误。


对于该renderError方法,我们将用

错误消息替换元素的内容。在事件侦听器之后添加此方法。

    function renderError(message) {
      const main = document.querySelector('main');
      main.innerHTML = `

${message}

`; }

如果我们可以访问,MediaRecorder那么我们现在需要访问麦克风进行录音。为此,我们将使用getUserMediaAPI。我们不会立即请求访问麦克风,因为这对任何用户来说都是糟糕的体验。相反,我们将等待用户单击按钮访问麦克风,然后询问。

    if ('MediaRecorder' in window) {
      getMic.addEventListener('click', async () => {
        getMic.setAttribute('hidden', 'hidden');
        try {
          const stream = await navigator.mediaDevices.getUserMedia({
            audio: true,
            video: false
          });
          console.log(stream);
        } catch {
          renderError(
            'You denied access to the microphone so this demo will not work.'
          );
        }
      });
    } else {

navigator.mediaDevices.getUserMedia如果用户允许访问媒体,则调用返回一个成功解析的承诺。由于我们使用的是现代 JavaScript,因此我们可以使用async/await. 我们声明点击处理程序是一个async函数,然后当它调用getUserMedia我们await的结果时,然后继续。

用户可能会拒绝访问麦克风,我们将通过将调用包装在try/catch语句中来处理这种情况。Denial 将导致catch块执行,我们将renderError再次使用我们的函数。

保存您的文件并在浏览器中打开它。单击获取麦克风按钮。系统会询问您是否要授予对麦克风的访问权限,当您接受时,您将看到结果MediaStream记录到控制台。

MediaRecorder API 简介_第2张图片

记录

现在我们可以使用麦克风了,我们可以准备录音机了。我们将存储一些我们也需要的其他变量。首先是我们将使用的 MIME 类型,“audio/webm”。这似乎是浏览器将记录到今天的最广泛支持的格式。我们还将创建一个名为 的数组chunks,我们将使用该数组在创建录音时存储部分录音。

使用我们从用户麦克风捕获的媒体流和选项对象进行MediaRecorder初始化,我们将传递我们之前定义的 MIME 类型。将console.log之前的替换为:

        try {
          const stream = await navigator.mediaDevices.getUserMedia({
            audio: true,
            video: false
          });
          const mimeType = 'audio/webm';
          let chunks = [];
          const recorder = new MediaRecorder(stream, { type: mimeType });

现在我们已经创建了MediaRecorder我们需要为它设置一些事件监听器。记录器出于多种不同的原因发出事件。许多与记录器本身的交互有关,因此您可以在开始记录、暂停、恢复和停止时监听事件。最重要的事件是dataavailable记录器正在主动记录时定期发出的事件。这些事件包含一段录音,我们将把它推送到chunks我们刚刚创建的数组上。

对于我们的应用程序,我们将侦听dataavailable收集块的事件,然后当stop事件触发时,我们会将所有块收集到 a 中Blob,然后我们可以使用一个元素并重置chunks.

           const recorder = new MediaRecorder(stream, { type: mimeType });
           recorder.addEventListener('dataavailable', event => {
             if (typeof event.data === 'undefined') return;
               if (event.data.size === 0) return;
               chunks.push(event.data);
             });
           recorder.addEventListener('stop', () => {
             const recording = new Blob(chunks, {
               type: mimeType
             });
             renderRecording(recording, list);
             chunks = [];
           });

我们很快就会实现这个renderRecording方法。我们只需要做更多的工作来启用按钮来开始和停止录制。

我们需要取消隐藏录制按钮,然后在单击时开始录制或停止录制,具体取决于录制器本身的状态。该代码如下所示:

           chunks = [];
         });
         recordButton.removeAttribute('hidden');
         recordButton.addEventListener('click', () => {
           if (recorder.state === 'inactive') {
             recorder.start();
             recordButton.innerText = 'Stop';
           } else {
             recorder.stop();
             recordButton.innerText = 'Record';
           }
         });

为了完成这个小应用程序,我们将把录音渲染成元素并提供一个下载链接,以便用户可以将他们的录音保存到桌面。这里的关键是我们可以使用Blob我们创建的URL.createObjectURL方法将其转换为 URL 。然后,该URL可以用作为src一个的元素和作为href锚定的。为了让锚下载文件,我们设置了download属性。

此功能主要是创建 DOM 元素并在录制时间之外制作文件名。将其添加到您的renderError函数下方。

  function renderRecording(blob, list) {
    const blobUrl = URL.createObjectURL(blob);
    const li = document.createElement('li');
    const audio = document.createElement('audio');
    const anchor = document.createElement('a');
    anchor.setAttribute('href', blobUrl);
    const now = new Date();
    anchor.setAttribute(
      'download',
      `recording-${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDay().toString().padStart(2, '0')}--${now.getHours().toString().padStart(2, '0')}-${now.getMinutes().toString().padStart(2, '0')}-${now.getSeconds().toString().padStart(2, '0')}.webm`
    );
    anchor.innerText = 'Download';
    audio.setAttribute('src', blobUrl);
    audio.setAttribute('controls', 'controls');
    li.appendChild(audio);
    li.appendChild(anchor);
    list.appendChild(li);
  }

MediaRecorder API 简介_第3张图片

测试一下

在 Web 浏览器中打开该页面,然后单击“获取麦克风”按钮。接受权限对话框,然后单击开始录制。为自己录制一条消息并从页面播放。

WebM 文件

如果您下载其中一个录音,您可能会发现您没有能够播放 WebM 文件的媒体播放器。WebM 是一种音频和视频的开源格式,但它主要得到浏览器的支持。如果您有VLC 播放器,您可能可以播放音频,否则您可能想使用诸如convertio 之类的在线工具将其转换为 MP3 或 WAV 文件(或者如果您有胆量,可以在终端中使用ffmpeg)。

你的浏览器现在是一个记录器

MediaRecorderAPI是一个功能强大的新增加的浏览器。在这篇文章中,我们已经看到了它录制音频的能力,但它并不止于此。当前应用程序不保存音频文件,因此页面刷新会丢失它们。您可以使用 IndexedDB 保存它们或将它们发送到服务器。您还可以播放录音,想象一下在录制之前通过 Web Audio API 传递音频。如果 WebM 格式不是你的菜,你总是可以考虑在前端重新编码音频,尽管这可能是 WebAssembly(或你的服务器......)的工作。

如果您想尝试这篇文章中的代码,您可以查看现场演示。此GitHub 存储库中提供了所有代码,您也可以在Glitch上重新混合该项目。

你可能感兴趣的:(html,css,html5)