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

François Beaufort
François Beaufort

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

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

يمكن أن يساعدك التفكير في متطلبات تطبيق مؤتمرات الفيديو في فهم الحالات التي تكون فيها ميزة "التقاط العناصر" مفيدة. إذا كان لديك تطبيق لعقد مؤتمرات الفيديو يتيح لك تضمين تطبيقات خارجية في إطار 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). سيتم حلّ Promise الذي تم إرجاعه باستخدام عنصر 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()، يتم حلّ Promise الذي تم عرضه عندما يمكن ضمان أنّ جميع لقطات الفيديو اللاحقة ستقتصر على captureTarget.

وفي حال عدم النجاح، يتم رفض Promise. سيكون سبب عدم نجاح طلب restrictTo() أحد الأسباب التالية:

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

اعتبارات التسجيل الذاتي

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

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

الشفافية

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

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

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

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

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

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

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

دعم المتصفح

تتوفّر ميزة "التقاط العناصر" من الإصدار 132 من Chrome على أجهزة الكمبيوتر المكتبي فقط.

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

للتعرّف على المفاضلات بين الأمان والخصوصية، يمكنك الاطّلاع على قسم اعتبارات الخصوصية والأمان في مواصفات "التقاط العناصر".

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

عرض توضيحي

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

الملاحظات

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

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

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

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

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

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

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

كلمة شكر

صورة Paul Skorupskas على Unsplash