Screen Capture API به کاربر این امکان را می دهد که یک برگه، پنجره یا صفحه را برای ضبط به عنوان جریان رسانه انتخاب کند. سپس این جریان می تواند ضبط شود یا از طریق شبکه با دیگران به اشتراک گذاشته شود. این مستندات Conditional Focus را معرفی میکند، مکانیزمی برای برنامههای وب برای کنترل اینکه آیا برگه یا پنجره ضبطشده هنگام شروع عکسبرداری فوکوس میشود یا اینکه آیا صفحه عکسبرداری متمرکز باقی میماند.
پشتیبانی از مرورگر
Focus شرطی از Chrome 109 در دسترس است.
پس زمینه
هنگامی که یک برنامه وب شروع به گرفتن یک برگه یا یک پنجره می کند، مرورگر با یک تصمیم روبرو می شود - آیا سطح ضبط شده باید در خط مقدم قرار گیرد یا صفحه عکسبرداری باید متمرکز بماند؟ پاسخ به دلیل فراخوانی getDisplayMedia()
و سطحی که کاربر در نهایت انتخاب می کند بستگی دارد.
یک برنامه وب کنفرانس ویدئویی فرضی را در نظر بگیرید. با خواندن track.getSettings().displaySurface
و بررسی بالقوه Capture Handle ، برنامه وب کنفرانس ویدیویی می تواند بفهمد کاربر چه چیزی را برای اشتراک گذاری انتخاب کرده است. سپس:
- اگر تب یا پنجره ضبط شده را می توان از راه دور کنترل کرد، کنفرانس ویدیویی را در کانون توجه قرار دهید.
- در غیر این صورت، برگه یا پنجره ضبط شده را متمرکز کنید.
در مثال بالا، برنامه وب کنفرانس ویدئویی در صورت اشتراک گذاری یک عرشه اسلاید، تمرکز خود را حفظ می کند و به کاربر اجازه می دهد تا از راه دور اسلایدها را ورق بزند. اما اگر کاربر اشتراکگذاری یک ویرایشگر متن را انتخاب کند، برنامه وب کنفرانس ویدیویی فوراً فوکوس را به برگه یا پنجره ضبطشده تغییر میدهد.
با استفاده از 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()
، در صورتی که کاربر یک صفحه (نه یک برگه یا یک پنجره) را به اشتراک بگذارد، وعده حل می شود.
نمونه
با اجرای دمو در Glitch می توانید با Conditional Focus بازی کنید. حتماً کد منبع را بررسی کنید .
تشخیص ویژگی
برای بررسی اینکه آیا CaptureController.setFocusBehavior()
پشتیبانی می شود یا خیر، از:
if (
"CaptureController" in window &&
"setFocusBehavior" in CaptureController.prototype
) {
// CaptureController.setFocusBehavior() is supported.
}
بازخورد
تیم Chrome و انجمن استانداردهای وب میخواهند در مورد تجربیات شما با Conditional Focus بشنوند.
در مورد طراحی به ما بگویید
آیا چیزی در مورد Conditional Focus وجود دارد که آنطور که انتظار داشتید کار نمی کند؟ یا آیا روش ها یا ویژگی هایی وجود دارد که برای اجرای ایده خود به آنها نیاز دارید؟ سوال یا نظری در مورد مدل امنیتی دارید؟
- یک مشکل مشخصات را در مخزن GitHub ثبت کنید یا افکار خود را به یک مشکل موجود اضافه کنید.
مشکل در اجرا؟
آیا اشکالی در پیاده سازی کروم پیدا کردید؟ یا اجرا با مشخصات متفاوت است؟
- یک اشکال را در https://new.crbug.com ثبت کنید. حتماً تا جایی که می توانید جزئیات و دستورالعمل های ساده را برای بازتولید درج کنید. Glitch برای به اشتراک گذاری کد به خوبی کار می کند.
نشان دادن پشتیبانی
آیا قصد دارید از فوکوس شرطی استفاده کنید؟ پشتیبانی عمومی شما به تیم Chrome کمک میکند ویژگیها را اولویتبندی کند و به سایر فروشندگان مرورگر نشان میدهد که چقدر حمایت از آنها ضروری است.
یک توییت به @ChromiumDev ارسال کنید و به ما اطلاع دهید که کجا و چگونه از آن استفاده می کنید.
لینک های مفید
قدردانی ها
تصویر قهرمان توسط النا تاراننکو .
با تشکر از راشل اندرو برای بررسی این مقاله.