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 osobom w sieci. W tej dokumentacji omawiamy fokus warunkowy – mechanizm używany przez aplikacje internetowe do kontrolowania, czy przechwycona karta lub okno mają być zaznaczone w momencie rozpoczęcia przechwytywania, czy też strona przechwytywania pozostanie aktywna.

Obsługa przeglądarek

Ostrość warunkowa jest dostępna w Chrome 109.

Tło

Gdy aplikacja internetowa rozpoczyna przechwytywanie karty lub okna, przeglądarka musi podjąć decyzję. Czy przechwycona powierzchnia powinna znajdować się na pierwszym planie, czy powinna pozostać aktywna? Odpowiedź zależy od powodu wywołania funkcji getDisplayMedia() oraz od tego, co użytkownik wybierze.

Rozważ użycie hipotetycznej aplikacji internetowej do prowadzenia rozmów wideo. Jeśli czytasz komunikat track.getSettings().displaySurface i sprawdzasz nick do przechwytywania, aplikacja internetowa do obsługi rozmów wideo wie, co użytkownik zdecydował się udostępnić. Następnie:

  • Jeśli zapisaną kartą lub oknem można sterować zdalnie, upewnij się, że rozmowa wideo jest widoczna.
  • W przeciwnym razie zaznacz przechwyconą kartę lub okno.

W powyższym przykładzie aplikacja internetowa do obsługi rozmów wideo zachowałaby fokus, jeśli została udostępniona, ponieważ umożliwia użytkownikowi zdalne przechodzenie między slajdami. Jeśli jednak użytkownik udostępnia edytor tekstu, aplikacja internetowa do obsługi rozmów wideo natychmiast przełącza 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() natychmiast po rozwiązaniu zwróconej obietnicy getDiplayMedia(), możesz określić, czy przechwycona karta lub okno mają być zaznaczone. 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");
}

Podejmując decyzję o tym, czy się skupić, możesz wziąć pod uwagę nick przechwytywania.

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

Przed nawiązaniem połączenia z firmą getDisplayMedia() możesz nawet zdecydować, czy chcesz się skupić.

// 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ływać funkcję setFocusBehavior() dowolnie wiele razy przed zakończeniem obietnicy lub maksymalnie raz natychmiast po jej zrealizowaniu. Ostatnie wywołanie zastępuje wszystkie poprzednie wywołania.

A dokładniej: – Zwrócona obietnica getDisplayMedia() rozwiązuje się po wykonaniu mikrozadania. Wywołanie setFocusBehavior() po zakończeniu tego mikrozadań powoduje zgłoszenie błędu. – Wywoływanie połączenia setFocusBehavior() dłużej niż sekundę od rozpoczęcia nagrywania jest w żaden sposób.

Oznacza to, że nie powiodą się oba te fragmenty kodu:

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

Wywołanie setFocusBehavior() powoduje też:

  • ścieżka wideo strumienia zwrócona przez użytkownika getDisplayMedia() nie jest „live”.
  • po zwróceniu obietnicy getDisplayMedia(), jeśli użytkownik udostępnił ekran (a nie kartę lub okno).

Przykład

Aby wypróbować funkcję koncentracji warunkowej, uruchom wersję demonstracyjną aplikacji Glitch. Koniecznie zapoznaj się z kodem źródłowym.

Wykrywanie cech

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

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

Prześlij opinię

Zespół Chrome i społeczność ds. standardów internetowych chcą dowiedzieć się więcej o Twoich doświadczeniach związanych z fokusem warunkowym.

Opowiedz nam o projekcie

Czy jest coś, co w skupieniu warunkowym nie działa zgodnie z oczekiwaniami? A może brakuje Ci metod lub właściwości, które pozwolą Ci zrealizować Twój pomysł? Masz pytanie lub komentarz na temat modelu zabezpieczeń?

Problem z implementacją?

Czy wystąpił błąd z implementacją Chrome? Czy implementacja różni się od specyfikacji?

  • Zgłoś błąd na https://new.crbug.com. Postaraj się podać jak najwięcej szczegółów oraz proste instrukcje odtwarzania filmu. Usterka dobrze sprawdza się w przypadku udostępniania kodu.

Pokaż wsparcie

Czy zamierzasz zastosować fokus warunkowy? 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 na adres @ChromiumDev, aby poinformować nas, gdzie i jak go używasz.

Podziękowania

Baner powitalny: Elena Taranenko.

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