גלילה בכרטיסייה מוקלטת ושינוי מרחק התצוגה שלה

François Beaufort
François Beaufort

כבר אפשר לשתף כרטיסיות, חלונות ומסכים בפלטפורמת האינטרנט באמצעות Screen Capture API. כשאפליקציית אינטרנט קוראת ל-getDisplayMedia(), Chrome מציגה למשתמש בקשה לשתף כרטיסייה, חלון או מסך עם אפליקציית האינטרנט כסרטון MediaStreamTrack.

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

במסמך הזה נסביר על Captured Surface Control API החדש ב-Chrome, שמאפשר לאפליקציית האינטרנט לגלול בכרטיסייה שצולמה, וגם לקרוא ולכתוב את רמת הזום של כרטיסייה שצולמה.

משתמש גולל בכרטיסייה שצולמה ומגדיל את התצוגה שלה (הדגמה).

למה כדאי להשתמש ב-Captured Surface Control?

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

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

ממשק ה-API לניהול משטחים שתועדו פותר את הבעיות האלה.

איך משתמשים ב'שליטה בשטח התמונה'?

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

תיעוד של כרטיסייה בדפדפן

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

const controller = new CaptureController();
const stream = await navigator.mediaDevices.getDisplayMedia({ controller });

בשלב הבא, יוצרים תצוגה מקדימה מקומית של פני השטח שצולמו, בצורת רכיב <video>:

const previewTile = document.querySelector('video');
previewTile.srcObject = stream;

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

const [track] = stream.getVideoTracks();

if (track.getSettings().displaySurface !== 'browser') {
  // Bail out early if the user didn't pick a tab.
  return;
}

בקשת הרשאה

ההפעלה הראשונה של forwardWheel(), ‏increaseZoomLevel(), ‏decreaseZoomLevel() או resetZoomLevel() באובייקט CaptureController נתון מובילה להצגת בקשה להרשאה. אם המשתמש מעניק הרשאה, ניתן להפעיל את השיטות האלה שוב.

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

גלילה

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

בהנחה שאפליקציית הצילום משתמשת ברכיב <video> שנקרא "previewTile", הקוד הבא מראה איך להעביר אירועי שליחת גלגל לכרטיסייה שצולמה:

const previewTile = document.querySelector('video');
try {
  // Relay the user's action to the captured tab.
  await controller.forwardWheel(previewTile);
} catch (error) {
  // Inspect the error.
  // ...
}

ל-method forwardWheel() יש קלט יחיד שיכול להיות אחד מהערכים הבאים:

  • רכיב HTML שממנו אירועי גלילה יועברו לכרטיסייה שצולמה.
  • null, כדי לציין שההעברה צריכה להיפסק.

קריאה מוצלחת ל-forwardWheel() מבטלת את הקריאות הקודמות.

ההבטחה שמוחזרת על ידי forwardWheel() יכולה להידחות במקרים הבאים:

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

שינוי מרחק התצוגה

האינטראקציה עם רמת הזום של הכרטיסייה שצולמה מתבצעת באמצעות ממשקי ה-API הבאים של CaptureController:

getSupportedZoomLevels()

השיטה הזו מחזירה רשימה של רמות זום שנתמכות בדפדפן לסוג פני השטח שמצולם. הערכים ברשימה הזו מיוצגים באחוזים ביחס ל'רמת הזום שמוגדרת כברירת מחדל', שמוגדרת כ-100%. הרשימה עולה באופן מונוטונית ומכילה את הערך 100.

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

אפשר להפעיל את controller.getSupportedZoomLevels() אם מתקיימים התנאים הבאים:

  • controller משויך לתיעוד פעיל.
  • התמונה היא של כרטיסייה.

אחרת, תופיע הודעת שגיאה.

ההרשאה "captured-surface-control" לא נדרשת כדי לקרוא לשיטה הזו.

zoomLevel

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

בסיום הצילום, המאפיין יכיל את הערך האחרון של רמת הזום.

ההרשאה "captured-surface-control" לא נדרשת לקריאת המאפיין הזה.

onzoomlevelchange

פונקציית הטיפול באירועים הזו מאפשרת להאזין לשינויים ברמת הזום של הכרטיסייה שצולמה. אלה יכולים לקרות במקרים הבאים:

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

ההרשאה "captured-surface-control" לא נדרשת לקריאת המאפיין הזה.

increaseZoomLevel(),‏ decreaseZoomLevel() וגם resetZoomLevel()

השיטות האלה מאפשרות לשנות את רמת הזום של הכרטיסייה שצולמה.

increaseZoomLevel() ו-decreaseZoomLevel() משנים את רמת הזום לרמה הבאה או הקודמת, בהתאמה, לפי הסדר שמוחזר על ידי getSupportedZoomLevels(). resetZoomLevel() מגדיר את הערך כ-100.

כדי לקרוא לשיטות האלה, נדרשת ההרשאה "captured-surface-control". אם לאפליקציית הצילום אין את ההרשאה הזו, המשתמש יתבקש להעניק או לדחות אותה.

כל השיטות האלה מחזירות הבטחה (promise) שמתקבלת אם הקריאה מסתיימת בהצלחה, ונדחית אחרת. סיבות אפשריות לדחייה:

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

חשוב לציין: מומלץ להימנע משיחות אל decreaseZoomLevel() אם controller.zoomLevel == controller.getSupportedZoomLevels().at(0), ולהגן על שיחות אל increaseZoomLevel() באופן דומה באמצעות .at(-1).

בדוגמה הבאה מוסבר איך לאפשר למשתמש להגדיל את רמת הזום של כרטיסייה שצולמה ישירות מאפליקציית הצילום:

const zoomIncreaseButton = document.getElementById('zoomInButton');
zoomIncreaseButton.addEventListener('click', async (event) => {
  if (controller.zoomLevel >= controller.getSupportedZoomLevels().at(-1)) {
    return;
  }
  try {
    await controller.increaseZoomLevel();
  } catch (error) {
    // Inspect the error.
    // ...
  }
});

בדוגמה הבאה מוסבר איך להגיב לשינויים ברמת הזום של כרטיסייה שצולמה:

controller.addEventListener('zoomlevelchange', (event) => {
  const zoomLevelLabel = document.querySelector('#zoomLevelLabel');
  zoomLevelLabel.textContent = `${controller.zoomLevel}%`;
});

זיהוי תכונות

כדי לבדוק אם יש תמיכה בממשקי API לניהול של משטחי צפייה, משתמשים ב-:

if (!!window.CaptureController?.prototype.forwardWheel) {
  // CaptureController forwardWheel() is supported.
}

אפשר גם להשתמש בכל אחד מהמשטחים האחרים של Captured Surface Control API, כמו increaseZoomLevel או decreaseZoomLevel, או אפילו לבדוק את כולם.

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

התכונה 'שליטה במשטח שצולם' זמינה בגרסה 136 של Chrome במחשב בלבד.

אבטחה ופרטיות

מדיניות ההרשאות של "captured-surface-control" מאפשרת לכם לקבוע לאילו אפליקציות הקלטה ולפריטי iframe מוטמעים של צד שלישי תהיה גישה ל-Captured Surface Control. כדי להבין את הפשרות האבטחה, כדאי לעיין בקטע שיקולים לגבי פרטיות ואבטחה במאמר ההסבר על אמצעי הבקרה של משטחי הצגה.

הדגמה (דמו)

כדי לשחק עם Captured Surface Control, אפשר להריץ את הדמו ב-Glitch. חשוב לבדוק את קוד המקור.

משוב

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

נשמח לקבל פרטים על העיצוב

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

בעיה בהטמעה?

מצאתם באג בהטמעה של Chrome? או שההטמעה שונה מהמפרט? שולחים דיווח על באג בכתובת https://new.crbug.com. חשוב לכלול כמה שיותר פרטים, וגם הוראות לשחזור הבעיה.