مشاركة الشاشة بشكلٍ أفضل باستخدام ميزة "التركيز المشروط"

François Beaufort
François Beaufort

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

Source

تتيح واجهة برمجة التطبيقات لأخذ لقطة شاشة للمستخدم اختيار علامة تبويب أو نافذة أو شاشة لأخذ لقطة منها كتدفق وسائط. ويمكن بعد ذلك تسجيل هذا البث أو مشاركته مع الآخرين عبر الشبكة. تقدّم هذه المستندات ميزة "التركيز الشرطي"، وهي آلية تتيح لتطبيقات الويب التحكّم في ما إذا كان سيتم التركيز على علامة التبويب أو النافذة التي يتم تسجيلها عند بدء التسجيل، أو ما إذا كانت صفحة التسجيل ستبقى في المقدّمة.

دعم المتصفح

تتوفّر ميزة "التركيز الشرطي" بدءًا من الإصدار 109 من Chrome.

الخلفية

عندما يبدأ تطبيق ويب في تسجيل شاشة أو نافذة، يواجه المتصفّح قرارًا: هل يجب عرض السطح المسجَّل في المقدّمة، أو هل يجب أن تظل صفحة التسجيل محل التركيز؟ تعتمد الإجابة على سبب الاتصال 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()، إذا شارك المستخدم شاشة (وليس علامة تبويب أو نافذة)

عيّنة

يمكنك تجربة ميزة "التركيز الشرطي" من خلال تشغيل العرض التوضيحي.

رصد الميزات

للتحقّق مما إذا كان الرمز CaptureController.setFocusBehavior() متاحًا، استخدِم ما يلي:

if (   "CaptureController" in window &&   "setFocusBehavior" in CaptureController.prototype ) {   // CaptureController.setFocusBehavior() is supported. } 

الملاحظات

يريد فريق Chrome ومنتدى معايير الويب معرفة تجاربك مع ميزة "التركيز الشرطي".

أخبِرنا عن التصميم

هل هناك أيّ مشكلة في ميزة "التركيز الشرطي" لا تعمل على النحو المتوقّع؟ أو هل هناك طرق أو سمات ناقصة تحتاج إلى تنفيذ فكرتك؟ هل لديك سؤال أو تعليق حول نموذج الأمان؟

  • يمكنك الإبلاغ عن مشكلة في المواصفات على مستودع GitHub، أو إضافة أفكارك إلى مشكلة حالية.

هل تواجه مشكلة في التنفيذ؟

هل عثرت على خطأ في تنفيذ Chrome؟ أو هل يختلف التنفيذ عن المواصفات؟

  • يمكنك الإبلاغ عن الخطأ على https://new.crbug.com. احرص على تضمين أكبر قدر ممكن من التفاصيل وتعليمات بسيطة لإعادة إنتاج الخطأ.

إظهار الدعم

هل تخطّط لاستخدام ميزة "التركيز الشرطي"؟ يساعد دعمك العلني فريق Chrome في تحديد أولويات الميزات، ويوضّح لمورّدي المتصفّحات الآخرين مدى أهمية توفيرها.

يمكنك إرسال تغريدة إلى ‎@ChromiumDev وإخبارنا بمكان استخدامك لها وطريقة استخدامك لها.

الإقرارات

الصورة الرئيسية من إيلينا تارانينكو

نشكر راشيل أندرو على مراجعة هذه المقالة.