באמצעות Screen Recording API אפשר לצלם את כל הכרטיסייה הנוכחית. Element Capture API מאפשר לכם לתעד אלמנט HTML ספציפי. היא הופכת צילום של הכרטיסייה כולה לצילום של עץ משנה ספציפי של DOM, שבו מתועדים רק הצאצאים הישירים של רכיב היעד. במילים אחרות, המערכת חותכת ומסירה גם תוכן שמסתיר וגם תוכן שמוסתר.
למה כדאי להשתמש ב-Element Capture?
כשאתם מביאים בחשבון את הדרישות של אפליקציה לשיחות ועידה בווידאו, אתם יכולים להבין באילו מקרים אלמנטים של צילום רכיבים מועילים. אם יש לכם אפליקציה לשיחות ועידה בווידאו שמאפשרת להטמיע אפליקציות של צד שלישי ב-iframe, יכול להיות שתצטרכו לפעמים לצלם את ה-iframe הזה כסרטון ולהעביר אותו למשתתפים מרוחקים.
קריאה ל-getDisplayMedia()
והרשאה למשתמש לבחור את הכרטיסייה הנוכחית יעבירו את כל הכרטיסייה הנוכחית. סביר להניח שהסרטון שלהם יועבר אליהם בחזרה. אפשר לחתוך את החלק הזה באמצעות צילום אזור.
עם זאת, מה קורה אם המגיש משתמש באפליקציית הווידאו-קונפרציה ותוכן כלשהו, כמו רשימה נפתחת, מופיע מעל התוכן שמיועד לצילום?
התכונה 'צילום אזור' לא תעזור לך במקרה כזה. יכול להיות שחלק מהרשימה הנפתחת יוצג במסכים של המשתתפים מרחוק.
העובדה שצילום האזור מתעד חלקים מרכיבים בדרך הזו (שנקראת חסימת תוכן) יוצרת כמה בעיות:
- חסימה של תוכן עלולה להסתיר את התוכן שהמשתמש התכוון לשתף.
- הסתרה של תוכן עשויה להיות פרטית (למשל, התראות בצ'אט).
- חסימה של תוכן עלולה לבלבל. (לדוגמה, עיצוב מחדש של האפליקציה יכול להציג למשך זמן קצר את הסרטונים של המשתתפים מרחוק מעל היעד שצולם).
Element Capture API פותר את כל הבעיות האלה, כי הוא מאפשר לכם לטרגט את הרכיב שרוצים לשתף.
איך משתמשים ב-Element Capture?
ה-captureTarget
הוא רכיב בדף שמכיל את התוכן שהמשתמש רוצה לצלם. אתם רוצים שהאפליקציה לאינטרנט לשיחות ועידה בווידאו תצלם את captureTarget
ותשתף אותו עם משתתפים מרחוק. כך מפיקים RestrictionTarget
מ-captureTarget
. אחרי שמגבילים את טראק הסרטון באמצעות RestrictionTarget
הזה, התמונות בטראק הסרטון הזה מורכבות עכשיו רק מהפיקסלים שנכללים ב-captureTarget
ובצאצאים הישירים שלו ב-DOM.
אם captureTarget
משתנה בגודל, בצורה או במיקום, הטראק של הסרטון עוקב אחריו בלי צורך בהזנה נוספת מאף אפליקציית אינטרנט. באופן דומה, אין צורך בטיפול מיוחד במקרים שבהם תוכן מופיע, נעלם או זז.
בודקים שוב את השלבים הבאים:
כדי להתחיל, צריך לאפשר למשתמש לצלם את הכרטיסייה הנוכחית.
// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();
מגדירים RestrictionTarget
על ידי קריאה ל-RestrictionTarget.fromElement()
עם רכיב לבחירתכם כקלט.
// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
לאחר מכן, קוראים לפונקציה restrictTo()
בטראק של הווידאו עם ה-RestrictionTarget
כקלט. אחרי שההבטחה האחרונה תיפתר, כל המסגרות הבאות יוגבלו.
// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);
// Enjoy! Transmit remotely.
ירידה לעומק
זיהוי תכונות
כדי לבדוק אם יש תמיכה ב-RestrictionTarget.fromElement()
, משתמשים ב-:
if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
// Deriving a restriction target is supported.
}
הפקת RestrictionTarget
מתמקדים ברכיב שנקרא captureTarget
. כדי להפיק ממנו RestrictionTarget
, צריך לבצע קריאה ל-RestrictionTarget.fromElement(captureTarget)
. אם הפעולה תתבצע בהצלחה, ה-Promise שהוחזר יפתור עם אובייקט RestrictionTarget
חדש. אחרת, הבקשה תידחה אם יצרתם מספר לא סביר של אובייקטים מסוג RestrictionTarget
.
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
בניגוד לאלמנט, אובייקט RestrictionTarget
הוא ניתן לסריאליזציה. למשל, אפשר להעביר אותה למסמך אחר באמצעות Window.postMessage()
.
הגבלה
כשמצלמים כרטיסייה, הטראק של הסרטון חושף את restrictTo()
. כשמצלמים את הכרטיסייה הנוכחית, אפשר להפעיל את restrictTo()
עם null
או עם כל RestrictionTarget
שמבוסס על רכיב בכרטיסייה הנוכחית.
קריאות ל-restrictTo(restrictionTarget)
משנות את טראק הסרטון לתיעוד של captureTarget
, כאילו הוא נמשך בעצמו, ללא תלות בשאר ה-DOM. כל הצאצאים של captureTarget
נתפסו גם הם. האחים של captureTarget
מסולקים מהצילום. כתוצאה מכך, כל הפריימים שהושגו בטראק נראים כאילו הם נחתכו לקווי המתאר של captureTarget
וכל תוכן מסתיר או מוסתר מוסרים.
// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);
קריאות ל-restrictTo(null)
מחזירות את הטראק למצב המקורי שלו.
// Stop restricting.
await track.restrictTo(null);
אם הקריאה אל restrictTo()
תאושר, ההבטחה שהוחזרה תיפתר כשניתן יהיה להבטיח שכל הפריימים הבאים של הווידאו יוגבלו ל-captureTarget
.
אם הפעולה לא מסתיימת בהצלחה, ה-Promise נדחה. שיחה שנכשלה אל restrictTo()
נובעת מאחת מהסיבות הבאות:
- אם ה-
restrictionTarget
הוטבע בכרטיסייה אחרת מזו שמתועדת. (שימו לב: באמצעות הלחצן 'שיתוף הכרטיסייה הזו במקום זאת', המשתמשים יכולים לשנות את הכרטיסייה שתועבר בכל זמן נתון). - אם השדה
restrictionTarget
נגזר מרכיב שכבר לא קיים. - אם יש לטראק עותקים כפולים. (בעיה מס' 1509418)
- אם הטראק הנוכחי הוא לא טראק של סרטון שצילמתם בעצמכם.
- אם האלמנט שממנו נגזר הערך
restrictionTarget
לא עומד בדרישות להגבלה.
שיקולים לגבי צילום עצמי
כשאפליקציה קוראת ל-getDisplayMedia()
והמשתמש בוחר לצלם את הכרטיסייה של האפליקציה, אנחנו קוראים לזה 'צילום עצמי'.
השיטה restrictTo()
חשופה בכל טראק וידאו לצילום כרטיסיות, ולא רק לצילום עצמי. עם זאת, התכונה 'צילום רכיבים' מופעלת כרגע רק לצילום עצמי. לכן מומלץ לבדוק אם המשתמש בחר בכרטיסייה הנוכחית, לפני שמנסים להגביל את הטראק. ניתן לעשות זאת באמצעות כינוי הצילום. אפשר גם לבקש מהדפדפן לעודד את המשתמש לצלם את עצמו באמצעות preferCurrentTab
.
שקיפות
מסגרות הווידאו שהאפליקציה מקבלת דרך getDisplayMedia()
לא כוללות ערוץ אלפא. אם אפליקציה מגדירה יעד צילום שקוף חלקית, יכולות להיות לכך כמה השלכות אפשריות:
- הצבעים עשויים להשתנות. רכיבי יעד שקופים חלקית המשורטטים על רקע בהיר עשויים להיראות כהים יותר כשמסירים את ערוץ האלפא, ורכיבים שמצוינים על רקע כהה עשויים להיראות בהירים יותר.
- צבעים שהיו נסתרים או לא גלויים למשתמש כשערוץ האלפא הוגדר למקסימום, יופיעו לאחר הסרה של ערוץ האלפא. לדוגמה, אם בקטעים השקופים היה קוד RGBA
rgba(0, 0, 0, 0)
, יכול להיות שיופיעו אזורים שחורים לא צפויים בפריימים שצולמו.
יעדים לא כשירים לחיוב מיידי
תמיד אפשר להתחיל להגביל טראק לכל יעד תקף לתיעוד. עם זאת, המערכת לא תיצור פריימים בתנאים מסוימים, למשל אם האלמנט או האב הוא display:none
. הנימוק הכללי הוא שההגבלה חלה רק על רכיב שמורכב מאזור מלבני אחד, מאוחד ודו-ממדי, שאפשר לקבוע את הפיקסלים שלו באופן לוגי בנפרד מאלמנטים של הורה או אח.
אחד השיקולים החשובים כדי לוודא שהאלמנט עומד בדרישות להגבלה הוא שהוא צריך ליצור הקשר סטאקינג משלו. כדי לוודא זאת, אפשר לציין את מאפיין ה-CSS isolation ולהגדיר אותו כ-isolate
.
<div id="captureTarget" style="isolation: isolate;"></iframe>
חשוב לזכור שרכיב היעד יכול לעבור בין סטטוס 'כשיר' לסטטוס 'לא כשיר' לכל זמן נתון, למשל אם האפליקציה משנה את מאפייני ה-CSS שלה. האפליקציה צריכה להשתמש ביעדים סבירים לצילום ולהימנע משינוי המאפיינים שלהם באופן בלתי צפוי. אם רכיב היעד לא עומד בדרישות, לא יועברו פריים חדשים בטראק עד שרכיב היעד יעמוד שוב בדרישות להגבלה.
הפעלת צילום רכיבים
Element Capture API זמין ב-Chrome במחשבים, מאחורי הדגל Element Capture, וניתן להפעיל אותו בכתובת chrome://flags/#element-capture
.
התכונה הזו גם נכנסת לתקופת ניסיון במקור מ-Chrome 121 במחשב, שמאפשרת למפתחים להפעיל את התכונה למבקרים באתרים שלהם כדי לאסוף נתונים ממשתמשים אמיתיים. מידע נוסף על ניסויים במקור זמין במאמר תחילת העבודה עם ניסויים במקור.
אבטחה ופרטיות
כדי להבין את הפשרות האבטחה, כדאי לעיין בקטע שיקולים לגבי פרטיות ואבטחה במפרט של Element Capture.
דפדפן Chrome מצייר גבול כחול סביב הקצוות של הכרטיסיות שצולמו.
הדגמה (דמו)
כדי לשחק עם Element Upload (צילום רכיבים), מריצים את ההדגמה ב-Glitch. חשוב לבדוק את קוד המקור.
משוב
צוות Chrome וקהילת תקני האינטרנט רוצים לשמוע על החוויה שלכם עם Element Capture.
נשמח לשמוע על העיצוב
האם יש משהו בתכונה 'צילום אזור' שלא פועל כצפוי? או אולי חסרות שיטות או מאפיינים שדרושים לכם כדי להטמיע את הרעיון? יש לכם שאלות או הערות לגבי מודל האבטחה?
- אפשר לשלוח דיווח על בעיה במפרט במאגר GitHub או להוסיף את המחשבות שלכם לבעיה קיימת.
בעיה בהטמעה?
מצאת באג באופן ההטמעה של Chrome? או שההטמעה שונה מהמפרט?
- שולחים דיווח על באג בכתובת https://new.crbug.com. חשוב לכלול כמה שיותר פרטים והוראות פשוטות לשחזור הבעיה. Glitch הוא כלי מצוין לשיתוף שחזור מהיר וקל של באגים.
קישורים שימושיים
אימות חתימות
צילום: Paul Skorupskas ב-Unsplash