HTML5 এ অডিও এবং ভিডিও ক্যাপচার করুন

ভূমিকা

অডিও/ভিডিও ক্যাপচার দীর্ঘদিন ধরে ওয়েব ডেভেলপমেন্টের " হলি গ্রেইল"। অনেক বছর ধরে কাজটি সম্পন্ন করার জন্য আমাদের ব্রাউজার প্লাগইনগুলির ( ফ্ল্যাশ বা সিলভারলাইট ) উপর নির্ভর করতে হয়েছে। চলে আসো!

উদ্ধারের জন্য HTML5. এটি স্পষ্ট নাও হতে পারে, কিন্তু HTML5 এর উত্থান ডিভাইস হার্ডওয়্যারে অ্যাক্সেসের ঢেউ এনেছে। জিওলোকেশন (জিপিএস), ওরিয়েন্টেশন এপিআই (অ্যাক্সিলোমিটার), ওয়েবজিএল (জিপিইউ), এবং ওয়েব অডিও এপিআই (অডিও হার্ডওয়্যার) নিখুঁত উদাহরণ। এই বৈশিষ্ট্যগুলি হাস্যকরভাবে শক্তিশালী, উচ্চ স্তরের জাভাস্ক্রিপ্ট এপিআইগুলিকে প্রকাশ করে যা সিস্টেমের অন্তর্নিহিত হার্ডওয়্যার ক্ষমতাগুলির উপরে বসে।

এই টিউটোরিয়ালটি একটি নতুন API, GetUserMedia প্রবর্তন করে, যা ওয়েব অ্যাপগুলিকে ব্যবহারকারীর ক্যামেরা এবং মাইক্রোফোন অ্যাক্সেস করতে দেয়৷

GetUserMedia() এর রাস্তা

আপনি যদি এর ইতিহাস সম্পর্কে সচেতন না হন, তাহলে আমরা যেভাবে getUserMedia() API এ পৌঁছেছি তা একটি আকর্ষণীয় গল্প।

"মিডিয়া ক্যাপচার APIs"-এর বেশ কয়েকটি রূপ গত কয়েক বছরে বিকশিত হয়েছে। অনেক লোক ওয়েবে নেটিভ ডিভাইসগুলি অ্যাক্সেস করতে সক্ষম হওয়ার প্রয়োজনীয়তা স্বীকার করেছে, কিন্তু এটি প্রত্যেককে এবং তাদের মাকে একত্রিত করতে একটি নতুন বৈশিষ্ট্য তৈরি করতে পরিচালিত করেছে। জিনিসগুলি এতটাই অগোছালো হয়ে গিয়েছিল যে W3C অবশেষে একটি ওয়ার্কিং গ্রুপ গঠন করার সিদ্ধান্ত নিয়েছে। তাদের একমাত্র উদ্দেশ্য? পাগলামি বোধ করি! Device APIs Policy (DAP) ওয়ার্কিং গ্রুপকে প্রস্তাবের আধিক্যকে একত্রীকরণ + মানসম্মত করার দায়িত্ব দেওয়া হয়েছে।

আমি 2011 সালে যা ঘটেছিল তা সংক্ষিপ্ত করার চেষ্টা করব...

রাউন্ড 1: HTML মিডিয়া ক্যাপচার

এইচটিএমএল মিডিয়া ক্যাপচার হল ওয়েবে মিডিয়া ক্যাপচারের মানসম্মত করার ক্ষেত্রে 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">

ঠিক কি সুন্দর? আমি বিশেষভাবে পছন্দ করি যে এটি একটি ফাইল ইনপুট পুনরায় ব্যবহার করে। শব্দার্থগতভাবে, এটি অনেক অর্থবহ করে তোলে। যেখানে এই নির্দিষ্ট "API" কম পড়ে তা হল রিয়েলটাইম প্রভাবগুলি করার ক্ষমতা (যেমন <canvas> ক্যানভাসে লাইভ ওয়েবক্যাম ডেটা রেন্ডার করুন এবং ওয়েবজিএল ফিল্টার প্রয়োগ করুন)। HTML মিডিয়া ক্যাপচার আপনাকে শুধুমাত্র একটি মিডিয়া ফাইল রেকর্ড করতে বা সময়মতো একটি স্ন্যাপশট নিতে দেয়।

সমর্থন:

রাউন্ড 2: ডিভাইস উপাদান

অনেকেই ভেবেছিলেন যে HTML মিডিয়া ক্যাপচার খুব সীমিত, তাই একটি নতুন বৈশিষ্ট্য আবির্ভূত হয়েছে যা যেকোনো ধরনের (ভবিষ্যত) ডিভাইসকে সমর্থন করে। আশ্চর্যের বিষয় নয়, ডিজাইনটি একটি নতুন উপাদানের জন্য আহ্বান করেছে, <device> উপাদান , যা getUserMedia() এর পূর্বসূরি হয়ে উঠেছে।

<device> উপাদানের উপর ভিত্তি করে ভিডিও ক্যাপচারের প্রাথমিক বাস্তবায়ন তৈরি করা প্রথম ব্রাউজারগুলির মধ্যে Opera ছিল। শীঘ্রই ( একই দিন সুনির্দিষ্ট হতে ) WhatWG সিদ্ধান্ত নেয় <device> ট্যাগটিকে অন্য একটি আপ এবং কামারের পক্ষে স্ক্র্যাপ করার, এবার একটি JavaScript API নামক navigator.getUserMedia() । এক সপ্তাহ পরে, অপেরা নতুন বিল্ডগুলি প্রকাশ করে যা আপডেট করা getUserMedia() স্পেকের জন্য সমর্থন অন্তর্ভুক্ত করে। সেই বছরের শেষের দিকে, মাইক্রোসফ্ট নতুন বৈশিষ্ট্য সমর্থন করে 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> জন্য চিন্তা করার জন্য একটি কম API এর জন্য দুটি দুর্দান্ত জিনিস ছিল: 1.) এটি শব্দার্থিক ছিল এবং 2.) এটি কেবলমাত্র অডিও/ভিডিও ডিভাইসের চেয়ে আরও বেশি সমর্থন করার জন্য সহজেই প্রসারিত ছিল।

শ্বাস নাও. এই জিনিস দ্রুত চলে!

রাউন্ড 3: WebRTC

<device> উপাদানটি অবশেষে ডোডোর পথে চলে গেছে।

বৃহত্তর WebRTC (ওয়েব রিয়েল টাইম কমিউনিকেশন) প্রচেষ্টার জন্য একটি উপযুক্ত ক্যাপচার API খুঁজে পাওয়ার গতি ত্বরান্বিত হয়েছে। এই বৈশিষ্ট্যটি W3C WebRTC ওয়ার্কিং গ্রুপ দ্বারা তত্ত্বাবধান করা হয়। গুগল, অপেরা, মজিলা এবং আরও কয়েকটি বাস্তবায়ন রয়েছে।

getUserMedia() WebRTC এর সাথে সম্পর্কিত কারণ এটি সেই API-এর সেটের গেটওয়ে। এটি ব্যবহারকারীর স্থানীয় ক্যামেরা/মাইক্রোফোন স্ট্রিম অ্যাক্সেস করার উপায় প্রদান করে।

সমর্থন:

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> । লক্ষ্য করুন যে আমরা একটি src অ্যাট্রিবিউট সেট করছি না বা <video> এলিমেন্টে <source> উপাদানগুলি অন্তর্ভুক্ত করছি না। ভিডিওটিকে একটি মিডিয়া ফাইলে একটি URL খাওয়ানোর পরিবর্তে, আমরা ওয়েবক্যামের প্রতিনিধিত্বকারী LocalMediaStream অবজেক্টে srcObject সেট করছি৷

আমি <video> কে autoplay করতে বলছি, অন্যথায় এটি প্রথম ফ্রেমে হিমায়িত হবে। controls যোগ করাও আপনার প্রত্যাশা অনুযায়ী কাজ করে।

মিডিয়া সীমাবদ্ধতা সেট করা (রেজোলিউশন, উচ্চতা, প্রস্থ)

getUserMedia() এর প্রথম প্যারামিটারটি ফেরত মিডিয়া স্ট্রীমে আরও প্রয়োজনীয়তা (বা সীমাবদ্ধতা) নির্দিষ্ট করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, আপনি ভিডিওতে প্রাথমিক অ্যাক্সেস চান এমন ইঙ্গিত করার পরিবর্তে (যেমন {video: true} ), আপনি অতিরিক্তভাবে স্ট্রিমটিকে HD হতে হবে:

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);

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

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