Met de Screen Capture API kan de gebruiker een tabblad, venster of scherm selecteren om vast te leggen als mediastream. Deze stream kan vervolgens worden opgenomen of gedeeld met anderen via het netwerk. Deze documentatie introduceert Conditional Focus, een mechanisme waarmee webapps kunnen bepalen of het vastgelegde tabblad of venster de focus krijgt wanneer de opname start, of dat de vastgelegde pagina de focus behoudt.
Browserondersteuning
Voorwaardelijke focus is beschikbaar in Chrome 109.
Achtergrond
Wanneer een webapp een tabblad of venster begint vast te leggen, staat de browser voor een beslissing: moet het vastgelegde oppervlak naar voren worden gehaald, of moet de vastgelegde pagina in beeld blijven? Het antwoord hangt af van de reden waarom getDisplayMedia()
is aangeroepen en van het oppervlak dat de gebruiker uiteindelijk selecteert.
Beschouw een hypothetische web-app voor videoconferenties. Door track.getSettings().displaySurface
te lezen en mogelijk de Capture Handle te onderzoeken, kan de web-app voor videoconferenties begrijpen wat de gebruiker heeft gekozen om te delen. Vervolgens:
- Als het vastgelegde tabblad of venster op afstand kan worden bediend, zorg er dan voor dat de videoconferentie scherp is.
- Anders focust u op het vastgelegde tabblad of venster.
In het bovenstaande voorbeeld behoudt de web-app voor videoconferenties de focus als er een diaserie wordt gedeeld, zodat de gebruiker op afstand door de dia's kan bladeren. Als de gebruiker er echter voor kiest om een teksteditor te delen, schakelt de web-app voor videoconferenties direct over naar het vastgelegde tabblad of venster.
De voorwaardelijke focus-API gebruiken
Instantieer een CaptureController
en geef deze door aan getDisplayMedia()
. Door setFocusBehavior()
aan te roepen direct nadat de door getDiplayMedia()
geretourneerde promise is opgelost, kunt u bepalen of het vastgelegde tabblad of venster de focus krijgt of niet. Dit is alleen mogelijk als de gebruiker een tabblad of venster heeft gedeeld.
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");
}
Bij het bepalen of u wilt scherpstellen, kunt u rekening houden met de Capture Handle .
// 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");
}
Het is zelfs mogelijk om te beslissen of er focus moet zijn voordat getDisplayMedia()
wordt aangeroepen.
// 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 });
U kunt setFocusBehavior()
willekeurig meerdere keren aanroepen voordat de belofte wordt opgelost, of maximaal één keer direct nadat de belofte is opgelost. De laatste aanroep overschrijft alle voorgaande aanroepen.
Preciezer gezegd: - De getDisplayMedia()
-belofte wordt geretourneerd op een microtaak. Het aanroepen van setFocusBehavior()
nadat die microtaak is voltooid, levert een fout op. - Het aanroepen van setFocusBehavior()
meer dan een seconde na de start van de opname is no-op.
Dat wil zeggen dat de volgende twee fragmenten beide zullen mislukken:
// 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");
Het aanroepen van setFocusBehavior()
levert ook de volgende gevallen op:
- het videospoor van de stream die door
getDisplayMedia()
wordt geretourneerd, is niet "live" . - nadat de
getDisplayMedia()
-belofte is geretourneerd, wordt opgelost of de gebruiker een scherm heeft gedeeld (geen tabblad of venster).
Steekproef
U kunt met Voorwaardelijke Focus spelen door de demo uit te voeren.
Functiedetectie
Om te controleren of CaptureController.setFocusBehavior()
wordt ondersteund, gebruikt u:
if (
"CaptureController" in window &&
"setFocusBehavior" in CaptureController.prototype
) {
// CaptureController.setFocusBehavior() is supported.
}
Feedback
Het Chrome-team en de webstandaardencommunity willen graag uw ervaringen met voorwaardelijke focus horen.
Vertel ons over het ontwerp
Werkt voorwaardelijke focus niet zoals verwacht? Of ontbreken er methoden of eigenschappen die u nodig hebt om uw idee te implementeren? Heeft u een vraag of opmerking over het beveiligingsmodel?
- Dien een spec-probleem in op de GitHub-repository of voeg uw mening toe over een bestaand probleem.
Probleem met de implementatie?
Heb je een bug gevonden in de implementatie van Chrome? Of wijkt de implementatie af van de specificatie?
- Meld een bug op https://new.crbug.com . Zorg ervoor dat je zoveel mogelijk details en eenvoudige instructies voor reproductie verstrekt.
Toon steun
Bent u van plan voorwaardelijke focus te gebruiken? Uw publieke steun helpt het Chrome-team bij het prioriteren van functies en laat andere browserleveranciers zien hoe belangrijk het is om deze te ondersteunen.
Stuur een tweet naar @ChromiumDev en laat ons weten waar en hoe je het gebruikt.
Nuttige links
Dankbetuigingen
Heldenfoto door Elena Taranenko .
Dank aan Rachel Andrew voor het beoordelen van dit artikel.