परिचय
ऑडियो/वीडियो कैप्चर, वेब डेवलपमेंट के लिए लंबे समय से "सबसे ज़रूरी चीज़" रहा है. कई सालों तक, हमें ब्राउज़र प्लग इन (Flash या Silverlight) पर निर्भर रहना पड़ा. चलो!
HTML5 की मदद से. ऐसा हो सकता है कि आपको यह न पता हो, लेकिन HTML5 के आने से डिवाइस के हार्डवेयर को ऐक्सेस करने की संख्या में बढ़ोतरी हुई है. जियोलोकेशन (जीपीएस), ओरिएंटेशन एपीआई (ऐक्सेलेरोमीटर), WebGL (जीपीयू), और वेब ऑडियो एपीआई (ऑडियो हार्डवेयर) इसके बेहतरीन उदाहरण हैं. ये सुविधाएं काफ़ी असरदार हैं. इनकी मदद से, सिस्टम के हार्डवेयर की क्षमताओं के साथ काम करने वाले हाई लेवल JavaScript API का इस्तेमाल किया जा सकता है.
इस ट्यूटोरियल में, GetUserMedia नाम का एक नया एपीआई पेश किया गया है. इसकी मदद से, वेब ऐप्लिकेशन उपयोगकर्ता के कैमरे और माइक्रोफ़ोन को ऐक्सेस कर सकते हैं.
getUserMedia() का इस्तेमाल करने का तरीका
अगर आपको इसके इतिहास के बारे में नहीं पता है, तो getUserMedia()
API के बारे में जानना दिलचस्प होगा.
पिछले कुछ सालों में, "Media Capture API" के कई वैरिएंट लॉन्च किए गए हैं. कई लोगों ने वेब पर नेटिव डिवाइसों को ऐक्सेस करने की ज़रूरत को समझा, लेकिन इससे सभी ने एक नई खास जानकारी इकट्ठा की. मामला इतना बिगड़ गया कि W3C ने आखिरकार एक वर्किंग ग्रुप बनाने का फ़ैसला लिया. क्या इसका एक ही मकसद है? इस पागलपन को समझें! डिवाइस एपीआई नीति (डीएपी) वर्किंग ग्रुप को, कई प्रस्तावों को एक साथ जोड़ने और उन्हें स्टैंडर्ड बनाने का काम सौंपा गया है.
मैं 2011 में हुई घटनाओं के बारे में खास जानकारी देने की कोशिश करूंगा…
पहला राउंड: एचटीएमएल मीडिया कैप्चर
एचटीएमएल मीडिया कैप्चर, वेब पर मीडिया कैप्चर को स्टैंडर्ड बनाने के लिए, डीएपी की पहली कोशिश थी. यह <input type="file">
को ओवरलोड करके काम करता है और accept
पैरामीटर के लिए नई वैल्यू जोड़ता है.
अगर आपको उपयोगकर्ताओं को वेबकैम से अपना स्नैपशॉट लेने की अनुमति देनी है, तो capture=camera
की मदद से ऐसा किया जा सकता है:
<input type="file" accept="image/*;capture=camera">
वीडियो या ऑडियो रिकॉर्ड करने का तरीका एक जैसा है:
<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">
अच्छा है, है ना? मुझे खास तौर पर यह पसंद है कि यह फ़ाइल इनपुट का फिर से इस्तेमाल करता है. सेमेटिक के हिसाब से,
यह बहुत सही है. इस "एपीआई" की कमी यह है कि यह रीयल टाइम इफ़ेक्ट नहीं दे पाता. उदाहरण के लिए, लाइव वेबकैम डेटा को <canvas>
में रेंडर करना और WebGL फ़िल्टर लागू करना.
एचटीएमएल मीडिया कैप्चर की मदद से, सिर्फ़ मीडिया फ़ाइल रिकॉर्ड की जा सकती है या समय-समय पर स्नैपशॉट लिया जा सकता है.
सहायता:
- Android 3.0 ब्राउज़र - यह सुविधा सबसे पहले यहां लागू की गई थी. इसका उदाहरण देखने के लिए, यह वीडियो देखें.
- Android के लिए Chrome (0.16)
- Firefox Mobile 10.0
- iOS6 Safari और Chrome (कुछ हद तक काम करता है)
दूसरा राउंड: डिवाइस एलिमेंट
कई लोगों को लगता था कि HTML Media Capture की सुविधा काफ़ी सीमित है. इसलिए, एक नई सुविधा का उदय हुआ, जो आने वाले समय में किसी भी तरह के डिवाइस के साथ काम करती है. इसलिए, यह कोई हैरानी की बात नहीं है कि डिज़ाइन के लिए एक नए एलिमेंट, <device>
एलिमेंट की ज़रूरत पड़ी. यह एलिमेंट, getUserMedia()
का पूर्ववर्ती एलिमेंट बन गया.
Opera, उन पहले ब्राउज़र में से एक था जिसने <device>
एलिमेंट के आधार पर, वीडियो कैप्चर करने की सुविधा को शुरुआती तौर पर लागू किया था. इसके कुछ समय बाद (उसी दिन), WhatWG ने <device>
टैग को हटाने का फ़ैसला लिया. इसकी जगह, एक नए टैग को इस्तेमाल करने का फ़ैसला लिया गया. यह टैग, navigator.getUserMedia()
नाम का JavaScript API था. एक हफ़्ते बाद, Opera ने नए बिल्ड रिलीज़ किए. इनमें अपडेट किए गए getUserMedia()
स्पेसिफ़िकेशन के लिए सहायता शामिल थी. उस साल के आखिर में, Microsoft ने नए स्पेसिफ़िकेशन के साथ काम करने वाला IE9 के लिए लैब रिलीज़ करके इस पार्टी में शामिल हुआ.
<device>
इस तरह दिखता:
<device type="media" onchange="update(this.data)"></device>
<video autoplay></video>
<script>
function update(stream) {
document.querySelector('video').src = stream.url;
}
</script>
सहायता:
माफ़ करें, रिलीज़ किए गए किसी भी ब्राउज़र में <device>
शामिल नहीं है.
मुझे लगता है कि अब एक एपीआई कम हो गया है :) हालांकि, <device>
में दो बेहतर चीज़ें थीं: 1.) यह सेमैंटिक था और 2.) इसे आसानी से ऑडियो/वीडियो डिवाइसों के अलावा, और भी डिवाइसों के साथ काम करने के लिए बढ़ाया जा सकता था.
गहरी सांस लें. यह चीज़ तेज़ी से चलती है!
तीसरा राउंड: WebRTC
<device>
एलिमेंट का इस्तेमाल अब नहीं किया जाता.
WebRTC (वेब रीयल टाइम कम्यूनिकेशन) की मदद से, कैप्चर करने के लिए सही एपीआई ढूंढने की प्रोसेस तेज़ हो गई है. इस स्पेसिफ़िकेशन को W3C WebRTC वर्किंग ग्रुप देखता है. Google, Opera, Mozilla, और कुछ अन्य ब्राउज़र में यह सुविधा लागू है.
getUserMedia()
, WebRTC से जुड़ा है, क्योंकि यह एपीआई के उस सेट का गेटवे है.
इससे उपयोगकर्ता के डिवाइस के कैमरे/माइक्रोफ़ोन की स्ट्रीम को ऐक्सेस किया जा सकता है.
सहायता:
getUserMedia()
, Chrome 21, Opera 18, और Firefox 17 से काम करता है.
शुरू करना
navigator.mediaDevices.getUserMedia()
की मदद से, अब हम प्लग इन के बिना वेबकैम और माइक्रोफ़ोन इनपुट का इस्तेमाल कर सकते हैं.
अब कैमरे का ऐक्सेस पाने के लिए, ऐप्लिकेशन इंस्टॉल करने की ज़रूरत नहीं है. यह सीधे ब्राउज़र में बनता है. क्या आप अब भी उत्साहित हैं?
फ़ीचर का पता लगाना
सुविधा का पता लगाने की सुविधा, navigator.mediaDevices.getUserMedia
की मौजूदगी की जांच करने का एक आसान तरीका है:
if (navigator.mediaDevices?.getUserMedia) {
// Good to go!
} else {
alert("navigator.mediaDevices.getUserMedia() is not supported");
}
इनपुट डिवाइस का ऐक्सेस पाना
वेबकैम या माइक्रोफ़ोन का इस्तेमाल करने के लिए, हमें अनुमति का अनुरोध करना होगा.
navigator.mediaDevices.getUserMedia()
का पहला पैरामीटर एक ऑब्जेक्ट होता है, जिसमें हर उस तरह के मीडिया की जानकारी और ज़रूरी शर्तें बताई जाती हैं जिसे आपको ऐक्सेस करना है. उदाहरण के लिए, अगर आपको वेबकैम ऐक्सेस करना है, तो पहला पैरामीटर {video: true}
होना चाहिए. माइक्रोफ़ोन और कैमरे, दोनों का इस्तेमाल करने के लिए,
{video: true, audio: true}
को अनुमति दें:
<video autoplay></video>
<script>
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((localMediaStream) => {
const video = document.querySelector("video");
video.srcObject = localMediaStream;
})
.catch((error) => {
console.log("Rejected!", error);
});
</script>
ठीक है। तो यहां क्या हो रहा है? मीडिया कैप्चर, एक साथ काम करने वाले नए HTML5 API का एक बेहतरीन उदाहरण है. यह हमारे अन्य HTML5 एट्रिब्यूट, <audio>
और <video>
के साथ काम करता है.
ध्यान दें कि हम src
एट्रिब्यूट को सेट नहीं कर रहे हैं या <video>
एलिमेंट पर <source>
एलिमेंट शामिल नहीं कर रहे हैं. वीडियो में मीडिया फ़ाइल का यूआरएल डालने के बजाय, हम srcObject
को वेबकैम को दिखाने वाले LocalMediaStream
ऑब्जेक्ट पर सेट कर रहे हैं.
मैंने <video>
को autoplay
पर भी सेट किया है, नहीं तो यह पहले फ़्रेम पर फ़्रीज़ हो जाएगा. controls
जोड़ने पर भी, आपको उम्मीद के मुताबिक नतीजे मिलेंगे.
मीडिया की पाबंदियां (रिज़ॉल्यूशन, ऊंचाई, चौड़ाई) सेट करना
getUserMedia()
के पहले पैरामीटर का इस्तेमाल, रिटर्न की गई मीडिया स्ट्रीम के लिए ज़्यादा ज़रूरी शर्तें (या पाबंदियां) तय करने के लिए भी किया जा सकता है. उदाहरण के लिए, सिर्फ़ यह बताने के बजाय कि आपको वीडियो का बुनियादी ऐक्सेस चाहिए (उदाहरण के लिए, {video: true}
), आपके पास स्ट्रीम को एचडी में दिखाने की ज़रूरी शर्त जोड़ने का विकल्प भी होता है:
const hdConstraints = {
video: { width: { exact: 1280} , height: { exact: 720 } },
};
const stream = await navigator.mediaDevices.getUserMedia(hdConstraints);
const vgaConstraints = {
video: { width: { exact: 640} , height: { exact: 360 } },
};
const stream = await navigator.mediaDevices.getUserMedia(hdConstraints);
ज़्यादा कॉन्फ़िगरेशन के लिए, constraints API देखें.
मीडिया सोर्स चुनना
MediaDevices
इंटरफ़ेस के enumerateDevices()
तरीके से, उपलब्ध मीडिया इनपुट और आउटपुट डिवाइसों की सूची का अनुरोध किया जाता है. जैसे, माइक्रोफ़ोन, कैमरे, हेडसेट वगैरह. लौटाए गए प्रॉमिस को, डिवाइसों के बारे में बताने वाले MediaDeviceInfo
ऑब्जेक्ट के कलेक्शन के साथ रिज़ॉल्व किया जाता है.
इस उदाहरण में, आखिरी माइक्रोफ़ोन और कैमरे को मीडिया स्ट्रीम के सोर्स के तौर पर चुना गया है:
if (!navigator.mediaDevices?.enumerateDevices) {
console.log("enumerateDevices() not supported.");
} else {
// List cameras and microphones.
navigator.mediaDevices
.enumerateDevices()
.then((devices) => {
let audioSource = null;
let videoSource = null;
devices.forEach((device) => {
if (device.kind === "audioinput") {
audioSource = device.deviceId;
} else if (device.kind === "videoinput") {
videoSource = device.deviceId;
}
});
sourceSelected(audioSource, videoSource);
})
.catch((err) => {
console.error(`${err.name}: ${err.message}`);
});
}
async function sourceSelected(audioSource, videoSource) {
const constraints = {
audio: { deviceId: audioSource },
video: { deviceId: videoSource },
};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
}
उपयोगकर्ताओं को मीडिया सोर्स चुनने की अनुमति देने का तरीका जानने के लिए, सैम डटन का शानदार डेमो देखें.
सुरक्षा
navigator.mediaDevices.getUserMedia()
को कॉल करने पर, ब्राउज़र एक अनुमति वाला डायलॉग बॉक्स दिखाते हैं. इससे उपयोगकर्ताओं को अपने कैमरे/माइक का ऐक्सेस देने या न देने का विकल्प मिलता है. उदाहरण के लिए, यहां Chrome का अनुमति डायलॉग है:
फ़ॉलबैक उपलब्ध कराना
जिन उपयोगकर्ताओं के डिवाइस पर navigator.mediaDevices.getUserMedia()
काम नहीं करता उनके लिए, किसी मौजूदा वीडियो फ़ाइल पर फ़ॉलबैक करने का विकल्प है. ऐसा तब किया जा सकता है, जब एपीआई काम न करता हो और/या किसी वजह से कॉल पूरा न हो पाता हो:
if (!navigator.mediaDevices?.getUserMedia) {
video.src = "fallbackvideo.webm";
} else {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
}