Screen Capture API를 사용하면 웹 플랫폼에서 탭, 창, 화면을 이미 공유할 수 있습니다. 웹 앱이 getDisplayMedia()
를 호출하면 Chrome에서 사용자에게 탭, 창 또는 화면을 웹 앱과 MediaStreamTrack
동영상으로 공유하라는 메시지를 표시합니다.
getDisplayMedia()
를 사용하는 많은 웹 앱은 캡처된 노출 영역의 동영상 미리보기를 사용자에게 표시합니다. 예를 들어 화상 회의 앱은 이 동영상을 원격 사용자에게 스트리밍하는 동시에 로컬 HTMLVideoElement
에 렌더링하여 로컬 사용자가 공유하는 항목의 미리보기를 계속 볼 수 있도록 합니다.
이 문서에서는 웹 앱이 캡처된 탭을 스크롤하고 캡처된 탭의 확대/축소 수준을 읽고 쓸 수 있는 Chrome의 새로운 Captured Surface Control API를 소개합니다.
캡처된 노출 영역 컨트롤을 사용해야 하는 이유
모든 화상 회의 앱에는 동일한 단점이 있습니다. 사용자가 캡처된 탭이나 창과 상호작용하려면 화상 회의 앱에서 벗어나 해당 노출 영역으로 전환해야 합니다. 이로 인해 몇 가지 문제가 발생합니다.
- 사용자가 PIP를 사용하거나 화상 회의 탭과 공유 탭을 위해 별도의 나란히 창을 사용하지 않는 한 캡처된 앱과 원격 사용자의 동영상 피드를 동시에 볼 수 없습니다. 작은 화면에서는 이 작업이 어려울 수 있습니다.
- 사용자는 화상 회의 앱과 캡처된 노출 영역 간에 전환해야 하는 부담을 느낍니다.
- 사용자가 화상 회의 앱을 사용하지 않는 동안 앱에서 노출하는 컨트롤(예: 삽입된 채팅 앱, 그림 이모티콘 반응, 통화에 참여하도록 요청하는 사용자에 관한 알림, 멀티미디어 및 레이아웃 컨트롤, 기타 유용한 화상 회의 기능)에 액세스할 수 없습니다.
- 발표자는 원격 참여자에게 제어 권한을 위임할 수 없습니다. 이로 인해 원격 사용자가 발표자에게 슬라이드를 변경하거나, 위아래로 약간 스크롤하거나, 확대/축소 수준을 조정하라고 요청하는 익숙한 상황이 발생합니다.
Captured Surface Control API는 이러한 문제를 해결합니다.
캡처된 노출 영역 컨트롤은 어떻게 사용하나요?
캡처된 노출 영역 컨트롤을 성공적으로 사용하려면 브라우저 탭을 명시적으로 캡처하고 사용자의 권한을 얻는 등의 몇 가지 단계를 거쳐야 캡처된 탭을 스크롤하고 확대/축소할 수 있습니다.
브라우저 탭 캡처
먼저 사용자에게 getDisplayMedia()
를 사용하여 공유할 노출 영역을 선택하라는 메시지를 표시하고 이 과정에서 CaptureController
객체를 캡처 세션과 연결합니다. 곧 이 객체를 사용하여 캡처된 노출 영역을 제어할 예정입니다.
const controller = new CaptureController();
const stream = await navigator.mediaDevices.getDisplayMedia({ controller });
다음으로 캡처된 노출 영역의 로컬 미리보기를 <video>
요소 형식으로 생성합니다.
const previewTile = document.querySelector('video');
previewTile.srcObject = stream;
사용자가 창이나 화면을 공유하려고 하는 경우 지금은 지원 범위가 아닙니다. 하지만 탭을 공유하려는 경우 계속 진행할 수 있습니다.
const [track] = stream.getVideoTracks();
if (track.getSettings().displaySurface !== 'browser') {
// Bail out early if the user didn't pick a tab.
return;
}
권한 메시지
지정된 CaptureController
객체에서 forwardWheel()
, increaseZoomLevel()
, decreaseZoomLevel()
또는 resetZoomLevel()
를 처음 호출하면 권한 메시지가 표시됩니다. 사용자가 권한을 부여하면 이러한 메서드를 계속 호출할 수 있습니다.
사용자에게 권한 메시지를 표시하려면 사용자 동작이 필요하므로 앱은 이미 권한을 보유하고 있거나 웹 앱의 관련 버튼에 있는 click
와 같은 사용자 동작에 응답하는 경우에만 위에서 언급한 메서드를 호출해야 합니다.
스크롤
forwardWheel()
를 사용하면 캡처 앱이 캡처 앱 자체 내의 소스 요소에서 캡처된 탭의 표시 영역으로 휠 이벤트를 전달할 수 있습니다. 이러한 이벤트는 캡처된 앱에서 직접적인 사용자 상호작용과 구분할 수 없습니다.
캡처 앱이 "previewTile"
라는 <video>
요소를 사용한다고 가정하면 다음 코드는 캡처된 탭에 휠 이벤트 전송을 릴레이하는 방법을 보여줍니다.
const previewTile = document.querySelector('video');
try {
// Relay the user's action to the captured tab.
await controller.forwardWheel(previewTile);
} catch (error) {
// Inspect the error.
// ...
}
forwardWheel()
메서드는 단일 입력을 사용하며, 이 입력은 다음 중 하나일 수 있습니다.
- 휠 이벤트가 캡처된 탭으로 전달되는 HTML 요소입니다.
null
: 전달을 중지해야 함을 나타냅니다.
forwardWheel()
를 성공적으로 호출하면 이전 호출이 재정의됩니다.
forwardWheel()
가 반환하는 프로미스는 다음과 같은 경우에 거부될 수 있습니다.
- 캡처 세션이 아직 시작되지 않았거나 이미 중지된 경우
- 사용자가 관련 권한을 부여하지 않은 경우
확대/축소
캡처된 탭의 확대/축소 수준과 상호작용하는 작업은 다음 CaptureController
API 노출 영역을 통해 이루어집니다.
getSupportedZoomLevels()
이 메서드는 캡처되는 노출 영역 유형에 대해 브라우저에서 지원하는 확대/축소 수준 목록을 반환합니다. 이 목록의 값은 100%로 정의된 '기본 확대/축소 수준'을 기준으로 백분율로 표시됩니다. 목록은 단조 증가하며 값 100을 포함합니다.
이 메서드는 지원되는 디스플레이 노출 영역 유형에 대해서만 호출할 수 있으며 현재는 탭에 대해서만 호출할 수 있습니다.
다음 조건이 충족되면 controller.getSupportedZoomLevels()
가 호출될 수 있습니다.
controller
는 활성 캡처와 연결됩니다.- 탭의 캡처입니다.
그렇지 않으면 오류가 발생합니다.
이 메서드를 호출하는 데 "captured-surface-control"
권한은 필요하지 않습니다.
zoomLevel
이 읽기 전용 속성은 캡처된 탭의 현재 확대/축소 수준을 보유합니다. null 허용 속성이며 캡처된 노출 영역 유형에 의미 있는 확대/축소 수준 정의가 없는 경우 null
를 보유합니다. 현재 zoom-level은 창이나 화면이 아닌 탭에 대해서만 정의됩니다.
캡처가 종료되면 속성은 마지막 확대/축소 수준 값을 유지합니다.
이 속성을 읽는 데는 "captured-surface-control"
권한이 필요하지 않습니다.
onzoomlevelchange
이 이벤트 핸들러는 캡처된 탭의 확대/축소 수준 변경사항을 수신 대기합니다. 다음과 같은 경우에 이 문제가 발생합니다.
- 사용자가 브라우저와 상호작용하여 캡처된 탭의 확대/축소 수준을 수동으로 변경하는 경우
- 캡처 앱의 확대/축소 설정 메서드 호출에 대한 응답으로 (아래 설명)
이 속성을 읽는 데는 "captured-surface-control"
권한이 필요하지 않습니다.
increaseZoomLevel()
, decreaseZoomLevel()
, resetZoomLevel()
이러한 메서드를 사용하면 캡처된 탭의 확대/축소 수준을 조작할 수 있습니다.
increaseZoomLevel()
및 decreaseZoomLevel()
는 getSupportedZoomLevels()
에서 반환된 순서에 따라 확대/축소 수준을 각각 다음 또는 이전 확대/축소 수준으로 변경합니다. resetZoomLevel()
는 값을 100으로 설정합니다.
이러한 메서드를 호출하려면 "captured-surface-control"
권한이 필요합니다. 캡처 앱에 이 권한이 없는 경우 사용자에게 권한을 부여하거나 거부하라는 메시지가 표시됩니다.
이러한 메서드는 모두 호출이 성공하면 해결되고 그렇지 않으면 거부되는 프로미스를 반환합니다. 거부 이유에는 다음이 포함될 수 있습니다.
- 권한이 누락됨
- 캡처가 시작되기 전에 호출됩니다.
- 캡처가 종료된 후에 호출됩니다.
- 지원되지 않는 디스플레이 노출 영역 유형의 캡처와 연결된
controller
에서 호출됩니다. 탭 캡처를 제외한 모든 작업입니다. - 각각 최대값 또는 최솟값을 초과하여 늘리거나 줄이려고 시도합니다.
특히 controller.zoomLevel == controller.getSupportedZoomLevels().at(0)
인 경우 decreaseZoomLevel()
를 호출하지 않는 것이 좋으며 .at(-1)
와 유사한 방식으로 increaseZoomLevel()
호출을 보호하는 것이 좋습니다.
다음 예는 사용자가 캡처 앱에서 직접 캡처된 탭의 확대/축소 수준을 높이도록 허용하는 방법을 보여줍니다.
const zoomIncreaseButton = document.getElementById('zoomInButton');
zoomIncreaseButton.addEventListener('click', async (event) => {
if (controller.zoomLevel >= controller.getSupportedZoomLevels().at(-1)) {
return;
}
try {
await controller.increaseZoomLevel();
} catch (error) {
// Inspect the error.
// ...
}
});
다음 예는 캡처된 탭의 확대/축소 수준 변경에 반응하는 방법을 보여줍니다.
controller.addEventListener('zoomlevelchange', (event) => {
const zoomLevelLabel = document.querySelector('#zoomLevelLabel');
zoomLevelLabel.textContent = `${controller.zoomLevel}%`;
});
기능 감지
Captured Surface Control API가 지원되는지 확인하려면 다음을 사용하세요.
if (!!window.CaptureController?.prototype.forwardWheel) {
// CaptureController forwardWheel() is supported.
}
increaseZoomLevel
또는 decreaseZoomLevel
와 같은 다른 Captured Surface Control API 노출 영역을 사용하거나 모두 확인할 수도 있습니다.
브라우저 지원
캡처된 노출 영역 제어는 데스크톱의 Chrome 136부터 사용할 수 있습니다.
보안 및 개인 정보 보호
"captured-surface-control"
권한 정책을 사용하면 캡처 앱과 삽입된 서드 파티 iframe이 캡처된 노출 영역 제어에 액세스하는 방식을 관리할 수 있습니다. 보안 절충점을 이해하려면 캡처된 노출 영역 제어 설명의 개인 정보 보호 및 보안 고려사항 섹션을 확인하세요.
데모
Glitch에서 데모를 실행하여 캡처된 노출 영역 컨트롤을 사용해 볼 수 있습니다. 소스 코드를 확인해야 합니다.
의견
Chrome팀과 웹 표준 커뮤니티는 캡처된 노출 영역 컨트롤 사용 경험에 관한 의견을 듣고자 합니다.
디자인에 관해 알려주세요.
캡처된 노출 영역 캡처가 예상대로 작동하지 않는 문제가 있나요? 아니면 아이디어를 구현하는 데 필요한 메서드나 속성이 누락되어 있나요? 보안 모델에 관해 질문이나 의견이 있으신가요? GitHub 저장소에서 사양 문제를 제출하거나 기존 문제에 의견을 추가하세요.
구현에 문제가 있나요?
Chrome 구현에서 버그를 발견했나요? 아니면 구현이 사양과 다른가요? https://new.crbug.com에서 버그를 신고합니다. 재현 안내와 함께 최대한 자세한 정보를 포함해야 합니다. Glitch는 재현 가능한 버그를 공유하는 데 적합합니다.