ব্যবহারকারীর কাছ থেকে অডিও রেকর্ডিং

অনেক ব্রাউজারে এখন ব্যবহারকারীর কাছ থেকে ভিডিও এবং অডিও ইনপুট অ্যাক্সেস করার ক্ষমতা রয়েছে। যাইহোক, ব্রাউজারের উপর নির্ভর করে, এটি একটি সম্পূর্ণ গতিশীল এবং ইনলাইন অভিজ্ঞতা হতে পারে, অথবা এটি ব্যবহারকারীর ডিভাইসে অন্য অ্যাপে অর্পণ করা যেতে পারে।

সহজ এবং ধীরে ধীরে শুরু করুন

সবচেয়ে সহজ কাজটি হল ব্যবহারকারীকে প্রাক-রেকর্ড করা ফাইলের জন্য জিজ্ঞাসা করা। একটি সাধারণ ফাইল ইনপুট উপাদান তৈরি করে এবং একটি accept ফিল্টার যোগ করে এটি করুন যা নির্দেশ করে যে আমরা কেবল অডিও ফাইলগুলি গ্রহণ করতে পারি এবং একটি capture বৈশিষ্ট্য যা নির্দেশ করে যে আমরা মাইক্রোফোন থেকে এটি সরাসরি পেতে চাই।

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

এই পদ্ধতিটি সমস্ত প্ল্যাটফর্মে কাজ করে। ডেস্কটপে, এটি ব্যবহারকারীকে ফাইল সিস্টেম থেকে একটি ফাইল আপলোড করতে অনুরোধ করবে ( capture অ্যাট্রিবিউট উপেক্ষা করে)। IOS-এ Safari-এ, এটি মাইক্রোফোন অ্যাপ খুলবে, আপনাকে অডিও রেকর্ড করতে এবং তারপরে ওয়েব পৃষ্ঠায় ফেরত পাঠাতে অনুমতি দেবে; অ্যান্ড্রয়েডে, এটি ওয়েব পেজে ফেরত পাঠানোর আগে ব্যবহারকারীকে কোন অ্যাপ ব্যবহার করে অডিও রেকর্ড করতে হবে তা বেছে নেবে।

ব্যবহারকারীর রেকর্ডিং শেষ হয়ে গেলে এবং তারা ওয়েবসাইটে ফিরে গেলে, আপনাকে কোনওভাবে ফাইল ডেটা ধরে রাখতে হবে। ইনপুট এলিমেন্টে একটি 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 এ সংযুক্ত করে একটি সার্ভারে আপলোড করুন৷
  • ওয়েব অডিও API এর মাধ্যমে এটি পাস করুন এবং এটিতে ফিল্টার প্রয়োগ করুন৷

যদিও অডিও ডেটাতে অ্যাক্সেস পাওয়ার ইনপুট উপাদান পদ্ধতি ব্যবহার করা সর্বব্যাপী, এটি সবচেয়ে কম আকর্ষণীয় বিকল্প। আমরা সত্যিই মাইক্রোফোনে অ্যাক্সেস পেতে চাই এবং সরাসরি পৃষ্ঠায় একটি চমৎকার অভিজ্ঞতা প্রদান করতে চাই।

ইন্টারেক্টিভভাবে মাইক্রোফোন অ্যাক্সেস করুন

আধুনিক ব্রাউজারগুলির মাইক্রোফোনে একটি সরাসরি লাইন থাকতে পারে যা আমাদের এমন অভিজ্ঞতা তৈরি করতে দেয় যা ওয়েব পৃষ্ঠার সাথে সম্পূর্ণরূপে একত্রিত হয় এবং ব্যবহারকারী কখনই ব্রাউজারটি ছেড়ে যাবে না।

মাইক্রোফোন অ্যাক্সেস অর্জন

getUserMedia() নামক WebRTC স্পেসিফিকেশনে API ব্যবহার করে আমরা সরাসরি মাইক্রোফোন অ্যাক্সেস করতে পারি। getUserMedia() ব্যবহারকারীকে তাদের সংযুক্ত মাইক্রোফোন এবং ক্যামেরা অ্যাক্সেসের জন্য অনুরোধ করবে।

সফল হলে API একটি Stream ফেরত দেবে যাতে ক্যামেরা বা মাইক্রোফোন থেকে ডেটা থাকবে, এবং তারপরে আমরা এটিকে একটি <audio> উপাদানের সাথে সংযুক্ত করতে পারি, এটিকে একটি WebRTC স্ট্রিমের সাথে সংযুক্ত করতে পারি, এটিকে একটি ওয়েব অডিও AudioContext এর সাথে সংযুক্ত করতে পারি, অথবা MediaRecorder API ব্যবহার করে এটি সংরক্ষণ করুন।

মাইক্রোফোন থেকে ডেটা পেতে, আমরা শুধু audio: true যা getUserMedia() API-তে পাস করা হয়।

<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() দ্বারা তৈরি স্ট্রিমটি নিতে হবে এবং তারপরে ডেটা প্রক্রিয়া করতে ওয়েব অডিও API ব্যবহার করতে হবে। ওয়েব অডিও এপিআই হল একটি সাধারণ এপিআই যা ইনপুট সোর্স নেয় এবং সেই সোর্সগুলিকে নোডের সাথে সংযুক্ত করে যা অডিও ডেটা প্রক্রিয়া করতে পারে (গেইন ইত্যাদি সামঞ্জস্য করুন) এবং শেষ পর্যন্ত একটি স্পিকারের সাথে যাতে ব্যবহারকারী এটি শুনতে পারে।

আপনি যে নোডগুলিকে সংযুক্ত করতে পারেন তার মধ্যে একটি হল একটি AudioWorkletNode । এই নোড আপনাকে কাস্টম অডিও প্রক্রিয়াকরণের জন্য নিম্ন-স্তরের ক্ষমতা দেয়। AudioWorkletProcessorprocess() কলব্যাক পদ্ধতিতে প্রকৃত অডিও প্রক্রিয়াকরণ ঘটে। ইনপুট এবং প্যারামিটার ফিড করতে এবং আউটপুট আনতে এই ফাংশনটি কল করুন।

আরও জানতে অডিও ওয়ার্কলেট এন্টার চেক আউট করুন।

<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 API ব্যবহার করা।

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 কল করবেন, ব্রাউজারটি ব্যবহারকারীকে মাইক্রোফোনে আপনার সাইটের অনুমতি দেওয়ার জন্য অনুরোধ করবে।

ব্যবহারকারীরা তাদের মেশিনে শক্তিশালী ডিভাইসগুলিতে অ্যাক্সেসের জন্য অনুরোধ করাকে ঘৃণা করে এবং তারা প্রায়শই অনুরোধটি ব্লক করবে, অথবা প্রম্পটটি যে প্রেক্ষাপটটি তৈরি করা হয়েছে তা বুঝতে না পারলে তারা এটিকে উপেক্ষা করবে। প্রথম প্রয়োজনে শুধুমাত্র মাইক্রোফোন অ্যাক্সেস করার জন্য জিজ্ঞাসা করা সর্বোত্তম অভ্যাস। ব্যবহারকারী একবার অ্যাক্সেস মঞ্জুর করলে, তাদের আর জিজ্ঞাসা করা হবে না, তবে, যদি তারা অ্যাক্সেস প্রত্যাখ্যান করে, আপনি ব্যবহারকারীকে আবার অনুমতি চাইতে পারবেন না।

আপনার ইতিমধ্যে অ্যাক্সেস আছে কিনা তা পরীক্ষা করতে অনুমতি API ব্যবহার করুন

getUserMedia API আপনার কাছে ইতিমধ্যেই মাইক্রোফোনে অ্যাক্সেস আছে কিনা সে সম্পর্কে কোনো জ্ঞান নেই। এটি আপনাকে একটি সমস্যার সাথে উপস্থাপন করে, ব্যবহারকারীকে আপনাকে মাইক্রোফোনে অ্যাক্সেস দেওয়ার জন্য একটি সুন্দর UI প্রদান করতে, আপনাকে মাইক্রোফোনে অ্যাক্সেসের জন্য জিজ্ঞাসা করতে হবে।

অনুমতি API ব্যবহার করে কিছু ব্রাউজারে এটি সমাধান করা যেতে পারে। navigator.permission API আপনাকে আবার প্রম্পট না করে নির্দিষ্ট API-এর অ্যাক্সেস করার ক্ষমতার অবস্থা জিজ্ঞাসা করতে দেয়।

ব্যবহারকারীর মাইক্রোফোনে আপনার অ্যাক্সেস থাকলে জিজ্ঞাসা করতে, আপনি ক্যোয়ারী পদ্ধতিতে {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 () {};
});

প্রতিক্রিয়া