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

François Beaufort
François Beaufort

دعم المتصفح

  • 109
  • 109
  • x
  • x

المصدر

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

المتصفحات المتوافقة

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

الخلفية

عندما يبدأ تطبيق ويب في التقاط علامة تبويب أو نافذة، يواجه المتصفح قرارًا - هل يجب وضع السطح الذي تم التقاطه في المقدمة، أم يجب أن تظل صفحة الالتقاط مركزة؟ تعتمد الإجابة على سبب طلب الرقم getDisplayMedia()، وتظهر نتائج البحث للمستخدمِين أمامهم.

يمكنك استخدام تطبيق ويب افتراضي لعقد اجتماعات الفيديو. وعند قراءة track.getSettings().displaySurface وربما فحص مقبض الالتقاط، يمكن لتطبيق الويب لاجتماعات الفيديو فهم ما اختار المستخدم مشاركته. بعد ذلك:

  • إذا كان من الممكن التحكم عن بُعد في علامة التبويب أو النافذة التي تم التقاطها، أبقِ مكالمة الفيديو محل التركيز.
  • أمّا في الحالات الأخرى، فركِّز على علامة التبويب أو النافذة التي تم التقاطها.

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

استخدام 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. تأكّد من الاطّلاع على رمز المصدر.

رصد الميزات

لمعرفة ما إذا كانت "CaptureController.setFocusBehavior()" متاحة، استخدِم:

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

ملاحظات

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

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

هل هناك شيء ما عن التركيز الشرطي لا يعمل كما توقعت؟ أو هل هناك طرق أو خصائص مفقودة تحتاجها لتنفيذ فكرتك؟ هل لديك سؤال أو تعليق بشأن نموذج الأمان؟

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

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

هل واجهت مشكلة في التنفيذ في Chrome؟ أم أن التنفيذ يختلف عن المواصفات؟

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

إظهار الدعم

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

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

شكر وتقدير

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

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