किसी भी एलिमेंट से वीडियो स्ट्रीम कैप्चर करें

François Beaufort
François Beaufort

स्क्रीन कैप्चर एपीआई की मदद से, मौजूदा टैब को पूरा कैप्चर किया जा सकता है. Element Capture API की मदद से, किसी खास एचटीएमएल एलिमेंट को कैप्चर और रिकॉर्ड किया जा सकता है. यह पूरे टैब के कैप्चर को किसी खास DOM सबट्री के कैप्चर में बदल देता है. इसमें सिर्फ़ टारगेट-एलिमेंट के डायरेक्ट डिससेंडेंट को कैप्चर किया जाता है. दूसरे शब्दों में, यह ओकुलेड और ओकुलेड कॉन्टेंट, दोनों को काटकर हटा देता है.

एलिमेंट कैप्चर का इस्तेमाल क्यों करना चाहिए?

वीडियो कॉन्फ़्रेंसिंग ऐप्लिकेशन की ज़रूरी शर्तों को ध्यान में रखकर, यह समझा जा सकता है कि एलिमेंट कैप्चर की सुविधा कहां काम की है. अगर आपके पास कोई ऐसा वीडियो कॉन्फ़्रेंसिंग ऐप्लिकेशन है जिसकी मदद से, तीसरे पक्ष के ऐप्लिकेशन को iframe में जोड़ा जा सकता है, तो हो सकता है कि कभी-कभी आपको उस iframe को वीडियो के तौर पर कैप्चर करके, रिमोट से जुड़े लोगों को भेजना हो.

Chrome में वीडियो-कॉन्फ़्रेंसिंग कॉल का स्क्रीनशॉट.
एलाद, फ़्रांकोइस के साथ वीडियो कॉन्फ़्रेंसिंग कॉल में तीसरे पक्ष के ऐप्लिकेशन का इस्तेमाल करता है.

getDisplayMedia() को कॉल करके, उपयोगकर्ता को मौजूदा टैब चुनने की अनुमति देने पर, मौजूदा टैब का पूरा डेटा ट्रांसफ़र हो जाएगा. ऐसा होने पर, लोगों को उनका वीडियो वापस दिख सकता है. इमेज का हिस्सा कैप्चर करें सुविधा का इस्तेमाल करके, इसे काटा जा सकता है.

हालांकि, अगर प्रज़ेंटर वीडियो कॉन्फ़्रेंसिंग ऐप्लिकेशन का इस्तेमाल करता है और कैप्चर किए जाने वाले कॉन्टेंट के ऊपर ड्रॉप-डाउन सूची जैसा कोई कॉन्टेंट दिखता है, तो क्या होगा?

कैप्चर किए जाने वाले कॉन्टेंट को कवर करने वाली ड्रॉप-डाउन सूची का स्क्रीनशॉट.
कैप्चर किए जाने वाले कॉन्टेंट के ऊपर एक ड्रॉप-डाउन सूची दिखती है.

ऐसे में, रीजन कैप्चर की सुविधा काम नहीं करेगी. ऐसा हो सकता है कि ड्रॉप-डाउन सूची का कुछ हिस्सा, मीटिंग में शामिल होने वाले उन लोगों की स्क्रीन पर दिखे जो मीटिंग में रिमोट से शामिल हैं.

कैप्चर की गई ड्रॉप-डाउन सूची का स्क्रीनशॉट.
एलाद की ड्रॉप-डाउन सूची, फ़्रांकोइस को मिले कॉन्टेंट के ऊपर दिखती है.

रीजन कैप्चर की सुविधा, एलिमेंट के कुछ हिस्सों को इस तरह कैप्चर करती है. इसे कॉन्टेंट को छिपाना कहा जाता है. इससे कई समस्याएं आती हैं:

  • कॉन्टेंट को छिपाने से, वह कॉन्टेंट नहीं दिख सकता जिसे शेयर करना है.
  • छिपाया गया कॉन्टेंट निजी हो सकता है. जैसे, चैट की सूचनाएं.
  • कॉन्टेंट को छिपाने से भ्रम की स्थिति पैदा हो सकती है. (उदाहरण के लिए, ऐप्लिकेशन का री-लेआउट करने पर, रिमोट से मीटिंग में शामिल लोगों के वीडियो, कैप्चर किए गए टारगेट पर कुछ समय के लिए दिख सकते हैं.)

Element Capture API, आपको उस एलिमेंट को टारगेट करने की सुविधा देता है जिसे आपको शेयर करना है. इससे, इन सभी समस्याओं को हल किया जा सकता है.

टारगेट एलिमेंट का स्क्रीनशॉट, जिसमें व्यू में कोई ड्रॉपडाउन सूची नहीं है.
फ़्रैंस्वा को एलाद की ड्रॉप-डाउन सूची नहीं दिखती.

मैं Element Capture का इस्तेमाल कैसे करूं?

captureTarget आपके पेज पर मौजूद एक एलिमेंट है. इसमें वह कॉन्टेंट होता है जिसे उपयोगकर्ता कैप्चर करना चाहता है. आपको वीडियो कॉन्फ़्रेंसिंग के वेब ऐप्लिकेशन से captureTarget कैप्चर करके, अलग-अलग जगहों से कॉल में जुड़े लोगों के साथ शेयर करना है. इसलिए, आपको captureTarget से RestrictionTarget मिलता है. इस RestrictionTarget का इस्तेमाल करके वीडियो ट्रैक पर पाबंदी लगाने के बाद, उस वीडियो ट्रैक के फ़्रेम में सिर्फ़ वे पिक्सल शामिल होते हैं जो captureTarget और उसके डायरेक्ट डीओएम डिसेंटेंट का हिस्सा होते हैं.

अगर 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 के कैप्चर में बदल दिया जाता है. ऐसा लगता है कि इसे बाकी डीओएम से अलग, अपने-आप ड्रॉ किया गया है. 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() तरीका, सिर्फ़ सेल्फ़-कैप्चर के लिए नहीं, बल्कि किसी भी टैब-कैप्चर वीडियो ट्रैक पर लागू होता है. हालांकि, फ़िलहाल एलिमेंट कैप्चर की सुविधा सिर्फ़ अपने-आप कैप्चर करने के लिए चालू है. इसलिए, हमारा सुझाव है कि ट्रैक पर पाबंदी लगाने से पहले, यह देख लें कि उपयोगकर्ता ने मौजूदा टैब को चुना है या नहीं. कैप्चर हैंडल का इस्तेमाल करके, ऐसा किया जा सकता है. preferCurrentTab का इस्तेमाल करके, ब्राउज़र से उपयोगकर्ता को खुद की फ़ोटो लेने के लिए कहा जा सकता है.

पारदर्शिता

getDisplayMedia() से ऐप्लिकेशन को मिलने वाले वीडियो फ़्रेम में, कोई अल्फा चैनल शामिल नहीं होता. अगर कोई ऐप्लिकेशन, कुछ हद तक पारदर्शी कैप्चर-टारगेट सेट करता है, तो अल्फा चैनल को हटाने से कुछ संभावित नतीजे हो सकते हैं:

  • रंग बदल सकते हैं. हल्के बैकग्राउंड पर बनाए गए कुछ पारदर्शी टारगेट-एलिमेंट, अल्फा चैनल हटाने पर गहरे रंग के दिख सकते हैं. वहीं, गहरे बैकग्राउंड पर बनाए गए टारगेट-एलिमेंट, हल्के रंग के दिख सकते हैं.
  • जब अल्फा चैनल को ज़्यादा से ज़्यादा पर सेट किया गया था, तब उपयोगकर्ता को जो रंग नहीं दिख रहे थे या जो रंगों को पहचानने में मुश्किल हो रही थी वे अल्फा चैनल हटाने के बाद दिखेंगे. उदाहरण के लिए, अगर पारदर्शी सेक्शन में RGBA कोड rgba(0, 0, 0, 0) है, तो कैप्चर किए गए फ़्रेम में अनचाहे काले हिस्से दिख सकते हैं.
ऐसे कैप्चर टारगेट के नतीजे का स्क्रीनशॉट जो आयताकार नहीं है और पारदर्शी है.
रेक्टैंगल के बजाय ट्रांसफ़ैरेंट कैप्चर टारगेट वीडियो स्ट्रीम (दाईं ओर) एक ब्लैक बैकग्राउंड रेक्टैंगल है, जिसमें एक अपारदर्शी नीला सर्कल है.

कैप्चर करने के लिए अमान्य टारगेट

किसी भी मान्य कैप्चर-टारगेट के लिए, किसी ट्रैक पर पाबंदी लगाई जा सकती है. हालांकि, कुछ स्थितियों में फ़्रेम नहीं बनाए जाएंगे. उदाहरण के लिए, अगर एलिमेंट या कोई पैरंट एलिमेंट display:none है. आम तौर पर, यह पाबंदी सिर्फ़ उस एलिमेंट पर लागू होती है जिसमें एक ही तरह का, दो डाइमेंशन वाला, आयताकार एरिया हो. साथ ही, उसके पिक्सल को किसी पैरंट या सिबलिंग एलिमेंट से अलग करके तय किया जा सकता हो.

किसी एलिमेंट पर पाबंदी लगाने से पहले, यह पक्का करना ज़रूरी है कि वह एलिमेंट अपना स्टैकिंग कॉन्टेक्स्ट बनाता हो. यह पक्का करने के लिए, अलग-अलग सीएसएस प्रॉपर्टी की जानकारी दें और उसे isolate पर सेट करें.

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

ध्यान दें कि टारगेट एलिमेंट, किसी भी समय पाबंदी के लिए ज़रूरी शर्तें पूरी करने और पूरी न करने के बीच टॉगल कर सकता है. उदाहरण के लिए, अगर ऐप्लिकेशन अपनी सीएसएस प्रॉपर्टी बदलता है. यह ऐप्लिकेशन के ऊपर है कि वह कैप्चर करने के लिए सही टारगेट का इस्तेमाल करे और अपनी प्रॉपर्टी में अचानक बदलाव न करे. अगर टारगेट एलिमेंट ज़रूरी शर्तें पूरी नहीं करता है, तो ट्रैक पर नए फ़्रेम तब तक नहीं भेजे जाएंगे, जब तक टारगेट एलिमेंट फिर से पाबंदी के लिए ज़रूरी शर्तें पूरी नहीं कर लेता.

एलिमेंट कैप्चर की सुविधा चालू करना

Element Capture API, Chrome के डेस्कटॉप वर्शन में Element Capture फ़्लैग के पीछे उपलब्ध है. इसे chrome://flags/#element-capture पर जाकर चालू किया जा सकता है.

यह सुविधा डेस्कटॉप पर Chrome 121 से ऑरिजिन ट्रायल में भी शामिल है. इससे डेवलपर, अपनी साइटों पर आने वाले लोगों के लिए इस सुविधा को चालू कर सकते हैं, ताकि वे असली उपयोगकर्ताओं का डेटा इकट्ठा कर सकें. ऑरिजिन ट्रायल के बारे में ज़्यादा जानने के लिए, ऑरिजिन ट्रायल का इस्तेमाल शुरू करना लेख पढ़ें.

सुरक्षा और निजता

सुरक्षा से जुड़े समझौते को समझने के लिए, एलिमेंट कैप्चर स्पेसिफ़िकेशन का निजता और सुरक्षा से जुड़ी बातें सेक्शन देखें.

Chrome ब्राउज़र, कैप्चर किए गए टैब के किनारों पर नीला बॉर्डर बनाता है.

डेमो

Glitch पर डेमो चलाकर, Element Capture का इस्तेमाल किया जा सकता है. सोर्स कोड देखना न भूलें.

सुझाव/राय दें या शिकायत करें

Chrome की टीम और वेब स्टैंडर्ड कम्यूनिटी, एलिमेंट कैप्चर के बारे में आपके अनुभव जानना चाहती है.

हमें डिज़ाइन के बारे में बताएं

क्या रीजन कैप्चर की सुविधा आपकी उम्मीद के मुताबिक काम नहीं कर रही है? क्या आपके आइडिया को लागू करने के लिए, कोई तरीका या प्रॉपर्टी मौजूद नहीं है? क्या आपको सुरक्षा मॉडल के बारे में कोई सवाल पूछना है या कोई टिप्पणी करनी है?

  • GitHub repo पर, खास जानकारी से जुड़ी समस्या दर्ज करें या किसी मौजूदा समस्या में अपने सुझाव जोड़ें.

क्या लागू करने में समस्या आ रही है?

क्या आपको Chrome में इस सुविधा को लागू करने में कोई गड़बड़ी मिली? या क्या इसे लागू करने का तरीका, खास जानकारी से अलग है?

  • https://new.crbug.com पर जाकर, गड़बड़ी की शिकायत करें. इसमें ज़्यादा से ज़्यादा जानकारी शामिल करें. साथ ही, गड़बड़ी को दोहराने के लिए आसान निर्देश दें. Glitch, तुरंत और आसानी से समस्या की जानकारी शेयर करने के लिए बहुत अच्छा है.

लोगों का आभार

Unsplash पर पॉल स्कोर्पस्कस की फ़ोटो