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

فرانسوا بوفورت
فرانسوا بوفورت
إيلاد ألون
"إيلاد ألون"

دعم المتصفح

  • 109
  • 109
  • x
  • x

المصدر

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

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

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

الخلفية

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

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

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

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

إظهار الدعم

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

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

شكر وتقدير

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

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