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

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

आसान शुरुआत करें और धीरे-धीरे आगे बढ़ें

सबसे आसान तरीका है कि उपयोगकर्ता से पहले से रिकॉर्ड की गई फ़ाइल के लिए कहें. ऐसा करने के लिए, एक आसान फ़ाइल इनपुट एलिमेंट बनाएं और एक 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 से पास करें और इस पर फ़िल्टर लागू करें

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

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

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

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

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

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

माइक्रोफ़ोन से डेटा पाने के लिए, हमने getUserMedia() API को पास किए गए कंस्ट्रेंट ऑब्जेक्ट में बस 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');
});

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

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 एपीआई, 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 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 () {};
});

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