오디오 녹음 및 화면 캡처

이 가이드에서는 chrome.tabCapture 또는 getDisplayMedia()와 같은 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를 가져올 수 있습니다. 그런 다음 이 데이터를 오프스크린 문서에 전달하여 녹화를 시작할 수 있습니다.

서비스 워커에서:

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

전체 예는 탭 캡처 - 녹음기 샘플을 참고하세요.

새 탭에서 오디오 및 동영상 녹화

Chrome 116 이전에는 서비스 워커에서 chrome.tabCapture API를 사용하거나 이 API로 생성된 스트림 ID를 오프스크린 문서에서 사용할 수 없었습니다. 두 가지 모두 위 접근 방식의 요구사항입니다.

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

확장 프로그램 페이지를 열어 시작합니다 (예: 팝업 또는 서비스 워커).

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