تسجيل بث فيديو من أي عنصر

François Beaufort
François Beaufort

باستخدام واجهة برمجة التطبيقات Screen Capture API، يمكنك التقاط علامة التبويب الحالية بأكملها. تتيح لك واجهة برمجة التطبيقات Element Capture API تسجيل عنصر HTML معيّن. ويحوّل هذا الإجراء عملية تسجيل لعلامة التبويب بأكملها إلى عملية تسجيل لشجرة فرعية معيّنة من نموذج DOM، مع تسجيل العناصر المباشرة فقط للعنصر المستهدَف. بعبارة أخرى، يتم اقتصاص المحتوى الذي يحجب المحتوى المرئي وإزالته.

لماذا يجب استخدام ميزة "التقاط العناصر"؟

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

لقطة شاشة لمكالمة فيديو في Chrome
يستخدم "إلاد" تطبيقًا تابعًا لجهة خارجية في مكالمة عبر مؤتمر فيديو مع "فاروق".

سيؤدي طلب الإجراء getDisplayMedia() والسماح للمستخدم باختيار علامة التبويب الحالية إلى نقل علامة التبويب الحالية بالكامل. من المرجّح أن يؤدي ذلك إلى إعادة إرسال الفيديو الخاص بالمستخدمين إليهم. يمكنك اقتصاص هذه المنطقة باستخدام ميزة التقاط منطقة.

ولكن ماذا لو تفاعل المُقدّم مع تطبيق مكالمات الفيديو وظهر بعض المحتوى، مثل قائمة منسدلة، فوق المحتوى المراد تسجيله؟

لقطة شاشة لقائمة منسدلة تحجب المحتوى المراد تسجيله
تظهر قائمة منسدلة أعلى المحتوى المراد تسجيله.

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

لقطة شاشة لقائمة منسدلة تم التقاطها
تظهر القائمة المنسدلة التي أنشأها "إياد" أعلى المحتوى الذي تلقّاه "فاروق".

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

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

تحلّ واجهة برمجة التطبيقات Element Capture API جميع هذه المشاكل، من خلال السماح لك باستهداف العنصر الذي تريد مشاركته.

لقطة شاشة للعنصر المستهدَف بدون قائمة منسدلة في العرض
لا تظهر لـ "فاروق" القائمة المنسدلة التي أنشأها "إياد".

كيف يمكنني استخدام ميزة "التقاط العناصر"؟

captureTarget هو عنصر على صفحتك يحتوي على المحتوى الذي يريد المستخدم تسجيله. تريد أن يُسجِّل تطبيق الويب لعقد اجتماعات الفيديو captureTarget ويشاركه مع المشاركين عن بُعد. وبالتالي، يمكنك الحصول على RestrictionTarget من captureTarget. بعد حظر مقطع الفيديو باستخدام هذا RestrictionTarget، تتألف اللقطات في مقطع الفيديو هذا الآن من وحدات البكسل التي تشكّل جزءًا من captureTarget وعناصر DOM المباشرة المشتقة منه فقط.

إذا تغيّر حجم captureTarget أو شكله أو موقعه، يتبعه مقطع الفيديو بدون الحاجة إلى أي إدخال إضافي من أي تطبيق ويب. وبالمثل، لا يتطلّب حجب المحتوى الذي يظهر أو يختفي أو يتحرك أي معالجة خاصة.

يُرجى مراجعة هذه الخطوات مرة أخرى:

ابدأ بالسماح للمستخدم بتسجيل علامة التبويب الحالية.

// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
 preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

حدِّد RestrictionTarget من خلال استدعاء RestrictionTarget.fromElement() مع إدخال عنصر من اختيارك.

// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

بعد ذلك، اطلب restrictTo() في مقطع الفيديو باستخدام RestrictionTarget كمدخل. بعد حلّ الوعد الأخير، سيتم حظر جميع اللقطات اللاحقة.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

// Enjoy! Transmit remotely.

نظرة تفصيلية

رصد الميزات

للتحقّق مما إذا كان RestrictionTarget.fromElement() متوافقًا، استخدِم:

if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
  // Deriving a restriction target is supported.
}

اشتقاق عنصر RestrictionTarget

ركِّز على العنصر المُسمى captureTarget. لاستخراج RestrictionTarget منه، اتصل RestrictionTarget.fromElement(captureTarget). سيتم حلّ الوعد الذي تم إرجاعه باستخدام عنصر RestrictionTarget جديد في حال نجاحه. وإلا سيتم رفضها إذا أنشأت عددًا غير معقول من عناصر RestrictionTarget.

const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

على عكس العنصر، يمكن تسلسل عنصر RestrictionTarget. ويمكن تمريرها إلى مستند آخر باستخدام Window.postMessage()، على سبيل المثال.

تقييد

عند تسجيل علامة تبويب، يعرض مقطع الفيديو الرمز restrictTo(). عند التقاط علامة التبويب الحالية، يكون من الصحيح استدعاء restrictTo() باستخدام null أو أي RestrictionTarget مشتق من عنصر ضمن علامة التبويب الحالية.

طلبات restrictTo(restrictionTarget) لتحويل مسار الفيديو إلى لقطة من captureTarget، كما لو تم رسمها بنفسها، بغض النظر عن بقية عناصر DOM يتم أيضًا تسجيل أيّ نسل من captureTarget، ويتمّ استبعاد الأشقاء من captureTarget من عملية التسجيل. ونتيجةً لذلك، تظهر أيّ لقطات يتم عرضها على المقطع الصوتي كما لو تم اقتصاصها لتتلاءم مع حدود captureTarget، ويتمّ أيضًا إزالة أيّ محتوى يحجب الرؤية أو يتم حجبه.

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

طلبات restrictTo(null) لإعادة المقطع الصوتي إلى حالته الأصلية

// Stop restricting.
await track.restrictTo(null);

إذا نجحت المكالمة إلى restrictTo()، يتم حلّ الوعد الذي تم إرجاعه عندما يمكن ضمان أنّ جميع لقطات الفيديو اللاحقة ستقتصر على captureTarget.

وفي حال عدم نجاح المحاولة، يتم رفض الوعد. قد تؤدي إحدى الحالات التالية إلى عدم نجاح المكالمة إلى restrictTo():

  • إذا تم إنشاء restrictionTarget في علامة تبويب غير العلامة التي يتم التقاطها. (يُرجى العِلم أنّه باستخدام الزر "مشاركة علامة التبويب هذه بدلاً من ذلك"، يمكن للمستخدمين تغيير علامة التبويب التي يتم التقاطها في أي وقت).
  • إذا تمّ اشتقاق restrictionTarget من عنصر لم يعُد متوفّرًا.
  • إذا كان المقطع الصوتي يتضمّن نُسخًا طبق الأصل (راجِع المشكلة 1509418).
  • إذا لم يكن المقطع الصوتي الحالي مقطع فيديو تم تسجيله ذاتيًا
  • إذا كان العنصر الذي تم اشتقاق restrictionTarget منه غير مؤهّل للتقييد

اعتبارات حول الالتقاط الذاتي

عندما يطلب تطبيق getDisplayMedia() ويختار المستخدم التقاط علامة تبويب التطبيق، نُطلق على ذلك اسم "الالتقاط الذاتي".

تظهر طريقة restrictTo() في أي مقطع فيديو يتم تسجيله من علامة تبويب، وليس فقط في الفيديوهات التي يتم تسجيلها ذاتيًا. لا يمكن استخدام ميزة "التقاط العناصر" إلا لالتقاط الصور الذاتية في الوقت الحالي. لذلك، من المستحسن التحقّق مما إذا كان المستخدم قد اختار علامة التبويب الحالية قبل محاولة حظر المقطع الصوتي. ويمكن إجراء ذلك باستخدام Capture Handle. من الممكن أيضًا أن يطلب المتصفّح من المستخدم التقاط الصور الذاتية باستخدام preferCurrentTab.

الشفافية

لا تتضمّن لقطات الفيديو التي يحصل عليها التطبيق من خلال getDisplayMedia() قناة شفافة. إذا ضبط تطبيق هدفًا للتسجيل شفافًا جزئيًا، قد يؤدي إزالة قناة الشفافية إلى بعض النتائج المحتمَلة:

  • قد تتغيّر الألوان. قد تبدو العناصر المستهدَفة الشفافة جزئيًا والمرسومة على خلفية فاتحة أغمق عند إزالة قناة ألفا، وقد تبدو العناصر المرسومة على خلفية داكنة أفتح.
  • ستظهر الألوان التي كانت غير مرئية أو غير محسوسة للمستخدم عند ضبط قناة الشفافية على الحد الأقصى، بعد إزالة قناة الشفافية. على سبيل المثال، قد يؤدي ذلك إلى ظهور مناطق سوداء غير متوقّعة في اللقطات التي تم التقاطها، إذا كانت الأقسام الشفافة تحتوي على رمز RGBA rgba(0, 0, 0, 0).
لقطة شاشة لنتيجة استهداف الالتقاط الشفاف غير المستطيل
في بث الفيديو المستهدَف للتسجيل الشفاف غير المستطيل (على اليمين)، يكون الإطار المستطيل للخلفية السوداء يحتوي على دائرة زرقاء غير شفافة.

استهدافات الالتقاط غير المؤهّلة

من الممكن دائمًا بدء حظر مسار على أيّ هدف صالح لالتقاط المحتوى. ومع ذلك، لن يتم إنشاء الإطارات في حالات معيّنة، على سبيل المثال، إذا كان العنصر أو أحد الأسلاف هو display:none. والسبب المنطقي العام هو أنّ هذا التقييد لا ينطبق إلا على عنصر يتألف من منطقة مستطيلة ثنائية الأبعاد ومتماسكة واحدة يمكن تحديد وحدات البكسل فيها منطقيًا بشكل منفصل عن أي عناصر رئيسية أو عناصر شقيقة.

من العوامل المهمة التي يجب أخذها في الاعتبار لضمان أهلية العنصر للتقييد أنّه يجب أن يشكّل سياق تجميع خاصًا به. لضمان ذلك، يمكنك تحديد سمة CSS isolation، وضبطها على isolate.

<div id="captureTarget" style="isolation: isolate;"></iframe>

يُرجى العِلم أنّ العنصر المستهدَف يمكن أن يتبدّل بين أن يكون مؤهّلاً وغير مؤهّل للتقييد في أيّ وقت عشوائي، على سبيل المثال، إذا غيّر التطبيق سمات CSS. ويعود الأمر للتطبيق في استخدام استهدافات معقولة لتسجيل البيانات وتجنُّب تغيير خصائصها بشكل غير متوقّع. إذا أصبح العنصر المستهدَف غير مؤهَّل، لن يتم ببساطة عرض لقطات جديدة في المقطع الصوتي إلى أن يصبح العنصر المستهدَف مؤهَّلاً مرة أخرى للتقييد.

تفعيل ميزة "التقاط العناصر"

تتوفّر واجهة برمجة التطبيقات Element Capture API في Chrome على أجهزة الكمبيوتر المكتبي ضمن ميزة Element Capture التجريبية، ويمكن تفعيلها على العنوان chrome://flags/#element-capture.

ستتم أيضًا إتاحة هذه الميزة للتجربة من المصدر في الإصدار 121 من Chrome على أجهزة الكمبيوتر المكتبي، ما يتيح للمطوّرين تفعيل الميزة لزوّار مواقعهم الإلكترونية من أجل جمع البيانات من المستخدمين الفعليين. اطّلِع على البدء في استخدام الفترات التجريبية للإصدارات الأصلية للحصول على مزيد من المعلومات حول الفترات التجريبية للإصدارات الأصلية.

الأمان والخصوصية

لفهم المفاضلات الأمنية، اطّلِع على قسم الاعتبارات المتعلّقة بالخصوصية والأمان في مواصفات Element Capture.

يرسم متصفّح Chrome حدودًا زرقاء حول حواف علامات التبويب التي تم التقاطها.

عرض توضيحي

يمكنك تجربة ميزة "التقاط العناصر" من خلال تشغيل الإصدار التجريبي على Glitch. احرص على الاطّلاع على رمز المصدر.

ملاحظات

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

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

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

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

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

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

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

خدمات الإقرار

صورة Paul Skorupskas على Unsplash