Nagrywanie dźwięku i przechwytywanie ekranu

Z tego przewodnika dowiesz się, jak nagrywać dźwięk i obraz z karty, okna lub ekranu za pomocą interfejsów API, takich jak browser.tabCapture lub getDisplayMedia().

Nagrywanie ekranu

Aby nagrać ekran, kliknij getDisplayMedia(). Spowoduje to wyświetlenie okna dialogowego pokazanego poniżej. Dzięki temu użytkownik może wybrać kartę, okno lub ekran, które chce udostępnić, i ma jasną informację o tym, że nagrywanie jest w toku.

Okno udostępniania ekranu dla example.com
Okno udostępniania ekranu w przypadku example.com.

Poniższy przykład żąda dostępu do nagrywania dźwięku i obrazu.

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

Jeśli wywołasz tę funkcję w skrypcie treści, nagrywanie zakończy się automatycznie, gdy użytkownik przejdzie na nową stronę. Aby nagrywać w tle i podczas nawigacji, użyj dokumentu poza ekranem z atrybutem DISPLAY_MEDIA reason.

Przechwytywanie karty na podstawie gestu użytkownika

Wywołanie funkcji getDisplayMedia() powoduje wyświetlenie w przeglądarce okna z pytaniem do użytkownika, co chce udostępnić. W niektórych przypadkach użytkownik kliknął przycisk polecenia, aby wywołać rozszerzenie dla konkretnej karty, i chcesz od razu rozpocząć przechwytywanie karty bez tego monitu.

Nagrywanie dźwięku i obrazu w tle

Od wersji 116 Chrome możesz wywoływać interfejs browser.tabCapture API w skrypcie service worker, aby uzyskać identyfikator strumienia po wykonaniu gestu użytkownika. Można go następnie przekazać do dokumentu poza ekranem, aby rozpocząć nagrywanie.

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

Następnie w dokumencie poza ekranem:

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

Pełny przykład znajdziesz w próbce Tab Capture – Recorder.

Nagrywanie dźwięku i wideo w nowej karcie

Przed Chrome 116 nie można było używać interfejsu browser.tabCapture w skrypcie service worker ani korzystać z identyfikatora strumienia utworzonego przez ten interfejs API w dokumencie poza ekranem. Oba te elementy są wymagane w przypadku powyższego podejścia.

Zamiast tego możesz otworzyć stronę rozszerzenia w nowej karcie lub nowym oknie i bezpośrednio uzyskać strumień. Ustaw właściwość targetTabId, aby przechwycić prawidłową kartę.

Zacznij od otwarcia strony rozszerzenia (np. w wyskakującym okienku lub w skrypcie service worker):

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

Następnie na stronie rozszerzenia:

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

Możesz też użyć nagrywania ekranu, które umożliwia nagrywanie w tle za pomocą dokumentu poza ekranem, ale wyświetla użytkownikowi okno dialogowe, w którym może on wybrać kartę, okno lub ekran do nagrywania.

Nagrywanie dźwięku w wyskakującym okienku

Jeśli chcesz nagrać tylko dźwięk, możesz bezpośrednio uzyskać strumień w wyskakującym okienku rozszerzenia za pomocą funkcji browser.tabCapture.capture. Po zamknięciu wyskakującego okienka nagrywanie zostanie zatrzymane.

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

Jeśli chcesz, aby nagranie było dostępne podczas nawigacji, skorzystaj z metody opisanej w poprzedniej sekcji.

Inne uwagi

Więcej informacji o nagrywaniu strumienia znajdziesz w dokumentacji interfejsu MediaRecorder.