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

Mat Scales

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

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

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

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

অনেক মোবাইল ডিভাইসে একাধিক ক্যামেরা থাকে। যদি আপনার পছন্দ থাকে, আপনি user জন্য capture অ্যাট্রিবিউট সেট করতে পারেন, যদি আপনি ব্যবহারকারীর মুখোমুখি হওয়া ক্যামেরা বা environment চান যদি আপনি বাইরের দিকে মুখ করা ক্যামেরা চান।

<input type="file" accept="video/*" capture="user" />
<input type="file" accept="video/*" capture="environment" />

মনে রাখবেন যে এটি শুধুমাত্র একটি ইঙ্গিত - যদি ব্রাউজারটি বিকল্পটিকে সমর্থন না করে, বা আপনি যে ক্যামেরার ধরনটি চান তা উপলব্ধ না হলে, ব্রাউজার অন্য ক্যামেরা বেছে নিতে পারে৷

ব্যবহারকারীর রেকর্ডিং শেষ হয়ে গেলে এবং তারা ওয়েবসাইটে ফিরে গেলে, আপনাকে কোনওভাবে ফাইল ডেটা ধরে রাখতে হবে। ইনপুট এলিমেন্টে একটি onchange ইভেন্ট সংযুক্ত করে এবং তারপর ইভেন্ট অবজেক্টের files সম্পত্তি পড়ার মাধ্যমে আপনি দ্রুত অ্যাক্সেস পেতে পারেন।

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

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

একবার আপনি ফাইলটিতে অ্যাক্সেস পেয়ে গেলে আপনি এটি দিয়ে যা চান তা করতে পারেন। উদাহরণস্বরূপ, আপনি করতে পারেন:

  • এটি সরাসরি একটি <video> উপাদানের সাথে সংযুক্ত করুন যাতে আপনি এটি চালাতে পারেন
  • ব্যবহারকারীর ডিভাইসে এটি ডাউনলোড করুন
  • একটি XMLHttpRequest সংযুক্ত করে এটি একটি সার্ভারে আপলোড করুন৷
  • একটি ক্যানভাসে ফ্রেম আঁকুন এবং এটিতে ফিল্টার প্রয়োগ করুন

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

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

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

ক্যামেরা অ্যাক্সেস অর্জন

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

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

ক্যামেরা থেকে ডেটা পেতে আমরা শুধু video: true যা getUserMedia() API-তে পাস করা হয়

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

  var handleSuccess = function (stream) {
    player.srcObject = stream;
  };

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

আপনি যদি একটি নির্দিষ্ট ক্যামেরা চয়ন করতে চান তবে আপনি প্রথমে উপলব্ধ ক্যামেরাগুলি গণনা করতে পারেন।

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

তারপর আপনি getUserMedia কল করার সময় যে ডিভাইস আইডিটি ব্যবহার করতে চান সেটি পাস করতে পারেন।

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

নিজেই, এই যে দরকারী নয়. আমরা যা করতে পারি তা হল ভিডিও ডেটা নেওয়া এবং এটিকে আবার প্লে করা।

ক্যামেরা থেকে কাঁচা ডেটা অ্যাক্সেস করুন

ক্যামেরা থেকে কাঁচা ভিডিও ডেটা অ্যাক্সেস করতে আপনি প্রতিটি ফ্রেমকে একটি <canvas> এ আঁকতে পারেন এবং পিক্সেলগুলিকে সরাসরি ম্যানিপুলেট করতে পারেন।

একটি 2D ক্যানভাসের জন্য আপনি ক্যানভাসে <video> উপাদানের বর্তমান ফ্রেম আঁকতে প্রসঙ্গটির drawImage পদ্ধতি ব্যবহার করতে পারেন।

context.drawImage(myVideoElement, 0, 0);

একটি WebGL ক্যানভাসের সাহায্যে আপনি একটি <video> উপাদান একটি টেক্সচারের উৎস হিসেবে ব্যবহার করতে পারেন।

gl.texImage2D(
  gl.TEXTURE_2D,
  0,
  gl.RGBA,
  gl.RGBA,
  gl.UNSIGNED_BYTE,
  myVideoElement,
);

মনে রাখবেন যে উভয় ক্ষেত্রেই এটি একটি প্লে ভিডিওর বর্তমান ফ্রেম ব্যবহার করবে। একাধিক ফ্রেম প্রক্রিয়া করতে আপনাকে প্রতিবার ক্যানভাসে ভিডিওটি পুনরায় আঁকতে হবে।

আপনি চিত্র এবং ভিডিওতে রিয়েল-টাইম প্রভাব প্রয়োগ করার বিষয়ে আমাদের নিবন্ধে এই সম্পর্কে আরও জানতে পারেন।

ক্যামেরা থেকে ডেটা সংরক্ষণ করুন

ক্যামেরা থেকে ডেটা সংরক্ষণ করার সবচেয়ে সহজ উপায় হল MediaRecorder API ব্যবহার করা।

MediaRecorder API getUserMedia দ্বারা তৈরি স্ট্রীমটি গ্রহণ করবে এবং তারপর ধীরে ধীরে আপনার পছন্দের গন্তব্যে স্ট্রীম থেকে ডেটা সংরক্ষণ করবে।

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

  stopButton.addEventListener('click', function() {
    shouldStop = true;
  })

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

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

      if(shouldStop === true && stopped === false) {
        mediaRecorder.stop();
        stopped = true;
      }
    });

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

    mediaRecorder.start();
  };

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

আমাদের ক্ষেত্রে আমরা ডেটা সরাসরি একটি অ্যারেতে সংরক্ষণ করছি যা আমরা পরে একটি Blob এ পরিণত করতে পারি যা আমাদের ওয়েব সার্ভারে বা সরাসরি ব্যবহারকারীর ডিভাইসে স্টোরেজে সংরক্ষণ করতে ব্যবহার করা যেতে পারে।

দায়িত্বের সাথে ক্যামেরা ব্যবহার করার অনুমতি জিজ্ঞাসা করুন

ব্যবহারকারী যদি আগে ক্যামেরায় আপনার সাইটের অ্যাক্সেস মঞ্জুর না করে থাকে তাহলে আপনি যে মুহূর্তে getUserMedia কল করবেন ব্রাউজারটি ব্যবহারকারীকে ক্যামেরায় আপনার সাইটের অনুমতি দেওয়ার জন্য অনুরোধ করবে।

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

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

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

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

ব্যবহারকারীর ক্যামেরায় আপনার অ্যাক্সেস থাকলে জিজ্ঞাসা করতে আপনি ক্যোয়ারী পদ্ধতিতে {name: 'camera'} পাস করতে পারেন এবং এটি যেকোন একটিতে ফিরে আসবে:

  • granted — ব্যবহারকারী আপনাকে আগে ক্যামেরায় অ্যাক্সেস দিয়েছে;
  • prompt — ব্যবহারকারী আপনাকে অ্যাক্সেস দেয়নি এবং আপনি যখন getUserMedia কল করবেন তখন অনুরোধ করা হবে;
  • denied — সিস্টেম বা ব্যবহারকারী স্পষ্টভাবে ক্যামেরার অ্যাক্সেস ব্লক করেছে এবং আপনি এটিতে অ্যাক্সেস পেতে সক্ষম হবেন না।

এবং আপনি এখন দ্রুত পরীক্ষা করে দেখতে পারেন যে আপনার ব্যবহারকারীর ইন্টারফেস পরিবর্তন করার জন্য ব্যবহারকারীর যে ক্রিয়াগুলি নেওয়া দরকার তা মিটমাট করতে হবে কিনা।

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

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