परिचय
ऑडियो/वीडियो कैप्चर करना, लंबे समय से वेब डेवलपमेंट का सबसे अहम हिस्सा रहा है. पिछले कई सालों से, हमें ब्राउज़र प्लगिन (Flash या Silverlight) पर निर्भर रहना पड़ा है. चलो!
HTML5 की मदद से. यह साफ़ तौर पर नहीं दिखता, लेकिन HTML5 के इस्तेमाल से डिवाइस के हार्डवेयर को ऐक्सेस करने की सुविधा मिली है. जियोलोकेशन (जीपीएस), ओरिएंटेशन एपीआई (ऐक्सिलरोमीटर), WebGL (जीपीयू), और Web Audio API (ऑडियो हार्डवेयर) इसके बेहतरीन उदाहरण हैं. ये सुविधाएं बहुत काम की हैं. ये ऐसे हाई लेवल JavaScript API उपलब्ध कराती हैं जो सिस्टम के हार्डवेयर की बुनियादी सुविधाओं के साथ काम करते हैं.
इस ट्यूटोरियल में, एक नए एपीआई, GetUserMedia के बारे में बताया गया है. इसकी मदद से, वेब ऐप्लिकेशन किसी व्यक्ति के कैमरे और माइक्रोफ़ोन को ऐक्सेस कर सकते हैं.
getUserMedia() तक पहुंचने का तरीका
अगर आपको इसके इतिहास के बारे में नहीं पता है, तो getUserMedia()
API तक पहुंचने का हमारा सफ़र काफ़ी दिलचस्प है.
पिछले कुछ सालों में, "Media Capture APIs" के कई वर्शन उपलब्ध कराए गए हैं. कई लोगों ने वेब पर नेटिव डिवाइसों को ऐक्सेस करने की ज़रूरत को समझा. हालांकि, इसकी वजह से हर किसी ने एक नया स्पेसिफ़िकेशन तैयार कर लिया. चीज़ें इतनी उलझ गईं कि W3C ने आखिरकार एक वर्किंग ग्रुप बनाने का फ़ैसला किया. इनका मुख्य मकसद क्या है? इस पागलपन को समझें! डिवाइस एपीआई से जुड़ी नीति (डीएपी) वर्किंग ग्रुप को कई तरह के सुझावों को एक साथ लाने और उन्हें स्टैंडर्ड बनाने का काम सौंपा गया है.
मैं 2011 में हुई घटनाओं के बारे में खास जानकारी देने की कोशिश करूंगा…
पहला राउंड: एचटीएमएल मीडिया कैप्चर
एचटीएमएल मीडिया कैप्चर, वेब पर मीडिया कैप्चर करने की प्रोसेस को स्टैंडर्ड बनाने के लिए, DAP का पहला प्रयास था. यह <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 (कुछ हद तक काम करता है)
दूसरा राउंड: डिवाइस एलिमेंट
कई लोगों को लगता था कि एचटीएमएल मीडिया कैप्चर की सुविधा बहुत सीमित है. इसलिए, एक नया स्पेसिफ़िकेशन तैयार किया गया. यह स्पेसिफ़िकेशन, आने वाले समय में उपलब्ध होने वाले किसी भी डिवाइस के साथ काम कर सकता है. इसमें कोई हैरानी नहीं है कि डिज़ाइन के लिए एक नए एलिमेंट, <device>
एलिमेंट की ज़रूरत पड़ी. यह getUserMedia()
का पूर्ववर्ती बन गया.
Opera, <device>
एलिमेंट पर आधारित वीडियो कैप्चर की शुरुआती सुविधाएं देने वाले पहले ब्राउज़र में से एक था. इसके कुछ समय बाद (उसी दिन), WhatWG ने <device>
टैग को बंद करने का फ़ैसला किया. इसके बजाय, उसने JavaScript API navigator.getUserMedia()
को इस्तेमाल करने का फ़ैसला किया. एक हफ़्ते बाद, Opera ने नए बिल्ड जारी किए. इनमें अपडेट किए गए getUserMedia()
स्पेसिफ़िकेशन के लिए सहायता शामिल थी. बाद में, Microsoft ने भी इस स्पेसिफ़िकेशन के साथ IE9 के लिए Lab जारी किया.
<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>
के साथ मिलकर काम करता है.
ध्यान दें कि हम <video>
एलिमेंट पर src
एट्रिब्यूट सेट नहीं कर रहे हैं या <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()
तरीका, उपलब्ध मीडिया इनपुट और आउटपुट डिवाइसों की सूची का अनुरोध करता है. जैसे, माइक्रोफ़ोन, कैमरे, हेडसेट वगैरह. वापस किया गया Promise, 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;
}