音訊錄音和螢幕畫面擷取

本指南說明使用 chrome.tabCapturegetDisplayMedia() 等 API,從分頁、視窗或畫面中錄製音訊和影片的各種方法。

錄製螢幕畫面

如要錄製螢幕畫面,請呼叫 getDisplayMedia(),觸發下方顯示的對話方塊。這可讓使用者選取要分享的分頁、視窗或畫面,並明確指出系統正在進行錄製。

example.com 的分享螢幕畫面對話方塊
example.com 的螢幕畫面分享對話方塊。

以下範例要求存取音訊及視訊的錄音權限。

const stream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: true });

如果在內容指令碼中呼叫,系統將在使用者前往新頁面時自動結束記錄。如要在背景和跨導覽錄製,請使用含有 DISPLAY_MEDIA 原因的畫面外文件

根據使用者手勢擷取分頁

呼叫 getDisplayMedia() 後,瀏覽器會顯示對話方塊,詢問使用者想分享什麼內容。不過,在某些情況下,使用者剛點選動作按鈕可叫用特定分頁的擴充功能,而您想要立即擷取分頁,而不想看到這則提示。

在背景錄製音訊和視訊

從 Chrome 116 開始,您可以在服務工作站中呼叫 chrome.tabCapture API,以便在使用者手勢後取得串流 ID。接著,系統可將其傳遞至畫面外的文件開始錄製。

在 Service Worker 中:

chrome.action.onClicked.addListener(async (tab) => {
  const existingContexts = await chrome.runtime.getContexts({});

  const offscreenDocument = existingContexts.find(
    (c) => c.contextType === 'OFFSCREEN_DOCUMENT'
  );

  // If an offscreen document is not already open, create one.
  if (!offscreenDocument) {
    // Create an offscreen document.
    await chrome.offscreen.createDocument({
      url: 'offscreen.html',
      reasons: ['USER_MEDIA'],
      justification: 'Recording from chrome.tabCapture API',
    });
  }

  // Get a MediaStream for the active tab.
  const streamId = await chrome.tabCapture.getMediaStreamId({
    targetTabId: tab.id
  });

  // Send the stream ID to the offscreen document to start recording.
  chrome.runtime.sendMessage({
    type: 'start-recording',
    target: 'offscreen',
    data: streamId
  });
});

然後在螢幕外文件中:

chrome.runtime.onMessage.addListener(async (message) => {
  if (message.target !== 'offscreen') return;
  
  if (message.type === 'start-recording') {
    const media = await navigator.mediaDevices.getUserMedia({
      audio: {
        mandatory: {
          chromeMediaSource: "tab",
          chromeMediaSourceId: message.data,
        },
      },
      video: {
        mandatory: {
          chromeMediaSource: "tab",
          chromeMediaSourceId: message.data,
        },
      },
    });

    // Continue to play the captured audio to the user.
    const output = new AudioContext();
    const source = output.createMediaStreamSource(media);
    source.connect(output.destination);

    // TODO: Do something to recording the MediaStream.
  }
});

如需完整範例,請參閱「Tab Capture - Recorder」範例。

在新分頁中錄製音訊和影片

在 Chrome 116 以下版本中,您無法在服務工作站中使用 chrome.tabCapture API,也無法在螢幕外文件中使用由該 API 建立的串流 ID。這兩項設定都是適用於上述方法的需求條件。

請改為在新分頁或視窗中開啟擴充功能頁面,直接取得串流內容。設定 targetTabId 屬性來擷取正確的分頁。

先開啟擴充功能頁面 (可能出現在彈出式視窗或 Service Worker 中):

chrome.windows.create({ url: chrome.runtime.getURL("recorder.html") });

接著,在擴充功能頁面中:

chrome.tabCapture.getMediaStreamId({ targetTabId: tabId }, async (id) => {
  const media = await navigator.mediaDevices.getUserMedia({
    audio: {
      mandatory: {
        chromeMediaSource: "tab",
        chromeMediaSourceId: id,
      },
    },
    video: {
      mandatory: {
        chromeMediaSource: "tab",
        chromeMediaSourceId: id,
      },
    },
  });

  // Continue to play the captured audio to the user.
  const output = new AudioContext();
  const source = output.createMediaStreamSource(media);
  source.connect(output.destination);
});

或者,您也可以使用「螢幕錄製」方法,透過畫面外文件在背景進行錄製,但向使用者顯示對話方塊,讓使用者選取要錄製的分頁、視窗或畫面。

在彈出式視窗中錄製音訊

如果只需要錄製音訊,您可以使用 chrome.tabCapture.capture 在擴充功能彈出式視窗中直接取得串流。彈出式視窗關閉後,系統就會停止錄製。

chrome.tabCapture.capture({ audio: true }, (stream) => {
  // Continue to play the captured audio to the user.
  const output = new AudioContext();
  const source = output.createMediaStreamSource(stream);
  source.connect(output.destination);

  // TODO: Do something with the stream (e.g record it)
});

如果您需要在各個導覽中持續使用該記錄,請考慮使用上一節所述的方法。

其他考量

如要進一步瞭解如何錄製串流,請參閱 MediaRecorder API。