שיתוף טוב יותר של המסך עם 'התמקדות מותנית'

François Beaufort
François Beaufort

תמיכה בדפדפן

  • Chrome: 109.
  • קצה: 109.
  • Firefox: לא נתמך.
  • Safari: לא נתמך.

מקור

Screen capture API מאפשר למשתמשים לבחור כרטיסייה, חלון או מסך כדי לצלם אותם בתור שידור מדיה. לאחר מכן ניתן יהיה להקליט את השידור או לשתף אותו עם אנשים אחרים ברשת. מסמכי התיעוד כוללים את התכונה 'מיקוד מותנה', מנגנון לאפליקציות אינטרנט שקובע אם יתמקדו בכרטיסייה או בחלון שתועדו בתחילת הצילום, או אם דף הצילום יישאר ממוקד.

תמיכה בדפדפנים

התכונה 'פוקוס מותנה' זמינה ב-Chrome 109.

רקע

כשאפליקציית אינטרנט מתחילה לצלם כרטיסייה או חלון, הדפדפן מקבל החלטה – האם צריך להציג את הפלטפורמה שתועדה או להתמקד בדף הצילום? התשובה תלויה בסיבה להתקשרות אל getDisplayMedia(), ועל פני השטח המשתמש יבחר את השיחה.

כדאי להשתמש באפליקציית אינטרנט היפותטית לשיחות ועידה בווידאו. על ידי קריאה של track.getSettings().displaySurface ועיון בכינוי הצילום, אפליקציית האינטרנט לשיחות ועידה בווידאו יכולה להבין מה המשתמש בחר לשתף. לאחר מכן:

  • אם אפשר לשלוט מרחוק בכרטיסייה או בחלון שצולמו, התמקדו בשיחת הוועידה בווידאו.
  • אם לא, מתמקדים בכרטיסייה או בחלון שצולמו.

בדוגמה שלמעלה, המיקוד של אפליקציית האינטרנט של שיחות ועידה בווידאו יישמר אם הם רוצים לשתף מצגת, וכך המשתמש יוכל לדפדף מרחוק בין השקפים; אבל אם המשתמש יבחר לשתף עורך טקסט, אפליקציית האינטרנט לשיחות ועידה בווידאו תעביר מיד את המיקוד לכרטיסייה או לחלון שהוקלטו.

שימוש ב-Conditional Focus API

יוצרים CaptureController ומעבירים אותו אל getDisplayMedia(). התקשרות אל setFocusBehavior() מיד לאחר סיום ההבטחה של getDiplayMedia() שהוחזרה, תאפשר לך לקבוע אם הכרטיסייה או החלון שהוקלטו יתמקדו או לא. ניתן לעשות זאת רק אם המשתמש שיתף כרטיסייה או חלון.

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

כשמחליטים אם להתמקד, אפשר לקחת בחשבון את כינוי הצילום.

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

אפשר אפילו להחליט אם להתמקד לפני התקשרות ל-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 });

אפשר להתקשר אל setFocusBehavior() באופן שרירותי פעמים רבות לפני שההבטחה מתבטלת, או לכל היותר פעם אחת מיד לאחר שההבטחה מתבטלת. ההפעלה האחרונה מבטלת את כל ההפעלות הקודמות.

ליתר דיוק: - ההבטחה שהחזירה ב-getDisplayMedia() נפתרה במיקרו-משימה. קריאה אל setFocusBehavior() לאחר השלמת המיקרו-משימה גורמת לשגיאה. - התקשרות אל setFocusBehavior() למשך יותר משנייה לאחר התחלת הצילום היא ללא פעולה.

כלומר, שני קטעי הקוד הבאים ייכשלו:

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

קריאה אל setFocusBehavior() גורמת גם למקרים הבאים:

  • טראק הווידאו של השידור שהוחזר על ידי getDisplayMedia() אינו "פעיל".
  • אחרי שההבטחה שהוחזרה getDisplayMedia() נסגרת, אם המשתמש שיתף מסך (לא כרטיסייה או חלון).

דוגמה

כדי לשחק עם הפוקוס המותנה, מפעילים את ההדגמה במכשיר 'תקלה'. חשוב לבדוק את קוד המקור.

זיהוי תכונות

כדי לבדוק אם CaptureController.setFocusBehavior() נתמך, צריך להשתמש בקוד:

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

משוב

צוות Chrome וקהילת תקני האינטרנט רוצים לשמוע על החוויה שלכם עם 'מיקוד מותנה'.

נשמח לשמוע על העיצוב

האם יש משהו בתכונה 'פוקוס מותנה' שלא פועל כצפוי? או שיש שיטות או מאפיינים חסרים שתצטרכו ליישם את הרעיון שלכם? יש לך שאלה או הערה לגבי מודל האבטחה?

  • מפרסמים בעיית מפרט במאגר GitHub או מוסיפים הערות לגבי בעיה קיימת.

נתקלתם בבעיה בהטמעה?

מצאת באג בהטמעה של Chrome? או שההטמעה שונה מהמפרט?

פנייה לתמיכה

האם את/ה מתכננ/ת להשתמש בפוקוס מותנה? התמיכה הציבורית שלך עוזרת לצוות Chrome לתת עדיפות לתכונות, ומראה לספקי דפדפנים אחרים עד כמה חשוב לתמוך בהם.

שליחת ציוץ אל @ChromiumDev והראו לנו איפה ואיך אתם משתמשים בו.

אישורים

תמונה ראשית (Hero) של אלנה טארננקו.

תודה לרייצ'ל אנדרו שכתבה את המאמר הזה.