MediaRecorder API 簡介[譯]

在網絡上,咱們能夠從用戶的相機、麥克風甚至桌面捕獲媒體流。咱們可使用這些媒體流經過 WebRTC 進行實時視頻聊天,經過 MediaRecorder API 咱們還能夠直接在瀏覽器中記錄和保存用戶的音頻或視頻。css

下面咱們使用 HTML、CSS 和 JavaScript 構建一個簡單的錄音機應用來了解一下 MediaRecorder API 。在撰寫本文時,支持的瀏覽器包括 Firefox,Chrome 和Opera。Edge 和 Safari 後續也會支持。 咱們先來建立一個文件夾,再建立一個 HTML 文件及 CSS 文件供咱們使用。 開始 要構建此應用,咱們只須要一個文本編輯器和一個支持 MediaRecorded API 的瀏覽器。咱們將 CSS 文件命名爲 web-recorder-style.csshtml

HTML 代碼:前端

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Web Recorder</title>
    <link rel="stylesheet" href="./web-recorder-style.css" />
  </head>
  <body>
    <header>
      <h1>Web Recorder</h1>
    </header>
    <main>
      <div class="controls">
        <button type="button" id="mic">Get Microphone</button>
        <button type="button" id="record" hidden>Record</button>
      </div>
      <ul id="recordings"></ul>
    </main>
    <script></script>
  </body>
</html>
複製代碼

CSS 代碼:git

*{box-sizing: border-box;}
html,
body{min-height: 100vh; margin: 0; padding: 0;}
body{font-family: Helvetica, Arial, sans-serif; color: #0d122b; display: flex; flex-direction: column; padding-left: 1em; padding-right: 1em;}
h1{text-align: center; font-weight: 100;}
header{border-bottom: 1px solid #0d122b; margin-bottom: 2em;}
main{flex-grow: 2;}
.controls{text-align: center;}
button{font-size: 18px; font-weight: 200; padding: 1em; width: 200px; background: transparent; border: 4px solid #f22f46; border-radius: 4px; transition: all 0.4s ease 0s; cursor: pointer; color: #f22f46; margin-bottom: 2em;}
button:hover,
button:focus{background: #f22f46; color: #fff;}
#recordings{list-style-type: none; text-align: center; padding: 0; max-width: 600px; margin: 0 auto;}
#recordings li{display: flex; flex-direction: column; margin-bottom: 1em;}
#recordings audio{border-radius: 4px; margin: 0 auto 0.5em;}
a{color: #0d122b;}
.error{color: #f22f46; text-align: center;}
複製代碼

在瀏覽器打開頁面你會看到以下內容:github

圖片

如今讓咱們來看看 MediaRecorder API。web

MediaRecorder API

在使用 MediaRecorder API 時須要有媒體流。咱們能夠從 <video><audio> 中獲取,也能夠經過調用 getUserMedia 來捕獲用戶的攝像頭和麥克風。一旦得到流信息,即可以初始化 MediaRecorderapi

在錄音過程當中,MediaRecorder 會廣播 dataavailable 事件,並將記錄的數據做爲事件的一部分。咱們能夠監聽這些事件並將數據塊存放在數組中。錄音完成後,能夠將數組裏的數據合成 Blob 對象。經過調用 MediaRecorder 對象上的 startstop 來控制錄製的開始和結束。數組

下面,就讓咱們來實踐一下。promise

getUserMedia

首先,咱們與頁面結合起來,經過按鈕來獲取用戶的麥克風媒體流。在頁面 <script> 標籤裏寫上如下內容瀏覽器

window.addEventListener('DOMContentLoaded', () => {
  const getMic = document.getElementById('mic');
  const recordButton = document.getElementById('record');
  const list = document.getElementById('recordings');

});
複製代碼

接下來,咱們要檢查瀏覽器是否支持。若是不支持,咱們在頁面顯示提示信息。

window.addEventListener('DOMContentLoaded', () => {
    const getMic = document.getElementById('mic');
    const recordButton = document.getElementById('record');
    const list = document.getElementById('recordings');

    if ('MediaRecorder' in window) {
      // everything is good, let's go ahead
    } else {
      renderError("Sorry, your browser doesn't support the MediaRecorder API, so this demo will not work.");
    }
  });
複製代碼

在事件以後,咱們添加 renderErro 方法。

function renderError(message) {
  const main = document.querySelector('main');
  main.innerHTML = `<div class="error"><p>${message}</p></div>`;
}
複製代碼

若是能夠訪問 MediaRecorder ,那麼咱們須要麥克風權限來進行錄製。這裏會用到 getUserMedia API。咱們不會直接請求麥克風,而是由用戶點擊按鈕來使用麥克風並進行受權。

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 將返回一個 promise ,若是用戶容許訪問,咱們即可以成功獲取媒體流。

用戶可能會禁止訪問麥克風,咱們使用 try/catch 處理異常。若是用戶禁止則會執行 catch 裏的 renderError 方法。

保存文件並在瀏覽器裏打開。點擊「Get Microphone」按鈕。會顯示是否容許使用麥克風的提示,容許後在控件臺會看到打印出的 MediaStream 信息。

圖片

錄音

如今咱們得到了麥克風的使用權限,下來咱們要定義一些變量供後面使用。首先,MIME 類型使用 auto/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 數組中。

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';
   }
 });
複製代碼

咱們將把錄音在 <audio> 元素上呈現並提供下載連接,以便用戶能夠將他們的錄音下載下來。咱們可使用 URL.createObjectUrl 方法將 Blob 轉成 URL。轉成的 URL 能夠作爲 <audio>src 及錨點元素的 href 使用。爲保證文件可以下載,咱們設置 download 屬性。

renderRecording 方法主要建立 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);
  }
複製代碼

圖片

測試

在瀏覽器中打開頁面並點擊「Get Microphone」按鈕。在權限對話框點擊「容許」,而後點擊「Record」。本身錄一段信息並播放。

WebM 文件

若是您下載了其中一個錄音,您可能會發現沒有可以播放 WebM 文件的媒體播放器。WebM 是音頻和視頻的開源格式,它主要被瀏覽器所支持。若是你有 VLC 播放器即可以播放,否則的話你就須要將它轉成 MP3 或 WAV 文件。

如今你的瀏覽器變成錄音機了

MediaRecorder API 是瀏覽器新增的強大功能。在本文咱們已經看到了它的錄音能力,但它不只於此。咱們的應用沒有保存功能,刷新頁面後錄音會丟失。咱們可使用 IndexedDb 或發送到服務器保存。若是 WebM 不是你想要的格式,能夠考慮在前端進行從新編碼,儘管這多是 WebAssembly 的工做...

這裏有一個 live demoGithub 源碼在這裏

做者:Phil Nash

譯者:Mark Wong

原文:www.twilio.com/blog/medias…

相關文章
相關標籤/搜索