באמצעות Screen Capture API, אפשר לצלם את כל הכרטיסייה הנוכחית. Element Capture API מאפשר לכם לתעד אלמנט HTML ספציפי. הפונקציה הופכת צילום של הכרטיסייה כולה לצילום של עץ משנה ספציפי של DOM, שבו מתועדים רק הצאצאים הישירים של רכיב היעד. במילים אחרות, המערכת חותכת ומסירה גם תוכן שמסתיר וגם תוכן שמוסתר.
למה כדאי להשתמש ב-Element Capture?
כדאי לבדוק את הדרישות של אפליקציית שיתוף הווידאו כדי להבין איפה 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()
מסתיימת בהצלחה, ה-Promise המוחזר נפתר כשאפשר להבטיח שכל הפריימים הבאים של הסרטון יהיו מוגבלים ל-captureTarget
.
אם הפעולה לא מסתיימת בהצלחה, ה-Promise נדחה. קריאה ל-restrictTo()
שתיכשל תהיה בגלל אחת מהסיבות הבאות:
- אם
restrictionTarget
נוצר בכרטיסייה אחרת מזו שצולמה. (שימו לב: באמצעות הלחצן 'שיתוף הכרטיסייה הזו במקום זאת', המשתמשים יכולים לשנות את הכרטיסייה שתועבר בכל זמן נתון). - אם השדה
restrictionTarget
נגזר מרכיב שכבר לא קיים. - אם יש לטראק עותקים כפולים. (בעיה מס' 1509418)
- אם הטראק הנוכחי הוא לא טראק של סרטון שצילמתם בעצמכם.
- אם האלמנט שממנו נגזר הערך
restrictionTarget
לא עומד בדרישות להגבלה.
שיקולים לגבי צילום עצמי
כשאפליקציה קוראת ל-getDisplayMedia()
והמשתמש בוחר לצלם את הכרטיסייה של האפליקציה, אנחנו קוראים לזה 'צילום עצמי'.
השיטה restrictTo()
מוצגת בכל טראק וידאו של צילום כרטיסייה, ולא רק בצילום עצמי. אבל בשלב זה, התכונה 'צילום רכיבים' מופעלת רק לצילום עצמי. לכן, מומלץ לבדוק אם המשתמש בחר בכרטיסייה הנוכחית לפני שמנסים להגביל את הטראק. אפשר לעשות זאת באמצעות Capture Handle. אפשר גם לבקש מהדפדפן לדחוף את המשתמש לצילום עצמי באמצעות 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 Capture, אפשר להריץ את הדמו ב-Glitch. חשוב לבדוק את קוד המקור.
משוב
צוות Chrome וקהילת תקני האינטרנט רוצים לשמוע על החוויה שלכם עם Element Capture.
נשמח לשמוע על העיצוב
האם יש משהו בצילום האזור שלא פועל כצפוי? או אולי חסרות שיטות או מאפיינים שדרושים לכם כדי להטמיע את הרעיון? יש לכם שאלות או הערות לגבי מודל האבטחה?
- אפשר לשלוח דיווח על בעיה במפרט במאגר GitHub או להוסיף את המחשבות שלכם לבעיה קיימת.
בעיה בהטמעה?
מצאתם באג בהטמעה של Chrome? או שההטמעה שונה מהמפרט?
- שולחים דיווח על באג בכתובת https://new.crbug.com. חשוב לכלול כמה שיותר פרטים והוראות פשוטות לשחזור הבעיה. Glitch הוא כלי מצוין לשיתוף שחזור מהיר וקל של באגים.
קישורים שימושיים
אימות חתימות
צילום: Paul Skorupskas ב-Unsplash