Interfejs Screen Capture API umożliwia użytkownikowi wybranie karty, okna lub ekranu do przechwycenia jako strumienia multimediów. Strumień można nagrać lub udostępnić innym osobom w sieci. W tym dokumencie przedstawiamy funkcję Conditional Focus, czyli mechanizm, który umożliwia aplikacjom internetowym określanie, czy przechwycona karta lub okno mają być aktywne po rozpoczęciu przechwytywania, czy też aktywna ma pozostać strona przechwytująca.
Obsługa przeglądarek
Warunkowe ustawianie ostrości jest dostępne od Chrome 109.
Tło
Gdy aplikacja internetowa zaczyna przechwytywać kartę lub okno, przeglądarka musi podjąć decyzję, czy przechwytywana powierzchnia ma zostać przeniesiona na pierwszy plan, czy też strona przechwytująca ma pozostać aktywna. Odpowiedź zależy od powodu połączenia getDisplayMedia()
i od wybranej przez użytkownika usługi.
Weźmy pod uwagę hipotetyczną aplikację internetową do rozmów wideo. Odczytując track.getSettings().displaySurface
i ewentualnie sprawdzając uchwyt przechwytywania, aplikacja internetowa do rozmów wideo może dowiedzieć się, co użytkownik wybrał do udostępnienia. Następnie:
- Jeśli przechwycona karta lub okno mogą być sterowane zdalnie, utrzymuj fokus na wideokonferencji.
- W przeciwnym razie zaznacz przechwyconą kartę lub okno.
W powyższym przykładzie aplikacja internetowa do wideokonferencji zachowa fokus, jeśli użytkownik udostępni prezentację, co pozwoli mu zdalnie przełączać slajdy. Jeśli jednak użytkownik zdecyduje się udostępnić edytor tekstu, aplikacja internetowa do wideokonferencji natychmiast przełączy fokus na przechwyconą kartę lub okno.
Korzystanie z interfejsu Conditional Focus API
Utwórz instancję CaptureController
i przekaż ją do getDisplayMedia()
. Wywołując setFocusBehavior()
natychmiast po rozwiązaniu obietnicy zwróconej przez 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 ustawić ostrość, możesz wziąć pod uwagę uchwyt 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");
}
Możesz nawet zdecydować, czy chcesz ustawić ostrość przed nawiązaniem połączenia 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 rozwiązaniem obietnicy lub co najwyżej raz bezpośrednio po rozwiązaniu obietnicy. Ostatnie wywołanie zastępuje wszystkie poprzednie.
Dokładniej:getDisplayMedia()
- Zwrócony obiekt Promise jest rozstrzygany w mikrozadaniu. Wywołanie funkcji setFocusBehavior()
po zakończeniu tego mikrozadania spowoduje błąd.
– Wywołanie setFocusBehavior()
ponad sekundę po rozpoczęciu przechwytywania nie powoduje żadnej zmiany.
Oznacza to, że oba te fragmenty kodu nie będą działać:
// 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 funkcji setFocusBehavior()
powoduje też zgłoszenie wyjątku w tych przypadkach:
- ścieżka wideo strumienia zwróconego przez
getDisplayMedia()
nie jest „na żywo”. - po rozwiązaniu obietnicy zwróconej przez
getDisplayMedia()
, jeśli użytkownik udostępnił ekran (nie kartę ani okno).
Przykład
Możesz wypróbować funkcję warunkowego ustawiania ostrości, uruchamiając wersję demonstracyjną.
Wykrywanie cech
Aby sprawdzić, czy znak CaptureController.setFocusBehavior()
jest obsługiwany, użyj tego kodu:
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 chcą poznać Twoje wrażenia związane z korzystaniem z warunkowego ustawiania ostrości.
Opisz projekt
Czy jest coś w funkcji warunkowego ustawiania ostrości, co nie działa zgodnie z Twoimi oczekiwaniami? Czy brakuje metod lub właściwości, które są potrzebne do realizacji Twojego pomysłu? Masz pytania lub uwagi dotyczące modelu zabezpieczeń?
- Zgłoś problem ze specyfikacją w repozytorium GitHub lub dodaj swoje uwagi do istniejącego problemu.
Masz problem z implementacją?
Czy w implementacji Chrome występuje błąd? 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 odtworzenia problemu.
Okaż wsparcie
Czy planujesz używać funkcji Conditional Focus? Twoje publiczne wsparcie pomaga zespołowi Chrome ustalać priorytety funkcji i pokazuje innym dostawcom przeglądarek, jak ważne jest ich obsługiwanie.
Wyślij tweeta do @ChromiumDev i napisz, gdzie i jak korzystasz z tej funkcji.
Przydatne linki
Podziękowania
Baner powitalny autorstwa Eleny Taranenko.
Dziękujemy Rachel Andrew za sprawdzenie tego artykułu.