HTML5 में ऑडियो और वीडियो कैप्चर करें

शुरुआती जानकारी

ऑडियो/वीडियो कैप्चर, लंबे समय से वेब डेवलपमेंट का "Holy Grail" रहा है. कई सालों से हमें इस काम को पूरा करने के लिए ब्राउज़र प्लग इन (फ़्लैश या सिल्वरलाइट) पर निर्भर रहना पड़ा था. चलिए, शुरू करते हैं!

HTML5 का इस्तेमाल करें. ऐसा हो सकता है कि यह साफ़ तौर पर न दिखे, लेकिन HTML5 के बढ़ने से डिवाइस के हार्डवेयर की ऐक्सेस में उछाल आया है. जियोलोकेशन (जीपीएस), Orientation API (एक्सलरोमीटर), WebGL (GPU), और वेब ऑडियो एपीआई (ऑडियो हार्डवेयर) इसका सटीक उदाहरण है. ये सुविधाएं बहुत ही ताकतवर हैं. इनमें हाई लेवल के JavaScript API शामिल हैं, जो सिस्टम की हार्डवेयर क्षमताओं के साथ-साथ सबसे ऊपर मौजूद हैं.

इस ट्यूटोरियल में, एक नए एपीआई GetUserMedia के बारे में बताया गया है, जो वेब ऐप्लिकेशन को उपयोगकर्ता के कैमरे और माइक्रोफ़ोन को ऐक्सेस करने की सुविधा देता है.

getUserMedia() की ओर जाने का रास्ता

अगर आपको इसके इतिहास के बारे में जानकारी नहीं है, तो हम getUserMedia() 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 मोबाइल 10.0
  • iOS6 Safari और Chrome (आंशिक सहायता)

दूसरा राउंड: डिवाइस एलिमेंट

कई लोगों को लगा कि एचटीएमएल मीडिया कैप्चर करने का दायरा काफ़ी सीमित हो रहा है. इसलिए, एक नया बदलाव आया, जो किसी भी तरह के (आने वाले समय में) डिवाइस के साथ काम करेगा. इसमें कोई हैरानी की बात नहीं है कि नए एलिमेंट, <device> एलिमेंट के लिए डिज़ाइन किया गया है, जो getUserMedia() का पहले वाला वर्शन बन गया.

Opera उन शुरुआती ब्राउज़र में से एक है जिन्होंने <device> एलिमेंट के आधार पर वीडियो कैप्चर को शुरुआती प्रोसेस में बनाया है. इसके तुरंत बाद (उसी दिन, सटीक होना चाहिए), WhatWG ने <device> टैग को स्क्रैप करने का फ़ैसला किया और अपने उपयोगकर्ता के लिए ऐसा किया. इस बार JavaScript API का नाम navigator.getUserMedia() था. एक हफ़्ते बाद, Opera ने नए बिल्ड रिलीज़ किए, जिनमें getUserMedia() की अपडेट की गई खास जानकारी से जुड़ी सहायता शामिल थी. उस साल के आखिर में, Microsoft नई स्पेसिफ़िकेशन को ध्यान में रखते हुए Lab for 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 के बाद से इस्तेमाल किया जा सकता है.

YouTube TV का इस्तेमाल शुरू करना

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> एलिमेंट शामिल नहीं कर रहे हैं. वीडियो को किसी मीडिया फ़ाइल का यूआरएल देने के बजाय, हम LocalMediaStream ऑब्जेक्ट पर srcObject को सेट कर रहे हैं. यह वेबकैम को दिखाने वाला होता है.

मैं <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);

ज़्यादा कॉन्फ़िगरेशन के लिए, Contraints 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 का अनुमति वाला डायलॉग बॉक्स है:

Chrome में अनुमति वाला डायलॉग बॉक्स
Chrome में अनुमति वाला डायलॉग बॉक्स

फ़ॉलबैक दिया जा रहा है

जिन लोगों के पास navigator.mediaDevices.getUserMedia() की सुविधा नहीं है उनके लिए एपीआई काम न करने और/या किसी वजह से कॉल काम नहीं कर पाने पर, एक विकल्प यह है कि वे किसी मौजूदा वीडियो फ़ाइल पर वापस जाएं:

if (!navigator.mediaDevices?.getUserMedia) {
  video.src = "fallbackvideo.webm";
} else {
  const stream = await navigator.mediaDevices.getUserMedia({ video: true });
  video.srcObject = stream;
}