오디오 녹음 및 화면 캡처

이 가이드에서는 browser.tabCapture 또는 getDisplayMedia()과 같은 API를 사용하여 탭, 창 또는 화면에서 오디오와 동영상을 녹화하는 다양한 방법을 설명합니다.

화면 녹화

화면 녹화의 경우 아래에 표시된 대화상자를 트리거하는 getDisplayMedia()를 호출합니다. 이를 통해 사용자는 공유할 탭, 창 또는 화면을 선택할 수 있으며 녹화가 진행 중임을 명확하게 알 수 있습니다.

example.com의 화면 공유 대화상자
example.com의 화면 공유 대화상자

다음 예에서는 오디오와 동영상을 모두 녹화할 수 있는 액세스 권한을 요청합니다.

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

콘텐츠 스크립트 내에서 호출되면 사용자가 새 페이지로 이동할 때 녹화가 자동으로 종료됩니다. 백그라운드에서 탐색 전반에 걸쳐 녹화하려면 DISPLAY_MEDIA 이유와 함께 오프스크린 문서를 사용하세요.

사용자 동작에 기반한 탭 캡처

getDisplayMedia()를 호출하면 브라우저에 사용자가 공유하고 싶은 항목을 묻는 대화상자가 표시됩니다. 하지만 사용자가 특정 탭의 확장 프로그램을 호출하기 위해 작업 버튼을 클릭한 경우 이 프롬프트 없이 탭 캡처를 즉시 시작하고 싶을 수 있습니다.

백그라운드에서 오디오 및 동영상 녹화

Chrome 116부터 서비스 워커에서 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 이전에는 서비스 워커에서 browser.tabCapture API를 사용하거나 오프스크린 문서에서 해당 API로 생성된 스트림 ID를 사용할 수 없었습니다. 이 두 가지 모두 위의 접근 방식에 대한 요구사항입니다.

대신 새 탭이나 창에서 확장 프로그램 페이지를 열고 스트림을 직접 가져올 수 있습니다. targetTabId 속성을 설정하여 올바른 탭을 캡처합니다.

먼저 확장 프로그램 페이지를 엽니다 (팝업 또는 서비스 워커에서).

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를 참고하세요.