Audio- und Bildschirmaufnahme

In diesem Leitfaden werden verschiedene Ansätze zum Aufzeichnen von Audio und Video von einem Tab, Fenster oder Bildschirm mithilfe von APIs wie browser.tabCapture oder getDisplayMedia() beschrieben.

Bildschirmaufzeichnung

Rufen Sie für die Bildschirmaufzeichnung getDisplayMedia() auf. Dadurch wird das unten gezeigte Dialogfeld ausgelöst. So kann der Nutzer auswählen, welchen Tab, welches Fenster oder welchen Bildschirm er teilen möchte. Außerdem wird deutlich angezeigt, dass eine Aufzeichnung stattfindet.

Dialogfeld für die Bildschirmfreigabe für example.com
Dialogfeld „Bildschirmfreigabe“ für beispiel.de

Im folgenden Beispiel wird der Zugriff zum Aufzeichnen von Audio und Video angefordert.

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

Wenn die Funktion in einem Inhaltsscript aufgerufen wird, wird die Aufzeichnung automatisch beendet, wenn der Nutzer zu einer neuen Seite wechselt. Wenn Sie im Hintergrund und über verschiedene Navigationsvorgänge hinweg aufzeichnen möchten, verwenden Sie ein Dokument außerhalb des Bildschirms mit dem Grund DISPLAY_MEDIA.

Tab-Aufnahme basierend auf Nutzergeste

Wenn getDisplayMedia() aufgerufen wird, zeigt der Browser ein Dialogfeld an, in dem der Nutzer gefragt wird, was er teilen möchte. In einigen Fällen hat der Nutzer jedoch nur auf den Aktionsbutton geklickt, um Ihre Erweiterung für einen bestimmten Tab aufzurufen, und Sie möchten sofort mit der Aufzeichnung des Tabs beginnen, ohne dass diese Aufforderung angezeigt wird.

Audio und Video im Hintergrund aufzeichnen

Ab Chrome 116 können Sie die browser.tabCapture API in einem Service Worker aufrufen, um nach einer Nutzergeste eine Stream-ID abzurufen. Dieses kann dann an ein Offscreen-Dokument übergeben werden, um die Aufzeichnung zu starten.

In Ihrem Service Worker:

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

Gehen Sie dann in Ihrem Dokument vor:

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

Ein vollständiges Beispiel finden Sie im Tab Capture-Recorder-Beispiel.

Audio und Video in einem neuen Tab aufzeichnen

Vor Chrome 116 war es nicht möglich, die browser.tabCapture API in einem Service Worker zu verwenden oder eine von dieser API erstellte Stream-ID in einem Offscreen-Dokument zu nutzen. Beide sind Voraussetzungen für den oben beschriebenen Ansatz.

Stattdessen können Sie eine Erweiterungsseite in einem neuen Tab oder Fenster öffnen und direkt einen Stream abrufen. Legen Sie die Eigenschaft targetTabId fest, um den richtigen Tab zu erfassen.

Öffnen Sie zuerst eine Erweiterungsseite, z. B. in Ihrem Pop-up oder Service Worker:

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

Gehen Sie dann auf der Seite Ihrer Erweiterung so vor:

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

Alternativ können Sie auch die Bildschirmaufzeichnung verwenden. Damit können Sie im Hintergrund mit einem Offscreen-Dokument aufzeichnen, aber dem Nutzer wird ein Dialogfeld angezeigt, in dem er einen Tab, ein Fenster oder einen Bildschirm für die Aufzeichnung auswählen kann.

Audio in einem Pop-up-Fenster aufnehmen

Wenn Sie nur Audio aufnehmen müssen, können Sie im Erweiterungs-Pop-up mit browser.tabCapture.capture direkt einen Stream abrufen. Wenn das Pop-up-Fenster geschlossen wird, wird die Aufnahme beendet.

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

Wenn die Aufzeichnung über mehrere Navigationsvorgänge hinweg beibehalten werden soll, sollten Sie den im vorherigen Abschnitt beschriebenen Ansatz verwenden.

Weitere Hinweise

Weitere Informationen zum Aufzeichnen eines Streams finden Sie in der MediaRecorder API.