उपयोगकर्ता का ऑडियो रिकॉर्ड कर रहा है

अब कई ब्राउज़र, उपयोगकर्ता से वीडियो और ऑडियो इनपुट ऐक्सेस कर सकते हैं. हालांकि, ब्राउज़र के हिसाब से, यह पूरी तरह से डाइनैमिक और इनलाइन अनुभव हो सकता है. इसके अलावा, इसे उपयोगकर्ता के डिवाइस पर किसी दूसरे ऐप्लिकेशन को भी सौंपा जा सकता है.

आसानी से और धीरे-धीरे शुरू करें

सबसे आसान तरीका यह है कि उपयोगकर्ता से पहले से रिकॉर्ड की गई फ़ाइल मांगी जाए. ऐसा करने के लिए, एक आसान फ़ाइल इनपुट एलिमेंट बनाएं. साथ ही, एक accept फ़िल्टर जोड़ें, जिससे पता चलता हो कि हम सिर्फ़ ऑडियो फ़ाइलें स्वीकार कर सकते हैं. इसके अलावा, एक capture एट्रिब्यूट जोड़ें, जिससे पता चलता हो कि हमें इसे सीधे माइक्रोफ़ोन से चाहिए.

<input type="file" accept="audio/*" capture />

यह तरीका सभी प्लैटफ़ॉर्म पर काम करता है. डेस्कटॉप पर, यह उपयोगकर्ता से फ़ाइल सिस्टम से कोई फ़ाइल अपलोड करने के लिए कहेगा. इसमें capture एट्रिब्यूट को अनदेखा किया जाएगा. iOS पर Safari में, यह माइक्रोफ़ोन ऐप्लिकेशन खोलेगा. इससे, ऑडियो रिकॉर्ड करके उसे वेब पेज पर भेजा जा सकता है. Android पर, यह उपयोगकर्ता को यह चुनने का विकल्प देगा कि वेब पेज पर भेजने से पहले, ऑडियो को किस ऐप्लिकेशन से रिकॉर्ड करना है.

जब उपयोगकर्ता रिकॉर्डिंग पूरी कर लेता है और वह वेबसाइट पर वापस आ जाता है, तो आपको किसी तरह से फ़ाइल का डेटा हासिल करना होगा. इनपुट एलिमेंट में onchange इवेंट अटैच करके और फिर इवेंट ऑब्जेक्ट की files प्रॉपर्टी पढ़कर, तुरंत ऐक्सेस किया जा सकता है.

<input type="file" accept="audio/*" capture id="recorder" />
<audio id="player" controls></audio>
  <script>
    const recorder = document.getElementById('recorder');
    const player = document.getElementById('player');

    recorder.addEventListener('change', function (e) {
      const file = e.target.files[0];
      const url = URL.createObjectURL(file);
      // Do something with the audio file.
      player.src = url;
    });
  </script>
</audio>

फ़ाइल का ऐक्सेस मिलने के बाद, उसमें अपनी पसंद के मुताबिक बदलाव किए जा सकते हैं. उदाहरण के लिए, ये काम किए जा सकते हैं:

  • इसे सीधे किसी <audio> एलिमेंट से अटैच करें, ताकि इसे चलाया जा सके
  • उसे उपयोगकर्ता के डिवाइस पर डाउनलोड करें
  • इसे XMLHttpRequest से अटैच करके, सर्वर पर अपलोड करें
  • इसे Web Audio API के ज़रिए पास करें और उस पर फ़िल्टर लागू करें

ऑडियो डेटा का ऐक्सेस पाने के लिए, इनपुट एलिमेंट का तरीका हर जगह इस्तेमाल किया जाता है. हालांकि, यह सबसे कम पसंदीदा विकल्प है. हम माइक्रोफ़ोन का ऐक्सेस पाना चाहते हैं, ताकि हम सीधे पेज पर ही बेहतर अनुभव दे सकें.

इंटरैक्टिव तरीके से माइक्रोफ़ोन ऐक्सेस करना

आधुनिक ब्राउज़र में माइक्रोफ़ोन से सीधे तौर पर कनेक्ट करने की सुविधा होती है. इससे, हम ऐसे अनुभव बना सकते हैं जो वेब पेज के साथ पूरी तरह से इंटिग्रेट होते हैं और उपयोगकर्ता कभी भी ब्राउज़र से बाहर नहीं निकलता.

माइक्रोफ़ोन का ऐक्सेस पाना

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

अगर एपीआई काम करता है, तो वह एक Stream दिखाएगा. इसमें कैमरे या माइक्रोफ़ोन का डेटा होगा. इसके बाद, हम इसे <audio> एलिमेंट, WebRTC स्ट्रीम या वेब ऑडियो AudioContext से अटैच कर सकते हैं. इसके अलावा, MediaRecorder एपीआई का इस्तेमाल करके इसे सेव भी किया जा सकता है.

माइक्रोफ़ोन से डेटा पाने के लिए, हम getUserMedia() एपीआई को भेजे गए constraints ऑब्जेक्ट में audio: true सेट करते हैं.

<audio id="player" controls></audio>
<script>
  const player = document.getElementById('player');

  const handleSuccess = function (stream) {
    if (window.URL) {
      player.srcObject = stream;
    } else {
      player.src = stream;
    }
  };

  navigator.mediaDevices
    .getUserMedia({audio: true, video: false})
    .then(handleSuccess);
</script>

अगर आपको कोई खास माइक्रोफ़ोन चुनना है, तो पहले उपलब्ध माइक्रोफ़ोन की सूची देखें.

navigator.mediaDevices.enumerateDevices().then((devices) => {
  devices = devices.filter((d) => d.kind === 'audioinput');
});

इसके बाद, getUserMedia को कॉल करते समय उस deviceId का इस्तेमाल किया जा सकता है जिसका इस्तेमाल करना है.

navigator.mediaDevices.getUserMedia({
  audio: {
    deviceId: devices[0].deviceId,
  },
});

यह अपने-आप इतना काम का नहीं है. हम सिर्फ़ ऑडियो डेटा को लेकर उसे फिर से चला सकते हैं.

माइक्रोफ़ोन से रॉ डेटा ऐक्सेस करना

माइक्रोफ़ोन से रॉ डेटा ऐक्सेस करने के लिए, हमें getUserMedia() की बनाई गई स्ट्रीम लेनी होगी. इसके बाद, डेटा को प्रोसेस करने के लिए, Web Audio API का इस्तेमाल करना होगा. Web Audio API एक आसान एपीआई है. यह इनपुट सोर्स लेता है और उन सोर्स को नोड से कनेक्ट करता है. ये नोड, ऑडियो डेटा को प्रोसेस कर सकते हैं. जैसे, गेन में बदलाव करना वगैरह. आखिर में, यह डेटा स्पीकर से कनेक्ट होता है, ताकि उपयोगकर्ता उसे सुन सके.

कनेक्ट किए जा सकने वाले नोड में से एक AudioWorkletNode है. इस नोड की मदद से, ऑडियो को पसंद के मुताबिक प्रोसेस करने की सुविधा मिलती है. ऑडियो की असल प्रोसेसिंग, AudioWorkletProcessor में process() कॉलबैक वाले तरीके से होती है. इनपुट और पैरामीटर फ़ीड करने और आउटपुट फ़ेच करने के लिए, इस फ़ंक्शन को कॉल करें.

ज़्यादा जानने के लिए, ऑडियो वर्कलेट डालें पर जाएं.

<script>
  const handleSuccess = async function(stream) {
    const context = new AudioContext();
    const source = context.createMediaStreamSource(stream);

    await context.audioWorklet.addModule("processor.js");
    const worklet = new AudioWorkletNode(context, "worklet-processor");

    source.connect(worklet);
    worklet.connect(context.destination);
  };

  navigator.mediaDevices.getUserMedia({ audio: true, video: false })
      .then(handleSuccess);
</script>
// processor.js
class WorkletProcessor extends AudioWorkletProcessor {
  process(inputs, outputs, parameters) {
    // Do something with the data, e.g. convert it to WAV
    console.log(inputs);
    return true;
  }
}

registerProcessor("worklet-processor", WorkletProcessor);

बफ़र में सेव किया गया डेटा, माइक्रोफ़ोन से मिला रॉ डेटा होता है. इस डेटा का इस्तेमाल कई कामों के लिए किया जा सकता है:

  • इसे सीधे सर्वर पर अपलोड करें
  • इसे डिवाइस पर सेव करना
  • इसे WAV जैसे किसी खास फ़ाइल फ़ॉर्मैट में बदलें और फिर इसे अपने सर्वर या लोकल स्टोरेज में सेव करें

माइक्रोफ़ोन से डेटा सेव करना

माइक्रोफ़ोन से डेटा सेव करने का सबसे आसान तरीका, MediaRecorder एपीआई का इस्तेमाल करना है.

MediaRecorder API, getUserMedia से बनाई गई स्ट्रीम को लेगा. इसके बाद, स्ट्रीम में मौजूद डेटा को आपके पसंदीदा डेस्टिनेशन में धीरे-धीरे सेव करेगा.

<a id="download">Download</a>
<button id="stop">Stop</button>
<script>
  const downloadLink = document.getElementById('download');
  const stopButton = document.getElementById('stop');


  const handleSuccess = function(stream) {
    const options = {mimeType: 'audio/webm'};
    const recordedChunks = [];
    const mediaRecorder = new MediaRecorder(stream, options);

    mediaRecorder.addEventListener('dataavailable', function(e) {
      if (e.data.size > 0) recordedChunks.push(e.data);
    });

    mediaRecorder.addEventListener('stop', function() {
      downloadLink.href = URL.createObjectURL(new Blob(recordedChunks));
      downloadLink.download = 'acetest.wav';
    });

    stopButton.addEventListener('click', function() {
      mediaRecorder.stop();
    });

    mediaRecorder.start();
  };

  navigator.mediaDevices.getUserMedia({ audio: true, video: false })
      .then(handleSuccess);
</script>

हमारे मामले में, हम डेटा को सीधे किसी ऐरे में सेव कर रहे हैं, जिसे बाद में Blob में बदला जा सकता है. इसके बाद, इसका इस्तेमाल करके डेटा को अपने वेब सर्वर या सीधे उपयोगकर्ता के डिवाइस के स्टोरेज में सेव किया जा सकता है.

माइक्रोफ़ोन का ज़िम्मेदारी से इस्तेमाल करने के लिए अनुमति मांगना

अगर उपयोगकर्ता ने पहले कभी आपकी साइट को माइक्रोफ़ोन का ऐक्सेस नहीं दिया है, तो getUserMedia को कॉल करने के तुरंत बाद, ब्राउज़र उपयोगकर्ता को आपकी साइट को माइक्रोफ़ोन का ऐक्सेस देने के लिए कहेगा.

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

आपके पास पहले से ऐक्सेस है या नहीं, यह देखने के लिए अनुमतियां एपीआई का इस्तेमाल करना

getUserMedia एपीआई से आपको यह जानकारी नहीं मिलती कि आपके पास पहले से माइक्रोफ़ोन का ऐक्सेस है या नहीं. इससे आपको एक समस्या आती है. उपयोगकर्ता को माइक्रोफ़ोन का ऐक्सेस देने के लिए, आपको एक अच्छा यूज़र इंटरफ़ेस (यूआई) उपलब्ध कराना होगा. इसके लिए, आपको माइक्रोफ़ोन का ऐक्सेस मांगना होगा.

कुछ ब्राउज़र में, Permission API का इस्तेमाल करके इस समस्या को हल किया जा सकता है. navigator.permission एपीआई की मदद से, किसी खास एपीआई को ऐक्सेस करने की स्थिति के बारे में क्वेरी की जा सकती है. इसके लिए, आपको फिर से अनुरोध करने की ज़रूरत नहीं पड़ती.

यह जानने के लिए कि आपके पास उपयोगकर्ता के माइक्रोफ़ोन का ऐक्सेस है या नहीं, क्वेरी के तरीके में {name: 'microphone'} डालें. इससे आपको इनमें से कोई एक नतीजा मिलेगा:

  • granted — उपयोगकर्ता ने पहले ही आपको माइक्रोफ़ोन का ऐक्सेस दिया हो;
  • prompt — उपयोगकर्ता ने आपको ऐक्सेस नहीं दिया है और getUserMedia पर कॉल करने पर, उसे सूचना दी जाएगी;
  • denied — सिस्टम या उपयोगकर्ता ने माइक्रोफ़ोन का ऐक्सेस साफ़ तौर पर ब्लॉक कर दिया है और आपको इसका ऐक्सेस नहीं मिलेगा.

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

navigator.permissions.query({name: 'microphone'}).then(function (result) {
  if (result.state == 'granted') {
  } else if (result.state == 'prompt') {
  } else if (result.state == 'denied') {
  }
  result.onchange = function () {};
});

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