지역 캡처로 탭 공유 개선

François Beaufort
François Beaufort

웹 플랫폼에서는 이미 웹 앱이 현재 탭의 동영상 트랙을 캡처할 수 있습니다. 이제 이러한 동영상 트랙을 자르는 메커니즘인 영역 캡처가 함께 제공됩니다. 웹 앱은 현재 탭의 일부를 관심 영역으로 지정하고 브라우저는 해당 영역 외부의 모든 픽셀을 자릅니다.

이전에는 웹 앱이 동영상 트랙을 '수동'으로 자를 수 있었습니다. 즉, 웹 앱이 모든 단일 프레임을 직접 조작할 수 있었습니다. 이는 견고하지도 성능이 좋지도 않았습니다. 리전 캡처는 이러한 단점을 해결합니다. 이제 웹 앱이 브라우저에 작업을 대신 수행하도록 지시할 수 있습니다.

영역 캡처 정보

동적 콘텐츠™로 웹사이트를 만들었습니다. 최고의 웹 앱이며 사람들이 자주 공동작업을 하면서 사용합니다. 다음 단계로 가상 회의 기능을 삽입할 수 있습니다. 이 방법을 사용하기로 합니다. 기존 화상 회의 서비스 제공업체와 협력하여 웹 앱을 교차 출처 iframe으로 삽입합니다. 화상 회의 웹 앱은 현재 탭을 동영상 트랙으로 캡처하여 원격 참가자에게 전송합니다.

기본 콘텐츠 영역과 교차 출처 iframe을 강조 표시하는 웹 앱이 표시된 브라우저 창의 스크린샷
기본 콘텐츠 영역은 파란색이고 교차 출처 iframe은 빨간색입니다.

잠깐만요… 사용자의 동영상을 다시 사용자에게 전송하고 싶지는 않으시죠? 그 부분을 잘라내는 것이 좋습니다. 하지만 어떻게 할 수 있을까요? 삽입된 iframe은 사용자가 어떤 콘텐츠를 어디에 노출하는지 알지 못하므로 도움이 없으면 자를 수 없습니다. 이론적으로는 의도한 좌표를 전달할 수 있습니다. 하지만 사용자가 창 크기를 조절하면 어떻게 될까요? 표시 영역을 스크롤합니다. 확대 또는 축소 레이아웃 변경을 유발하는 방식으로 페이지와 상호작용하는가? 캡처링 iframe에 새 좌표를 전송하더라도 타이밍 문제로 인해 일부 프레임이 잘못 잘릴 수 있습니다.

영역 캡처를 사용해 보겠습니다. 페이지에 기본 콘텐츠를 포함하는 Element(예: <div>)이 있습니다. 이름을 mainContentArea라고 하겠습니다. 화상 회의 웹 앱이 이 요소의 경계 상자로 정의된 영역을 원격으로 캡처하고 공유하기를 원합니다. 따라서 mainContentArea에서 CropTarget를 파생시킵니다. 이 CropTarget를 화상 회의 웹 앱에 전달합니다. 이 CropTarget를 사용하여 동영상 트랙을 자르면 이제 해당 트랙의 프레임은 mainContentArea의 경계 상자 내에 있는 픽셀로만 구성됩니다. mainContentArea의 크기, 모양 또는 위치가 변경되면 웹 앱의 추가 입력 없이 동영상 트랙이 따라갑니다.

단계를 다시 살펴보겠습니다.

선택한 요소를 입력으로 사용하여 CropTarget.fromElement()를 호출하여 웹 앱에서 CropTarget를 정의합니다.

// In the main web app, associate mainContentArea with a new CropTarget
const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

CropTarget를 화상 회의 웹 앱에 전달합니다.

// Send the CropTarget to the video conferencing web app.
const iframe = document.querySelector("#videoConferenceIframe");
iframe.contentWindow.postMessage(cropTarget);

화상 회의 웹 앱은 기본 웹 앱에서 수신한 자르기 타겟을 사용하여 자체 캡처 동영상 트랙에서 cropTo()을 호출하여 브라우저에 CropTarget로 정의된 영역으로 트랙을 자르도록 요청합니다.

// In the embedded video conferencing web app, ask the user for permission
// to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
  preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

// Start cropping the self-capture video track using the CropTarget
// received over window.onmessage.
await track.cropTo(cropTarget);

// Enjoy! Transmit remotely the cropped video track with RTCPeerConnection.

Et voilà! 완료되었습니다.

심층 분석

기능 감지

CropTarget.fromElement()가 지원되는지 확인하려면 다음을 사용하세요.

if ("CropTarget" in self && "fromElement" in CropTarget) {
  // Deriving a target is supported.
}

CropTarget 파생

mainContentArea라는 요소에 집중해 보겠습니다. 여기에서 CropTarget를 파생시키려면 CropTarget.fromElement(mainContentArea)를 호출합니다. 반환된 Promise는 성공하면 새 CropTarget 객체로 확인됩니다. 그렇지 않으면 불합리한 수의 CropTarget 객체를 발행한 경우 거부됩니다.

const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);

Element와 달리 CropTarget 객체는 직렬화 가능합니다. 예를 들어 Window.postMessage()를 사용하여 다른 문서에 전달할 수 있습니다.

자르기

탭 캡처 시 동영상 트랙은 MediaStreamTrack의 하위 클래스인 BrowserCaptureMediaStreamTrack로 인스턴스화됩니다. 이 서브클래스는 cropTo()를 노출합니다. track.cropTo(cropTarget)를 호출하여 mainContentArea (cropTarget이 파생된 요소)의 윤곽에 맞게 자르기를 시작합니다.

성공하면 후속 동영상 프레임이 모두 mainContentArea의 경계 상자 내에 있는 픽셀로 구성된다고 보장할 수 있을 때 Promise가 해결됩니다.

실패하면 프로미스가 거부됩니다. 다음과 같은 경우에 발생합니다.

  • CropTarget이 다른 탭에서 발행되었습니다. (현재는 이 기능이 제공되지 않습니다. 기대해 주세요.)
  • CropTarget가 더 이상 존재하지 않는 요소에서 파생되었습니다.
  • 트랙에 클론이 있습니다. (문제 1509418 참고)
  • 현재 트랙이 자체 캡처 동영상 트랙이 아닙니다. 아래를 참고하세요.

cropTo() 메서드는 자체 캡처뿐만 아니라 모든 탭 캡처 동영상 트랙에 노출됩니다. 따라서 트랙을 자르기 전에 사용자가 현재 탭을 선택했는지 확인하는 것이 좋습니다. 이 작업은 핸들 캡처를 사용하여 실행할 수 있습니다. preferCurrentTab를 사용하여 브라우저에 사용자에게 셀프 캡처를 유도하도록 요청할 수도 있습니다.

// Start cropping the self-capture video track using the CropTarget.
await track.cropTo(cropTarget);

잘리지 않은 상태로 되돌리려면 null과 함께 cropTo()을 호출합니다.

// Stop cropping.
await track.cropTo(null);

가려진 콘텐츠 및 가려지는 콘텐츠

영역 캡처의 경우 타겟의 위치와 크기만 중요하며 z-index는 중요하지 않습니다. 타겟을 가리는 픽셀이 캡처됩니다. 타겟의 가려진 부분은 캡처되지 않습니다.

이는 영역 캡처가 기본적으로 자르기이기 때문에 발생하는 결과입니다. 향후 자체 API가 될 수 있는 한 가지 대안은 요소 수준 캡처입니다. 즉, 폐색과 관계없이 타겟과 연결된 픽셀만 캡처합니다. 이러한 API에는 단순한 자르기와는 다른 보안 및 개인 정보 보호 요구사항이 있습니다.

영역 캡처 및 요소 수준 캡처 API의 다양한 결과를 보여주는 그림
가려진 콘텐츠가 있는 영역 캡처의 동작

보안 및 개인 정보 보호

영역 캡처를 사용하면 탭의 모든 픽셀을 이미 관찰하고 있는 웹 앱이 이러한 픽셀 중 일부를 자발적으로 삭제할 수 있습니다. 새로운 정보를 얻을 수 없으므로 명백히 안전합니다.

영역 캡처를 사용하면 원격 참여자에게 전송되는 정보를 제한할 수 있습니다. 예를 들어 슬라이드는 공유하고 싶지만 발표자 노트는 공유하고 싶지 않을 수 있습니다.

슬라이드와 발표자 메모가 포함된 브라우저 창의 스크린샷
슬라이드와 발표자 노트가 포함된 웹 앱입니다.
원격으로 노트를 공유하는 것은 매우 바람직하지 않습니다. 큐 지역 캡처

로컬에서는 영역 캡처가 보안 보장을 추가하지 않습니다. 트랙을 다른 문서에 넘겨줄 때 수신 문서는 트랙의 자르기를 취소하고 캡처된 탭의 모든 픽셀에 액세스할 수 있습니다.

Chrome은 캡처된 탭의 가장자리에 파란색 테두리를 그립니다. 자르기 시 Chrome은 일반적으로 잘린 타겟 주위에 파란색 테두리를 그립니다.

데모

데모를 실행하여 영역 캡처를 사용해 볼 수 있습니다.

브라우저 지원

Browser Support

  • Chrome: 104.
  • Edge: 104.
  • Firefox: not supported.
  • Safari: not supported.

Source

영역 캡처는 데스크톱의 Chrome 104에서만 사용할 수 있습니다.

다음 단계

웹에서 화면 공유를 개선하기 위해 가까운 시일 내에 제공될 예정인 기능을 미리 살펴보세요.

  • 영역 캡처에서 다른 탭의 캡처를 지원합니다.
  • 조건부 포커스를 사용하면 캡처 웹 앱이 브라우저에 캡처된 디스플레이 화면으로 포커스를 전환하거나 이러한 포커스 변경을 방지하도록 지시할 수 있습니다.
  • 요소 수준 캡처 API가 제공될 수 있습니다.

의견

Chrome팀과 웹 표준 커뮤니티는 영역 캡처에 관한 여러분의 경험을 듣고 싶습니다.

디자인에 대해 알려주세요.

영역 캡처가 예상대로 작동하지 않는 부분이 있나요? 아이디어를 구현하는 데 필요한 메서드나 속성이 누락되어 있나요? 보안 모델에 관해 궁금한 점이나 의견이 있으신가요?

  • GitHub 저장소에 사양 문제를 제출하거나 기존 문제에 의견을 추가하세요.

구현에 문제가 있나요?

Chrome 구현에서 버그를 발견하셨나요? 아니면 구현이 사양과 다른가요?

  • https://new.crbug.com에서 버그를 신고하세요. 최대한 많은 세부정보와 재현을 위한 간단한 안내를 포함하세요.

지원 표시

영역 캡처를 사용할 계획인가요? 공개적인 지원은 Chrome팀이 기능의 우선순위를 정하는 데 도움이 되며 다른 브라우저 공급업체에 이러한 기능을 지원하는 것이 얼마나 중요한지 보여줍니다.

@ChromiumDev에 트윗을 보내 어디에서 어떻게 사용하고 있는지 알려주세요.

감사의 말씀

이 도움말을 검토해 주신 Joe Medley에게 감사드립니다.