Lepsze udostępnianie ekranu dzięki koncentracji warunkowej

François Beaufort
François Beaufort

Obsługa przeglądarek

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

Źródło

Interfejs Screen Capture API umożliwia wybór karty, okna lub ekranu, które mają zostać przechwycone jako strumień multimediów. Tę transmisję można potem nagrać lub udostępnić innym w sieci. Ta dokumentacja przedstawia tryb warunkowy, czyli mechanizm, który pozwala aplikacjom internetowym określić, czy przechwytywana karta lub okno mają być aktywne w momencie rozpoczęcia przechwytywania, czy też aktywna ma pozostać 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 połączenia getDisplayMedia()i od powierzchni, którą użytkownik wybierze.

Rozważ hipotetyczną aplikację internetową do rozmów wideo. Czytając track.getSettings().displaySurface i ewentualnie analizując uchwytywanie danych, aplikacja internetowa do rozmów wideo może się dowiedzieć, 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 zaznacz przechwyconą kartę lub okno.

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

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: - zwrócona 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ługiwana, 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 pytanie lub komentarz na temat 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. Usterka dobrze sprawdza się w przypadku udostępniania kodu.

Pokaż wsparcie

Czy planujesz korzystać z warunkowego skupienia uwagi? Twoja publiczna pomoc pomaga zespołowi Chrome ustalać priorytety funkcji i pokazywać innym dostawcom przeglądarek, jak ważne jest, aby wspierać te funkcje.

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

Podziękowania

Baner powitalny autorstwa Elena Taranenko.

Dziękujemy Rachelowi Andrew za przeczytanie tego artykułu.