조건부 포커스로 화면 공유 개선

François Beaufort
François Beaufort

브라우저 지원

  • 109
  • 109
  • x
  • x

소스

Screen Capture API를 사용하면 탭, 창, 화면을 선택하여 미디어 스트림으로 캡처할 수 있습니다. 그러면 이 스트림을 녹화하거나 네트워크를 통해 다른 사용자와 공유할 수 있습니다. 이 문서에서는 캡처 시작 시 캡처된 탭이나 창에 포커스를 둘지 또는 캡처 페이지에 포커스를 유지할지 여부를 제어하는 웹 앱 메커니즘인 조건부 포커스를 소개합니다.

브라우저 지원

조건부 포커스는 Chrome 109부터 사용할 수 있습니다.

배경

웹 앱이 탭이나 창을 캡처하기 시작하면 브라우저는 캡처된 노출 영역을 앞으로 표시해야 할지, 캡처 페이지에 포커스를 두어야 할지 결정해야 합니다. 답은 getDisplayMedia()를 호출하는 이유와 사용자가 최종적으로 선택하는 표시 경로에 따라 다릅니다.

가상의 화상 회의 웹 앱을 생각해 보세요. 화상 회의 웹 앱은 track.getSettings().displaySurface를 읽고 캡처 핸들을 검사함으로써 사용자가 공유하기로 선택한 사항을 이해할 수 있습니다. 그런 다음 아래를 실행합니다.

  • 캡처한 탭 또는 창을 원격으로 제어할 수 있는 경우 화상 회의에 계속 초점을 맞춥니다.
  • 또는 캡처한 탭이나 창에 포커스를 맞춥니다.

위의 예에서 화상 회의 웹 앱은 슬라이드 자료를 공유하면 사용자가 원격으로 슬라이드를 넘길 수 있도록 포커스를 유지하지만, 사용자가 텍스트 편집기를 공유하도록 선택하면 화상 회의 웹 앱에서 즉시 캡처된 탭 또는 창으로 포커스가 전환됩니다.

Conditional Focus API 사용

CaptureController를 인스턴스화하여 getDisplayMedia()에 전달합니다. getDiplayMedia() 반환된 프로미스가 확인된 직후 setFocusBehavior()를 호출하여 캡처된 탭이나 창에 포커스를 둘지 여부를 제어할 수 있습니다. 이 작업은 사용자가 탭 또는 창을 공유한 경우에만 가능합니다.

const controller = new CaptureController();

// Prompt the user to share a tab, a window or a screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

const [track] = stream.getVideoTracks();
const displaySurface = track.getSettings().displaySurface;
if (displaySurface == "browser") {
  // Focus the captured tab.
  controller.setFocusBehavior("focus-captured-surface");
} else if (displaySurface == "window") {
  // Do not move focus to the captured window.
  // Keep the capturing page focused.
  controller.setFocusBehavior("focus-capturing-application");
}

포커스 여부를 결정할 때 캡처 핸들을 고려할 수 있습니다.

// Retain focus if capturing a tab dialed to example.com.
// Focus anything else.
const origin = track.getCaptureHandle().origin;
if (displaySurface == "browser" && origin == "https://example.com") {
  controller.setFocusBehavior("focus-capturing-application");
} else if (displaySurface != "monitor") {
  controller.setFocusBehavior("focus-captured-surface");
}

getDisplayMedia()를 호출하기 전에 포커스를 둘지 결정할 수도 있습니다.

// Focus the captured tab or window when capture starts.
const controller = new CaptureController();
controller.setFocusBehavior("focus-captured-surface");

// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

프로미스가 결정되기 전에 임의의 횟수로 setFocusBehavior()를 호출하거나 프로미스가 확인된 직후에 최대 한 번 호출할 수 있습니다. 마지막 호출은 이전의 모든 호출을 재정의합니다.

더 정확하게는 다음과 같습니다. - 반환된 getDisplayMedia() 프라미스는 마이크로태스크에서 확인됩니다. 마이크로태스크가 완료된 후 setFocusBehavior()를 호출하면 오류가 발생합니다. - 캡처 시작 후 1초가 넘게 setFocusBehavior()을 호출하면 작동하지 않습니다.

즉, 다음 스니펫이 모두 실패합니다.

// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

// Too late, because it follows the completion of the task
// on which the getDisplayMedia() promise resolved.
// This will throw.
setTimeout(() => {
  controller.setFocusBehavior("focus-captured-surface");
});
// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

const start = new Date();
while (new Date() - start <= 1000) {
  // Idle for ≈1s.
}

// Because too much time has elapsed, the browser will have
// already decided whether to focus.
// This fails silently.
controller.setFocusBehavior("focus-captured-surface");

setFocusBehavior()을 호출하면 다음과 같은 경우에도 발생합니다.

  • getDisplayMedia()에서 반환한 스트림의 동영상 트랙이 'live'가 아닙니다.
  • 사용자가 탭이나 창이 아닌 화면을 공유한 경우 getDisplayMedia()가 반환된 프로미스가 확인된 후

샘플

Glitch에서 데모를 실행하여 조건부 포커스를 사용해 볼 수 있습니다. 소스 코드를 확인하세요.

특성 감지

CaptureController.setFocusBehavior()가 지원되는지 확인하려면 다음을 사용합니다.

if (
  "CaptureController" in window &&
  "setFocusBehavior" in CaptureController.prototype
) {
  // CaptureController.setFocusBehavior() is supported.
}

의견

Chrome팀과 웹 표준 커뮤니티는 조건부 포커스 사용 경험에 관한 의견을 기다리고 있습니다.

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

조건부 초점 기능이 예상대로 작동하지 않는 부분이 있나요? 아니면 아이디어를 구현하는 데 필요한 메서드나 속성이 누락되었나요? 보안 모델에 대한 질문이나 의견이 있습니까?

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

구현에 문제가 있습니까?

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

  • https://new.crbug.com에서 버그를 신고합니다. 재현을 위한 간단한 안내와 가능한 한 많은 세부정보를 포함하세요. Glitch는 코드 공유에 적합합니다.

지지 표시

조건부 포커스를 사용할 계획이신가요? 공개 지원은 Chrome팀이 기능의 우선순위를 정하고 다른 브라우저 공급업체에 해당 기능을 지원하는 것이 얼마나 중요한지 보여주는 데 도움이 됩니다.

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

감사의 말씀

히어로 이미지: Elena Taranenko

이 기사를 검토해 주신 Rachel Andrew님께 감사드립니다.