Lepsze udostępnianie ekranu dzięki koncentracji warunkowej

François Beaufort
François Beaufort

Obsługa przeglądarek

  • Chrome: 109.
  • Edge: 109.
  • Firefox: nieobsługiwane.
  • Safari: nieobsługiwane.

Źródło

Interfejs API do przechwytywania ekranu pozwala użytkownikowi wybrać kartę, okno lub ekran do przechwycenia jako strumień multimediów. Ten strumień można następnie nagrywać lub udostępniać innym osobom w sieci. Ta dokumentacja przedstawia fokus warunkowy, czyli mechanizm, który pozwala aplikacjom internetowym określić, czy przechwytywana karta lub okno będą aktywne w momencie rozpoczęcia przechwytywania, czy też aktywna pozostanie strona, na której odbywa się przechwytywanie.

Obsługa przeglądarek

Tryb ostrości warunkowej jest dostępny od wersji 109.

Tło

Gdy aplikacja internetowa zaczyna rejestrować kartę lub okno, przeglądarka musi podjąć decyzję, czy ma wyświetlić przechwyconą powierzchnię na pierwszym planie, czy też ma pozostać aktywna strona, z której jest pobierany obraz. Odpowiedź zależy od powodu kontaktu getDisplayMedia()i od tego, co użytkownik ostatecznie wybierze.

Rozważ hipotetyczną aplikację internetową do rozmów wideo. Czytając track.getSettings().displaySurface i potencjalnie analizując uchwytywanie uchwytu, aplikacja internetowa do rozmów wideo może dowiedzieć się, co użytkownik zdecydował się udostępnić. Następnie:

  • Jeśli można zdalnie sterować nagrywaną kartą lub oknem, pozostań w polu widzenia podczas wideokonferencji.
  • W przeciwnym razie ustaw zaznaczenie na przechwyconą kartę lub okno.

W przykładzie powyżej aplikacja do wideokonferencji zachowałaby fokus, jeśli użytkownik udostępnia prezentację, co pozwoliłoby mu zdalnie przełączać się między slajdami. Jeśli jednak użytkownik zdecyduje się udostępnić edytor tekstu, aplikacja do wideokonferencji natychmiast przełączy fokus na przechwycone okno lub kartę.

Korzystanie z interfejsu Conditional Focus API

Utwórz instancję CaptureController i przekaż ją do getDisplayMedia(). Wywołując funkcję setFocusBehavior() bezpośrednio po wykonaniu obietnicy z obietnicy zwracanej getDiplayMedia(), możesz określić, czy przechwycona karta lub okno ma być aktywne. Można to zrobić tylko wtedy, gdy użytkownik udostępnił kartę lub okno.

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

Decydując, czy użyć funkcji ostrości, możesz wziąć pod uwagę uchwyt na obiektyw.

// 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");
}

Możesz nawet zdecydować, czy chcesz się skupić, zanim zadzwonisz 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 });

Możesz wywołać funkcję setFocusBehavior() dowolną liczbę razy przed spełnieniem obietnicy lub maksymalnie raz bezpośrednio po jej spełnieniu. Ostatnie wywołanie zastąpi wszystkie poprzednie.

Dokładniej: - zwracana obietnica getDisplayMedia() jest realizowana w ramach mikrozadania. Po wywołaniu funkcji setFocusBehavior() po zakończeniu mikrozadania wystąpi błąd. – wywołanie funkcji setFocusBehavior() po upływie ponad sekundy od rozpoczęcia rejestrowania nie powoduje żadnych efektów.

Oznacza to, że oba podane niżej fragmenty kodu zakończą się niepowodzeniem:

// 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");

Funkcja setFocusBehavior() wywołuje też błąd w tych sytuacjach:

  • ścieżka wideo strumienia zwracana przez getDisplayMedia() nie jest „na żywo”.
  • po wykonaniu getDisplayMedia() z obietnicy, jeśli użytkownik udostępnił ekran (a nie kartę ani okno).

Przykład

Możesz wypróbować funkcję Conditional Focus, uruchamiając demo w Glitch. Pamiętaj, aby sprawdzić kod źródłowy.

Wykrywanie cech

Aby sprawdzić, czy CaptureController.setFocusBehavior() jest obsługiwane, użyj:

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

Prześlij opinię

Zespół Chrome i społeczność zajmująca się standardami internetowymi chce poznać Twoje wrażenia związane z użyciem funkcji Conditional Focus.

Opowiedz nam o projektowaniu

Czy coś w przypadku reguły warunkowej nie działa zgodnie z oczekiwaniami? A może brakuje metod lub właściwości, których potrzebujesz do wdrożenia swojego pomysłu? Masz pytania lub uwagi dotyczące modelu zabezpieczeń?

  • Zgłoś problem ze specyfikacją w repozytorium GitHub lub podziel się opinią na temat istniejącego problemu.

Problem z implementacją?

Czy znalazłeś/znalazłaś błąd w implementacji Chrome? A może implementacja różni się od specyfikacji?

  • Zgłoś błąd na stronie https://new.crbug.com. Podaj jak najwięcej szczegółów i proste instrukcje odtwarzania problemu. Glitch sprawdza się przy udostępnianiu kodu.

Pokaż pomoc

Czy planujesz korzystać z warunkowego skupienia uwagi? Twoje publiczne wsparcie pomaga zespołowi Chrome ustalać priorytety funkcji i pokazuje innym dostawcom przeglądarek, jak ważne jest ich wsparcie.

Wyślij tweeta do @ChromiumDev i powiedz nam, gdzie i jak z niego korzystasz.

Podziękowania

Baner powitalny autorstwa Elena Taranenko.

Dziękujemy Rachel Andrew za sprawdzenie tego artykułu.