音声の録音とスクリーン キャプチャ

このガイドでは、browser.tabCapture や getDisplayMedia() などの API を使用して、タブ、ウィンドウ、画面から音声と動画を録画するさまざまな方法について説明します。

画面の録画

画面録画の場合は、getDisplayMedia() を呼び出します。これにより、以下のダイアログ ボックスがトリガーされます。これにより、ユーザーは共有するタブ、ウィンドウ、画面を選択できるようになり、録画が行われていることを明確に示します。

example.com の画面共有ダイアログ example.com の画面共有ダイアログ。

次の例では、音声と動画の両方を録画するためのアクセス権をリクエストしています。

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

コンテンツ スクリプト内で呼び出された場合、ユーザーが新しいページに移動すると、録画は自動的に終了します。バックグラウンドでナビゲーションをまたいで記録するには、DISPLAY_MEDIA の理由でオフスクリーン ドキュメントを使用します。

ユーザー ジェスチャーに基づくタブのキャプチャ

getDisplayMedia() を呼び出すと、ブラウザに共有する内容をユーザーに尋ねるダイアログが表示されます。ただし、ユーザーが特定のタブで拡張機能を呼び出すために操作ボタンをクリックした直後には、このプロンプトを表示せずにタブのキャプチャをすぐに開始したい場合があります。

バックグラウンドで音声と動画を録画する

Chrome 116 以降では、Service Worker で browser.tabCapture API を呼び出して、ユーザー ジェスチャーに続くストリーム ID を取得できます。これは、オフスクリーン ドキュメントに渡して録画を開始できます。

サービス ワーカーで:

browser.action.onClicked.addListener(async (tab) => {
  const existingContexts = await browser.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 browser.offscreen.createDocument({
      url: 'offscreen.html',
      reasons: ['USER_MEDIA'],
      justification: 'Recording from browser.tabCapture API',
    });
  }

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

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

次に、オフスクリーン ドキュメントで次の操作を行います。

browser.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 record the MediaStream.
  }
});

完全な例については、タブ キャプチャ - レコーダーのサンプルをご覧ください。

新しいタブで音声と動画を録画する

Chrome 116 より前は、Service Worker で browser.tabCapture API を使用したり、オフスクリーン ドキュメントでその API によって作成されたストリーム ID を使用したりすることはできませんでした。これらは両方とも、上記のアプローチの要件です。

代わりに、新しいタブまたはウィンドウで拡張機能ページを開き、ストリームを直接取得できます。正しいタブをキャプチャするように targetTabId プロパティを設定します。

まず、拡張機能ページを開きます(ポップアップまたは Service Worker など)。

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

次に、拡張機能のページで次の操作を行います。

browser.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);
});

または、画面録画アプローチの使用を検討してください。このアプローチでは、オフスクリーン ドキュメントを使用してバックグラウンドで録画できますが、ユーザーには録画するタブ、ウィンドウ、画面を選択するダイアログが表示されます。

ポップアップで音声を録音する

音声のみを録音する必要がある場合は、browser.tabCapture.capture を使用して、拡張機能のポップアップでストリームを直接取得できます。ポップアップが閉じると、録画が停止します。

browser.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 をご覧ください。