স্ক্রিন ক্যাপচার এপিআই ব্যবহারকারীকে একটি ট্যাব, উইন্ডো বা স্ক্রিন নির্বাচন করে মিডিয়া স্ট্রিম হিসেবে ক্যাপচার করার সুযোগ দেয়। এরপর এই স্ট্রিমটি রেকর্ড করা যায় অথবা নেটওয়ার্কের মাধ্যমে অন্যদের সাথে শেয়ার করা যায়। এই ডকুমেন্টেশনে কন্ডিশনাল ফোকাস (Conditional Focus) সম্পর্কে আলোচনা করা হয়েছে, যা ওয়েব অ্যাপের জন্য একটি কৌশল। এর মাধ্যমে নিয়ন্ত্রণ করা যায় যে, ক্যাপচার শুরু হওয়ার সময় ক্যাপচার করা ট্যাব বা উইন্ডোটি ফোকাসড হবে, নাকি ক্যাপচারিং পেজটিই ফোকাসড থাকবে।
ব্রাউজার সমর্থন
ক্রোম ১০৯ থেকে কন্ডিশনাল ফোকাস পাওয়া যাচ্ছে।
পটভূমি
যখন কোনো ওয়েব অ্যাপ একটি ট্যাব বা উইন্ডো ক্যাপচার করা শুরু করে, তখন ব্রাউজারকে একটি সিদ্ধান্ত নিতে হয়—ক্যাপচার করা অংশটিকে সামনে নিয়ে আসা হবে, নাকি ক্যাপচারিং পেজটিই ফোকাসে থাকবে? এর উত্তর নির্ভর করে getDisplayMedia() কল করার কারণ এবং ব্যবহারকারী শেষ পর্যন্ত কোন অংশটি নির্বাচন করছেন তার উপর।
একটি কাল্পনিক ভিডিও কনফারেন্সিং ওয়েব অ্যাপের কথা ভাবুন। track.getSettings().displaySurface পড়ে এবং সম্ভবত Capture Handle পরীক্ষা করে, ভিডিও কনফারেন্সিং ওয়েব অ্যাপটি বুঝতে পারে যে ব্যবহারকারী কী শেয়ার করতে বেছে নিয়েছেন। তারপর:
- ক্যাপচার করা ট্যাব বা উইন্ডোটি যদি দূর থেকে নিয়ন্ত্রণ করা যায়, তাহলে ভিডিও কনফারেন্সটিকে ফোকাসে রাখুন।
- অন্যথায়, ক্যাপচার করা ট্যাব বা উইন্ডোটিতে ফোকাস করুন।
উপরের উদাহরণে, একটি স্লাইড ডেক শেয়ার করার সময় ভিডিও কনফারেন্সিং ওয়েব অ্যাপটি ফোকাস ধরে রাখত, যা ব্যবহারকারীকে দূর থেকে স্লাইডগুলো উল্টে দেখার সুযোগ দিত; কিন্তু যদি ব্যবহারকারী একটি টেক্সট এডিটর শেয়ার করার সিদ্ধান্ত নিতেন, তাহলে ভিডিও কনফারেন্সিং ওয়েব অ্যাপটি সঙ্গে সঙ্গে ক্যাপচার করা ট্যাব বা উইন্ডোতে ফোকাস পরিবর্তন করে দিত।
কন্ডিশনাল ফোকাস এপিআই ব্যবহার করে
একটি CaptureController ইনস্ট্যানশিয়েট করুন এবং এটিকে getDisplayMedia() ফাংশনে পাস করুন। getDiplayMedia() থেকে রিটার্ন করা প্রমিসটি রিজলভ হওয়ার ঠিক পরেই setFocusBehavior() কল করার মাধ্যমে, আপনি ক্যাপচার করা ট্যাব বা উইন্ডোটি ফোকাসড হবে কি না তা নিয়ন্ত্রণ করতে পারেন। এটি শুধুমাত্র তখনই করা সম্ভব, যদি ব্যবহারকারী কোনো ট্যাব বা উইন্ডো শেয়ার করে থাকেন।
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.
}
প্রতিক্রিয়া
ক্রোম টিম এবং ওয়েব স্ট্যান্ডার্ড কমিউনিটি কন্ডিশনাল ফোকাস নিয়ে আপনার অভিজ্ঞতা সম্পর্কে জানতে আগ্রহী।
ডিজাইন সম্পর্কে আমাদের বলুন
কন্ডিশনাল ফোকাস (Conditional Focus) সম্পর্কে এমন কিছু কি আছে যা আপনার প্রত্যাশা অনুযায়ী কাজ করছে না? অথবা আপনার ধারণাটি বাস্তবায়নের জন্য প্রয়োজনীয় কোনো মেথড বা প্রপার্টি কি অনুপস্থিত? নিরাপত্তা মডেল (security model) সম্পর্কে আপনার কোনো প্রশ্ন বা মন্তব্য আছে কি?
- গিটহাব রিপোতে একটি স্পেক ইস্যু ফাইল করুন, অথবা বিদ্যমান কোনো ইস্যুতে আপনার মতামত যোগ করুন।
বাস্তবায়নে সমস্যা?
আপনি কি ক্রোমের বাস্তবায়নে কোনো বাগ খুঁজে পেয়েছেন? নাকি এর বাস্তবায়ন স্পেসিফিকেশন থেকে ভিন্ন?
- https://new.crbug.com -এ একটি বাগ রিপোর্ট করুন। যতটা সম্ভব বিস্তারিত তথ্য এবং বাগটি পুনরায় ঘটানোর নির্দেশনা অবশ্যই অন্তর্ভুক্ত করবেন।
সমর্থন দেখান
আপনি কি কন্ডিশনাল ফোকাস ব্যবহার করার পরিকল্পনা করছেন? আপনার প্রকাশ্য সমর্থন ক্রোম টিমকে ফিচারগুলোকে অগ্রাধিকার দিতে সাহায্য করে এবং অন্যান্য ব্রাউজার নির্মাতাদের দেখায় যে এগুলোর সমর্থন করা কতটা জরুরি।
@ChromiumDev- কে একটি টুইট পাঠিয়ে আমাদের জানান, আপনি এটি কোথায় এবং কীভাবে ব্যবহার করছেন।
সহায়ক লিঙ্ক
কৃতজ্ঞতা স্বীকার
এই নথিটি পর্যালোচনা করার জন্য র্যাচেল অ্যান্ড্রুকে ধন্যবাদ।