১. ভূমিকা
WebRTC হলো একটি ওপেন সোর্স প্রকল্প, যা ওয়েব এবং নেটিভ অ্যাপে অডিও, ভিডিও ও ডেটার রিয়েল-টাইম যোগাযোগ সক্ষম করে।
WebRTC-এর বেশ কয়েকটি জাভাস্ক্রিপ্ট এপিআই রয়েছে — ডেমো দেখতে লিঙ্কগুলোতে ক্লিক করুন।
-
getUserMedia(): অডিও এবং ভিডিও ধারণ করে। -
MediaRecorder: অডিও এবং ভিডিও রেকর্ড করুন। -
RTCPeerConnection: ব্যবহারকারীদের মধ্যে অডিও এবং ভিডিও স্ট্রিম করুন। -
RTCDataChannel: ব্যবহারকারীদের মধ্যে ডেটা আদান-প্রদান করে।
আমি কোথায় WebRTC ব্যবহার করতে পারি?
ডেস্কটপ ও অ্যান্ড্রয়েডে ফায়ারফক্স, অপেরা এবং ক্রোমে এটি পাওয়া যায়। আইওএস এবং অ্যান্ড্রয়েডের নেটিভ অ্যাপের জন্যও ওয়েবআরটিসি উপলব্ধ।
সংকেত দেওয়া বলতে কী বোঝায়?
WebRTC ব্রাউজারগুলোর মধ্যে স্ট্রিমিং ডেটা আদান-প্রদানের জন্য RTCPeerConnection ব্যবহার করে, কিন্তু এর পাশাপাশি যোগাযোগ সমন্বয় এবং নিয়ন্ত্রণ বার্তা পাঠানোর জন্য একটি পদ্ধতিরও প্রয়োজন হয়, যা সিগন্যালিং নামে পরিচিত। WebRTC-তে সিগন্যালিং-এর পদ্ধতি ও প্রোটোকল নির্দিষ্ট করা নেই। এই কোডল্যাবে আপনি মেসেজিংয়ের জন্য Socket.IO ব্যবহার করবেন, তবে এর অনেক বিকল্পও রয়েছে।
STUN এবং TURN বলতে কী বোঝায়?
WebRTC পিয়ার-টু-পিয়ার পদ্ধতিতে কাজ করার জন্য ডিজাইন করা হয়েছে, যাতে ব্যবহারকারীরা সম্ভাব্য সবচেয়ে সরাসরি পথে সংযোগ করতে পারে। তবে, WebRTC বাস্তব জগতের নেটওয়ার্কিংয়ের সাথে মানিয়ে চলার জন্য তৈরি করা হয়েছে: ক্লায়েন্ট অ্যাপ্লিকেশনগুলোকে NAT গেটওয়ে এবং ফায়ারওয়াল অতিক্রম করতে হয়, এবং সরাসরি সংযোগ ব্যর্থ হলে পিয়ার-টু-পিয়ার নেটওয়ার্কিংয়ের জন্য ফলব্যাক বা বিকল্প ব্যবস্থার প্রয়োজন হয়। এই প্রক্রিয়ার অংশ হিসেবে, WebRTC API-গুলো আপনার কম্পিউটারের IP অ্যাড্রেস পাওয়ার জন্য STUN সার্ভার এবং পিয়ার-টু-পিয়ার যোগাযোগ ব্যর্থ হলে রিলে সার্ভার হিসেবে কাজ করার জন্য TURN সার্ভার ব্যবহার করে। ( বাস্তব জগতে WebRTC বিষয়ে আরও বিস্তারিত ব্যাখ্যা করা হয়েছে।)
WebRTC কি সুরক্ষিত?
WebRTC-এর সকল উপাদানের জন্য এনক্রিপশন বাধ্যতামূলক, এবং এর জাভাস্ক্রিপ্ট এপিআইগুলো শুধুমাত্র সুরক্ষিত উৎস (HTTPS বা লোকালহোস্ট) থেকে ব্যবহার করা যায়। WebRTC স্ট্যান্ডার্ডে সিগন্যালিং পদ্ধতি সংজ্ঞায়িত করা নেই, তাই সুরক্ষিত প্রোটোকল ব্যবহার করা আপনারই দায়িত্ব।
২. সংক্ষিপ্ত বিবরণ
আপনার ওয়েবক্যাম দিয়ে ভিডিও ও স্ন্যাপশট ধারণ করার এবং WebRTC-এর মাধ্যমে পিয়ার-টু-পিয়ার শেয়ার করার জন্য একটি অ্যাপ তৈরি করুন। এই প্রক্রিয়ার মধ্যে আপনি শিখবেন কীভাবে মূল WebRTC API-গুলো ব্যবহার করতে হয় এবং Node.js ব্যবহার করে একটি মেসেজিং সার্ভার সেট আপ করতে হয়।
আপনি যা শিখবেন
- আপনার ওয়েবক্যাম থেকে ভিডিও নিন
- RTCPeerConnection দিয়ে ভিডিও স্ট্রিম করুন
- RTCDataChannel-এর মাধ্যমে ডেটা স্ট্রিম করুন
- বার্তা আদান-প্রদানের জন্য একটি সংকেত পরিষেবা স্থাপন করুন
- পিয়ার সংযোগ এবং সংকেত একত্রিত করুন
- একটি ছবি তুলুন এবং ডেটা চ্যানেলের মাধ্যমে শেয়ার করুন।
আপনার যা যা লাগবে
- ক্রোম ৪৭ বা তার উপরে
- ক্রোমের জন্য ওয়েব সার্ভার , অথবা আপনার পছন্দমতো নিজস্ব ওয়েব সার্ভার ব্যবহার করুন।
- নমুনা কোড
- একটি টেক্সট এডিটর
- HTML, CSS এবং JavaScript-এর প্রাথমিক জ্ঞান
৩. নমুনা কোডটি নিন।
কোডটি ডাউনলোড করুন
আপনি যদি গিট-এর সাথে পরিচিত হন, তাহলে গিটহাব থেকে এই কোডল্যাবের কোডটি ক্লোন করে ডাউনলোড করতে পারেন:
git clone https://github.com/googlecodelabs/webrtc-web
বিকল্পভাবে, কোডটির একটি .zip ফাইল ডাউনলোড করতে নিচের বাটনটিতে ক্লিক করুন:
ডাউনলোড করা জিপ ফাইলটি খুলুন। এটি একটি প্রজেক্ট ফোল্ডার ( adaptive-web-media ) আনপ্যাক করবে, যার মধ্যে এই কোডল্যাবের প্রতিটি ধাপের জন্য একটি করে ফোল্ডার এবং আপনার প্রয়োজনীয় সমস্ত রিসোর্স রয়েছে।
আপনাকে আপনার সমস্ত কোডিংয়ের কাজ `work` নামের ডিরেক্টরিতে করতে হবে।
step-nn ফোল্ডারগুলোতে এই কোডল্যাবের প্রতিটি ধাপের একটি সম্পূর্ণ সংস্করণ রয়েছে। এগুলো রেফারেন্সের জন্য রাখা হয়েছে।
ওয়েব সার্ভার ইনস্টল এবং যাচাই করুন
যদিও আপনি আপনার নিজের ওয়েব সার্ভার ব্যবহার করতে পারেন, এই কোডল্যাবটি ক্রোম ওয়েব সার্ভারের সাথে ভালোভাবে কাজ করার জন্য ডিজাইন করা হয়েছে। যদি আপনার কাছে অ্যাপটি এখনও ইনস্টল করা না থাকে, তবে আপনি ক্রোম ওয়েব স্টোর থেকে এটি ইনস্টল করতে পারেন।

Web Server for Chrome অ্যাপটি ইনস্টল করার পর, বুকমার্ক বার, একটি নতুন ট্যাব পৃষ্ঠা বা অ্যাপ লঞ্চার থেকে Chrome Apps শর্টকাটে ক্লিক করুন:

ওয়েব সার্ভার আইকনে ক্লিক করুন:

এরপরে, আপনি এই ডায়ালগটি দেখতে পাবেন, যা আপনাকে আপনার স্থানীয় ওয়েব সার্ভার কনফিগার করার সুযোগ দেবে:

‘CHOOSE FOLDER’ বোতামে ক্লিক করুন এবং আপনার এইমাত্র তৈরি করা ওয়ার্ক ফোল্ডারটি নির্বাচন করুন। এর ফলে, আপনি ‘Web Server’ ডায়ালগের ‘ Web Server URL(s)’ বিভাগে হাইলাইট করা URL-টির মাধ্যমে Chrome-এ আপনার চলমান কাজটি দেখতে পারবেন।
Options-এর অধীনে, Automatically show index.html-এর পাশের বক্সে টিক চিহ্ন দিন, যেমনটি নিচে দেখানো হয়েছে:

এরপর, ‘Web Server: STARTED’ লেখা টগলটি বামে এবং তারপর আবার ডানে স্লাইড করে সার্ভারটি বন্ধ ও পুনরায় চালু করুন।

এখন হাইলাইট করা ওয়েব সার্ভার ইউআরএল-টিতে ক্লিক করে আপনার ওয়েব ব্রাউজারে আপনার কর্মক্ষেত্রে যান। আপনি এইরকম দেখতে একটি পৃষ্ঠা দেখতে পাবেন, যা work/index.html- এর সাথে সঙ্গতিপূর্ণ:

স্পষ্টতই, এই অ্যাপটি এখনও আকর্ষণীয় কিছু করছে না — আপাতত, এটি কেবল একটি ন্যূনতম কাঠামো যা আমরা আপনার ওয়েব সার্ভারটি সঠিকভাবে কাজ করছে কিনা তা নিশ্চিত করতে ব্যবহার করছি। পরবর্তী ধাপগুলোতে আপনি এতে কার্যকারিতা এবং লেআউটের বৈশিষ্ট্য যোগ করবেন।
৪. আপনার ওয়েবক্যাম থেকে ভিডিও স্ট্রিম করুন
আপনি যা শিখবেন
এই ধাপে আপনি জানতে পারবেন কীভাবে:
- আপনার ওয়েবক্যাম থেকে একটি ভিডিও স্ট্রিম নিন।
- স্ট্রিম প্লেব্যাক নিয়ন্ত্রণ করুন।
- ভিডিও সম্পাদনা করতে CSS এবং SVG ব্যবহার করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-01 ফোল্ডারে রয়েছে।
একটু এইচটিএমএল...
আপনার ওয়ার্ক ডিরেক্টরিতে থাকা index.html- এ একটি video এলিমেন্ট এবং একটি script এলিমেন্ট যোগ করুন:
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<video autoplay playsinline></video>
<script src="js/main.js"></script>
</body>
</html>
...এবং এক চিমটি জাভাস্ক্রিপ্ট
আপনার js ফোল্ডারের main.js ফাইলে নিম্নলিখিতটি যোগ করুন:
'use strict';
// On this codelab, you will be streaming only video (video: true).
const mediaStreamConstraints = {
video: true,
};
// Video element where stream will be placed.
const localVideo = document.querySelector('video');
// Local stream that will be reproduced on the video.
let localStream;
// Handles success by adding the MediaStream to the video element.
function gotLocalMediaStream(mediaStream) {
localStream = mediaStream;
localVideo.srcObject = mediaStream;
}
// Handles error by logging a message to the console with the error message.
function handleLocalMediaStreamError(error) {
console.log('navigator.getUserMedia error: ', error);
}
// Initializes media stream.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
.then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
চেষ্টা করে দেখুন
আপনার ব্রাউজারে index.html খুলুন এবং আপনি এইরকম কিছু দেখতে পাবেন (অবশ্যই, আপনার ওয়েবক্যাম থেকে তোলা দৃশ্যটি সহ!):

এটি কীভাবে কাজ করে
getUserMedia() কল করার পর, ব্রাউজার ব্যবহারকারীর ক্যামেরা অ্যাক্সেস করার জন্য অনুমতি চায় (যদি বর্তমান অরিজিনের জন্য এটি প্রথমবার ক্যামেরা অ্যাক্সেসের অনুরোধ হয়)। সফল হলে, একটি MediaStream রিটার্ন করা হয়, যা একটি মিডিয়া এলিমেন্ট srcObject অ্যাট্রিবিউটের মাধ্যমে ব্যবহার করতে পারে:
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
.then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
}
function gotLocalMediaStream(mediaStream) {
localVideo.srcObject = mediaStream;
}
constraints আর্গুমেন্টটি আপনাকে নির্দিষ্ট করতে দেয় যে কোন মিডিয়াটি পাওয়া যাবে। এই উদাহরণে, শুধুমাত্র ভিডিও, কারণ অডিও ডিফল্টরূপে নিষ্ক্রিয় থাকে:
const mediaStreamConstraints = {
video: true,
};
ভিডিও রেজোলিউশনের মতো অতিরিক্ত প্রয়োজনীয়তার জন্য আপনি সীমাবদ্ধতা ব্যবহার করতে পারেন:
const hdConstraints = {
video: {
width: {
min: 1280
},
height: {
min: 720
}
}
}
MediaTrackConstraints স্পেসিফিকেশনে সমস্ত সম্ভাব্য সীমাবদ্ধতার প্রকার তালিকাভুক্ত করা আছে, যদিও সব বিকল্প সব ব্রাউজার দ্বারা সমর্থিত নয়। যদি অনুরোধ করা রেজোলিউশনটি বর্তমানে নির্বাচিত ক্যামেরা দ্বারা সমর্থিত না হয়, তাহলে getUserMedia() একটি OverconstrainedError সহ প্রত্যাখ্যাত হবে এবং ব্যবহারকারীকে তাদের ক্যামেরা অ্যাক্সেস করার অনুমতি দেওয়ার জন্য অনুরোধ করা হবে না।
যদি getUserMedia() সফল হয়, তাহলে ওয়েবক্যাম থেকে আসা ভিডিও স্ট্রিমটি ভিডিও এলিমেন্টের উৎস হিসেবে সেট করা হয়:
function gotLocalMediaStream(mediaStream) {
localVideo.srcObject = mediaStream;
}
বোনাস পয়েন্ট
-
getUserMedia()ফাংশনে পাস করাlocalStreamঅবজেক্টটি গ্লোবাল স্কোপে থাকে, তাই আপনি ব্রাউজার কনসোল থেকে এটি দেখতে পারেন: কনসোল খুলুন, stream টাইপ করুন এবং Return চাপুন। (ক্রোমে কনসোল দেখতে Ctrl-Shift-J চাপুন, অথবা আপনি যদি Mac ব্যবহার করেন তবে Command-Option-J চাপুন।) -
localStream.getVideoTracks()কী রিটার্ন করে? -
localStream.getVideoTracks()[0].stop()কল করার চেষ্টা করুন। - constraints অবজেক্টটি দেখুন: এটিকে
{audio: true, video: true}তে পরিবর্তন করলে কী হয়? - ভিডিও এলিমেন্টটির সাইজ কত? ডিসপ্লে সাইজের পরিবর্তে জাভাস্ক্রিপ্ট থেকে ভিডিওটির আসল সাইজ কীভাবে পাওয়া যায়? এটি যাচাই করতে ক্রোম ডেভ টুলস ব্যবহার করুন।
- ভিডিও এলিমেন্টে CSS ফিল্টার যোগ করার চেষ্টা করুন। উদাহরণস্বরূপ:
video {
filter: blur(4px) invert(1) opacity(0.5);
}
- SVG ফিল্টার যোগ করে দেখুন। উদাহরণস্বরূপ:
video {
filter: hue-rotate(180deg) saturate(200%);
}
আপনি যা শিখেছেন
এই ধাপে আপনি শিখেছেন কীভাবে:
- আপনার ওয়েবক্যাম থেকে ভিডিও নিন।
- মিডিয়া সীমাবদ্ধতা নির্ধারণ করুন।
- ভিডিও উপাদানটি নিয়ে নাড়াচাড়া করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-01 ফোল্ডারে রয়েছে।
টিপস
-
videoএলিমেন্টেautoplayঅ্যাট্রিবিউটটি দিতে ভুলবেন না। সেটি ছাড়া আপনি কেবল একটি ফ্রেম দেখতে পাবেন! -
getUserMedia()কনস্ট্রেইন্ট-এর জন্য আরও অনেক অপশন আছে। webrtc.github.io/samples/src/content/peerconnection/constraints -এ দেওয়া ডেমোটি দেখুন। আপনি দেখতে পাবেন, ঐ সাইটে অনেক আকর্ষণীয় WebRTC স্যাম্পল রয়েছে।
সর্বোত্তম অনুশীলন
- নিশ্চিত করুন যেন আপনার ভিডিও এলিমেন্টটি তার কন্টেইনারের বাইরে চলে না যায়। ভিডিওটির জন্য একটি পছন্দের এবং সর্বোচ্চ আকার নির্ধারণ করতে আমরা
widthএবংmax-widthযোগ করেছি। ব্রাউজারটি উচ্চতা স্বয়ংক্রিয়ভাবে গণনা করবে।
video {
max-width: 100%;
width: 320px;
}
এরপরে
আপনার কাছে ভিডিও আছে, কিন্তু কীভাবে তা স্ট্রিম করবেন? পরবর্তী ধাপে জেনে নিন!
৫. RTCPeerConnection-এর মাধ্যমে ভিডিও স্ট্রিম করুন।
আপনি যা শিখবেন
এই ধাপে আপনি জানতে পারবেন কীভাবে:
- WebRTC শিম, adapter.js ব্যবহার করে ব্রাউজারের পার্থক্যগুলো দূর করুন।
- ভিডিও স্ট্রিম করতে RTCPeerConnection API ব্যবহার করুন।
- মিডিয়া ক্যাপচার এবং স্ট্রিমিং নিয়ন্ত্রণ করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-2 ফোল্ডারে রয়েছে।
RTCPeerConnection বলতে কী বোঝায়?
RTCPeerConnection হলো ভিডিও ও অডিও স্ট্রিম করতে এবং ডেটা আদান-প্রদান করতে WebRTC কল করার একটি API।
এই উদাহরণটি একই পৃষ্ঠায় থাকা দুটি RTCPeerConnection অবজেক্টের (যারা পিয়ার নামে পরিচিত) মধ্যে একটি সংযোগ স্থাপন করে।
ব্যবহারিক ক্ষেত্রে তেমন কাজে না লাগলেও, RTCPeerConnection কীভাবে কাজ করে তা বোঝার জন্য এটি ভালো।
ভিডিও উপাদান এবং নিয়ন্ত্রণ বোতাম যোগ করুন
index.html- এ থাকা একটিমাত্র ভিডিও এলিমেন্টটিকে দুটি ভিডিও এলিমেন্ট এবং তিনটি বাটন দিয়ে প্রতিস্থাপন করুন:
<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>
<div>
<button id="startButton">Start</button>
<button id="callButton">Call</button>
<button id="hangupButton">Hang Up</button>
</div>
একটি ভিডিও এলিমেন্ট getUserMedia() থেকে প্রাপ্ত স্ট্রিমটি প্রদর্শন করবে এবং অন্যটি RTCPeerconnection-এর মাধ্যমে স্ট্রিম করা একই ভিডিওটি দেখাবে। (বাস্তব অ্যাপ্লিকেশনে, একটি ভিডিও এলিমেন্ট লোকাল স্ট্রিম এবং অন্যটি রিমোট স্ট্রিম প্রদর্শন করবে।)
adapter.js শিমটি যোগ করুন
main.js- এর লিঙ্কের উপরে adapter.js- এর বর্তমান সংস্করণের একটি লিঙ্ক যোগ করুন:
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
Index.html এখন দেখতে এইরকম হবে:
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>
<div>
<button id="startButton">Start</button>
<button id="callButton">Call</button>
<button id="hangupButton">Hang Up</button>
</div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
RTCPeerConnection কোডটি ইনস্টল করুন
step-02 ফোল্ডারে থাকা ভার্সনটি দিয়ে main.js প্রতিস্থাপন করুন।
ফোন করুন
index.html খুলুন, আপনার ওয়েবক্যাম থেকে ভিডিও পেতে স্টার্ট বাটনে ক্লিক করুন এবং পিয়ার কানেকশন তৈরি করতে কল-এ ক্লিক করুন। আপনি উভয় ভিডিও এলিমেন্টেই একই ভিডিও (আপনার ওয়েবক্যাম থেকে) দেখতে পাবেন। WebRTC লগিং দেখতে ব্রাউজার কনসোল দেখুন।
এটি কীভাবে কাজ করে
এই পদক্ষেপটি অনেক কিছু করে...
WebRTC, পিয়ার নামে পরিচিত WebRTC ক্লায়েন্টদের মধ্যে ভিডিও স্ট্রিম করার জন্য সংযোগ স্থাপন করতে RTCPeerConnection API ব্যবহার করে।
এই উদাহরণে, দুটি RTCPeerConnection অবজেক্ট একই পেজে রয়েছে: pc1 এবং pc2 । এর তেমন কোনো ব্যবহারিক উপযোগিতা নেই, তবে API-গুলো কীভাবে কাজ করে তা দেখানোর জন্য এটি বেশ ভালো।
WebRTC পিয়ারদের মধ্যে একটি কল স্থাপন করতে তিনটি কাজ করতে হয়:
- কলের প্রতিটি প্রান্তের জন্য একটি RTCPeerConnection তৈরি করুন এবং উভয় প্রান্তে
getUserMedia()থেকে প্রাপ্ত লোকাল স্ট্রিমটি যোগ করুন। - নেটওয়ার্ক তথ্য সংগ্রহ ও আদান-প্রদান করুন: সম্ভাব্য সংযোগ প্রান্তবিন্দুগুলো ICE ক্যান্ডিডেট নামে পরিচিত।
- স্থানীয় ও দূরবর্তী বিবরণ সংগ্রহ ও শেয়ার করুন: SDP ফরম্যাটে স্থানীয় মিডিয়া সম্পর্কিত মেটাডেটা।
ধরে নিন যে অ্যালিস এবং বব একটি ভিডিও চ্যাট চালু করার জন্য RTCPeerConnection ব্যবহার করতে চান।
প্রথমে, অ্যালিস এবং বব নেটওয়ার্কের তথ্য বিনিময় করে। 'প্রার্থী খোঁজা' বলতে ICE ফ্রেমওয়ার্ক ব্যবহার করে নেটওয়ার্ক ইন্টারফেস ও পোর্ট খুঁজে বের করার প্রক্রিয়াকে বোঝায়।
- অ্যালিস একটি
onicecandidate (addEventListener('icecandidate'))হ্যান্ডলার সহ একটি RTCPeerConnection অবজেক্ট তৈরি করে। এটি main.js- এর নিম্নলিখিত কোডের সাথে সঙ্গতিপূর্ণ:
let localPeerConnection;
localPeerConnection = new RTCPeerConnection(servers);
localPeerConnection.addEventListener('icecandidate', handleConnection);
localPeerConnection.addEventListener(
'iceconnectionstatechange', handleConnectionChange);
- অ্যালিস
getUserMedia()কল করে এবং তাতে পাস করা স্ট্রিমটি যোগ করে:
navigator.mediaDevices.getUserMedia(mediaStreamConstraints).
then(gotLocalMediaStream).
catch(handleLocalMediaStreamError);
function gotLocalMediaStream(mediaStream) {
localVideo.srcObject = mediaStream;
localStream = mediaStream;
trace('Received local stream.');
callButton.disabled = false; // Enable call button.
}
localPeerConnection.addStream(localStream);
trace('Added local stream to localPeerConnection.');
- ধাপ ১-এর
onicecandidateহ্যান্ডলারটি তখন কল করা হয় যখন নেটওয়ার্ক ক্যান্ডিডেট উপলব্ধ হয়। - অ্যালিস ববের কাছে সিরিয়ালাইজড ক্যান্ডিডেট ডেটা পাঠায়। একটি বাস্তব অ্যাপ্লিকেশনে, এই প্রক্রিয়াটি (যা সিগন্যালিং নামে পরিচিত) একটি মেসেজিং সার্ভিসের মাধ্যমে সম্পন্ন হয় – পরবর্তী ধাপে আপনি শিখবেন কীভাবে তা করতে হয়। অবশ্যই, এই ধাপে, দুটি RTCPeerConnection অবজেক্ট একই প্ল্যাটফর্মে থাকে এবং কোনো বাহ্যিক মেসেজিংয়ের প্রয়োজন ছাড়াই সরাসরি যোগাযোগ করতে পারে।
- যখন বব অ্যালিসের কাছ থেকে একটি ক্যান্ডিডেট মেসেজ পায়, তখন সে ক্যান্ডিডেটটিকে রিমোট পিয়ার ডেসক্রিপশনে যুক্ত করার জন্য
addIceCandidate()কল করে:
function handleConnection(event) {
const peerConnection = event.target;
const iceCandidate = event.candidate;
if (iceCandidate) {
const newIceCandidate = new RTCIceCandidate(iceCandidate);
const otherPeer = getOtherPeer(peerConnection);
otherPeer.addIceCandidate(newIceCandidate)
.then(() => {
handleConnectionSuccess(peerConnection);
}).catch((error) => {
handleConnectionFailure(peerConnection, error);
});
trace(`${getPeerName(peerConnection)} ICE candidate:\n` +
`${event.candidate.candidate}.`);
}
}
WebRTC পিয়ারদের স্থানীয় এবং দূরবর্তী অডিও ও ভিডিও মিডিয়ার তথ্য, যেমন রেজোলিউশন এবং কোডেক সক্ষমতা, খুঁজে বের করতে এবং আদান-প্রদান করতে হয়। মিডিয়া কনফিগারেশন তথ্য আদান-প্রদানের জন্য সংকেত প্রেরণ প্রক্রিয়াটি সেশন ডেসক্রিপশন প্রোটোকল ( SDP) ফরম্যাট ব্যবহার করে মেটাডেটার ব্লব বিনিময়ের মাধ্যমে সম্পন্ন হয়, যা অফার এবং অ্যানসার নামে পরিচিত।
- অ্যালিস RTCPeerConnection-এর
createOffer()মেথডটি চালায়। ফেরত আসা প্রমিসটি একটি RTCSessionDescription প্রদান করে: যা হলো অ্যালিসের লোকাল সেশনের বিবরণ।
trace('localPeerConnection createOffer start.');
localPeerConnection.createOffer(offerOptions)
.then(createdOffer).catch(setSessionDescriptionError);
- সফল হলে, অ্যালিস
setLocalDescription()ব্যবহার করে স্থানীয় বিবরণ সেট করে এবং তারপর এই সেশন বিবরণটি তাদের সিগন্যালিং চ্যানেলের মাধ্যমে ববের কাছে পাঠায়। - বব
setRemoteDescription()ব্যবহার করে অ্যালিসের পাঠানো বিবরণটিকে রিমোট বিবরণ হিসেবে সেট করে। - বব, অ্যালিসের কাছ থেকে পাওয়া রিমোট ডেসক্রিপশনটি পাস করে RTCPeerConnection-এর
createAnswer()মেথডটি চালায়, যাতে তার সেশনের সাথে সামঞ্জস্যপূর্ণ একটি লোকাল সেশন তৈরি করা যায়।createAnswer()প্রমিসটি একটি RTCSessionDescription পাস করে: বব সেটিকে লোকাল ডেসক্রিপশন হিসেবে সেট করে অ্যালিসের কাছে পাঠিয়ে দেয়। - যখন অ্যালিস ববের সেশন বিবরণ পায়, তখন সে
setRemoteDescription()ব্যবহার করে সেটিকে রিমোট বিবরণ হিসেবে সেট করে।
// Logs offer creation and sets peer connection session descriptions.
function createdOffer(description) {
trace(`Offer from localPeerConnection:\n${description.sdp}`);
trace('localPeerConnection setLocalDescription start.');
localPeerConnection.setLocalDescription(description)
.then(() => {
setLocalDescriptionSuccess(localPeerConnection);
}).catch(setSessionDescriptionError);
trace('remotePeerConnection setRemoteDescription start.');
remotePeerConnection.setRemoteDescription(description)
.then(() => {
setRemoteDescriptionSuccess(remotePeerConnection);
}).catch(setSessionDescriptionError);
trace('remotePeerConnection createAnswer start.');
remotePeerConnection.createAnswer()
.then(createdAnswer)
.catch(setSessionDescriptionError);
}
// Logs answer to offer creation and sets peer connection session descriptions.
function createdAnswer(description) {
trace(`Answer from remotePeerConnection:\n${description.sdp}.`);
trace('remotePeerConnection setLocalDescription start.');
remotePeerConnection.setLocalDescription(description)
.then(() => {
setLocalDescriptionSuccess(remotePeerConnection);
}).catch(setSessionDescriptionError);
trace('localPeerConnection setRemoteDescription start.');
localPeerConnection.setRemoteDescription(description)
.then(() => {
setRemoteDescriptionSuccess(localPeerConnection);
}).catch(setSessionDescriptionError);
}
- পিং!
বোনাস পয়েন্ট
- chrome://webrtc-internals দেখুন। এটি WebRTC-এর পরিসংখ্যান এবং ডিবাগিং ডেটা প্রদান করে। (Chrome URL-গুলির একটি সম্পূর্ণ তালিকা chrome://about- এ রয়েছে।)
- CSS দিয়ে পেজটি স্টাইল করুন:
- ভিডিওগুলো পাশাপাশি রাখুন।
- বাটনগুলোর প্রস্থ একই রাখুন এবং লেখাগুলো বড় করুন।
- নিশ্চিত করুন যে লেআউটটি মোবাইলে কাজ করে।
- Chrome Dev Tools কনসোল থেকে
localStream,localPeerConnectionএবংremotePeerConnectionদেখুন। - কনসোল থেকে
localPeerConnectionpc1.localDescriptionদেখুন। SDP ফরম্যাটটি দেখতে কেমন?
আপনি যা শিখেছেন
এই ধাপে আপনি শিখেছেন কীভাবে:
- WebRTC শিম, adapter.js ব্যবহার করে ব্রাউজারের পার্থক্যগুলো দূর করুন।
- ভিডিও স্ট্রিম করতে RTCPeerConnection API ব্যবহার করুন।
- মিডিয়া ক্যাপচার এবং স্ট্রিমিং নিয়ন্ত্রণ করুন।
- WebRTC কল সক্ষম করার জন্য পিয়ারদের মধ্যে মিডিয়া এবং নেটওয়ার্ক তথ্য শেয়ার করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-2 ফোল্ডারে রয়েছে।
টিপস
- এই ধাপে শেখার অনেক কিছু আছে! RTCPeerConnection সম্পর্কে আরও বিস্তারিত জানতে webrtc.org ওয়েবসাইটটি দেখুন। এই পৃষ্ঠায় জাভাস্ক্রিপ্ট ফ্রেমওয়ার্কের পরামর্শ রয়েছে — যদি আপনি WebRTC ব্যবহার করতে চান, কিন্তু API-গুলোর জটিলতায় জড়াতে না চান।
- adapter.js শিম সম্পর্কে আরও জানতে adapter.js গিটহাব রিপো দেখুন।
- বিশ্বের সেরা ভিডিও চ্যাট অ্যাপটি দেখতে কেমন তা জানতে চান? তাহলে WebRTC প্রজেক্টের WebRTC কলের জন্য আদর্শ অ্যাপ AppRTC-টি দেখুন: অ্যাপ , কোড । কল সেটআপ হতে ৫০০ মিলিসেকেন্ডেরও কম সময় লাগে।
সর্বোত্তম অনুশীলন
- আপনার কোডকে ভবিষ্যতের জন্য প্রস্তুত করতে, নতুন প্রমিজ-ভিত্তিক এপিআই (API) ব্যবহার করুন এবং adapter.js ব্যবহার করে যেসব ব্রাউজার এগুলো সমর্থন করে না, সেগুলোর সাথে সামঞ্জস্যতা সক্ষম করুন।
এরপরে
এই ধাপে দেখানো হয়েছে কীভাবে পিয়ারদের মধ্যে ভিডিও স্ট্রিম করতে WebRTC ব্যবহার করতে হয় — কিন্তু এই কোডল্যাবটি ডেটা নিয়েও আলোচনা করে!
পরবর্তী ধাপে জেনে নিন কিভাবে RTCDataChannel ব্যবহার করে যেকোনো ডেটা স্ট্রিম করা যায়।
৬. ডেটা আদান-প্রদানের জন্য RTCDataChannel ব্যবহার করুন।
আপনি যা শিখবেন
- WebRTC এন্ডপয়েন্ট (পিয়ার)-গুলোর মধ্যে কীভাবে ডেটা আদান-প্রদান করা যায়।
এই ধাপটির সম্পূর্ণ সংস্করণ step-03 ফোল্ডারে রয়েছে।
আপনার HTML আপডেট করুন
এই ধাপে, আপনি একই পৃষ্ঠার দুটি textarea এলিমেন্টের মধ্যে টেক্সট পাঠাতে WebRTC ডেটা চ্যানেল ব্যবহার করবেন। এটি খুব বেশি দরকারি না হলেও, এটি দেখায় যে কীভাবে WebRTC ডেটা শেয়ার করার পাশাপাশি ভিডিও স্ট্রিমিংয়ের জন্যও ব্যবহার করা যেতে পারে।
index.html থেকে video এবং button এলিমেন্টগুলো সরিয়ে দিয়ে সেগুলোর জায়গায় নিচের HTML কোডটি দিন:
<textarea id="dataChannelSend" disabled
placeholder="Press Start, enter some text, then press Send."></textarea>
<textarea id="dataChannelReceive" disabled></textarea>
<div id="buttons">
<button id="startButton">Start</button>
<button id="sendButton">Send</button>
<button id="closeButton">Stop</button>
</div>
একটি টেক্সট এরিয়া টেক্সট লেখার জন্য ব্যবহৃত হবে, অন্যটি পিয়ারদের মধ্যে স্ট্রিম করা টেক্সট প্রদর্শন করবে।
index.html এখন দেখতে এইরকম হবে:
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<textarea id="dataChannelSend" disabled
placeholder="Press Start, enter some text, then press Send."></textarea>
<textarea id="dataChannelReceive" disabled></textarea>
<div id="buttons">
<button id="startButton">Start</button>
<button id="sendButton">Send</button>
<button id="closeButton">Stop</button>
</div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
আপনার জাভাস্ক্রিপ্ট আপডেট করুন
main.js ফাইলটিকে step-03/js/main.js ফাইলের বিষয়বস্তু দিয়ে প্রতিস্থাপন করুন।
পিয়ারদের মধ্যে ডেটা স্ট্রিমিং চেষ্টা করে দেখুন: index.html খুলুন, পিয়ার সংযোগ সেট আপ করতে Start চাপুন, বাম দিকের textarea কিছু টেক্সট লিখুন, তারপর WebRTC ডেটা চ্যানেল ব্যবহার করে টেক্সটটি স্থানান্তর করতে Send-এ ক্লিক করুন।
এটি কীভাবে কাজ করে
এই কোডটি টেক্সট মেসেজ আদান-প্রদান সক্ষম করতে RTCPeerConnection এবং RTCDataChannel ব্যবহার করে।
এই ধাপের কোডের বেশিরভাগ অংশ RTCPeerConnection উদাহরণের কোডের মতোই।
sendData() এবং createConnection() ফাংশনগুলোতে বেশিরভাগ নতুন কোড রয়েছে:
function createConnection() {
dataChannelSend.placeholder = '';
var servers = null;
pcConstraint = null;
dataConstraint = null;
trace('Using SCTP based data channels');
// For SCTP, reliable and ordered delivery is true by default.
// Add localConnection to global scope to make it visible
// from the browser console.
window.localConnection = localConnection =
new RTCPeerConnection(servers, pcConstraint);
trace('Created local peer connection object localConnection');
sendChannel = localConnection.createDataChannel('sendDataChannel',
dataConstraint);
trace('Created send data channel');
localConnection.onicecandidate = iceCallback1;
sendChannel.onopen = onSendChannelStateChange;
sendChannel.onclose = onSendChannelStateChange;
// Add remoteConnection to global scope to make it visible
// from the browser console.
window.remoteConnection = remoteConnection =
new RTCPeerConnection(servers, pcConstraint);
trace('Created remote peer connection object remoteConnection');
remoteConnection.onicecandidate = iceCallback2;
remoteConnection.ondatachannel = receiveChannelCallback;
localConnection.createOffer().then(
gotDescription1,
onCreateSessionDescriptionError
);
startButton.disabled = true;
closeButton.disabled = false;
}
function sendData() {
var data = dataChannelSend.value;
sendChannel.send(data);
trace('Sent Data: ' + data);
}
RTCDataChannel-এর সিনট্যাক্স ইচ্ছাকৃতভাবে WebSocket-এর অনুরূপ রাখা হয়েছে, যেখানে একটি send() মেথড এবং একটি message ইভেন্ট রয়েছে।
dataConstraint এর ব্যবহার লক্ষ্য করুন। বিভিন্ন ধরনের ডেটা শেয়ারিং সক্ষম করার জন্য ডেটা চ্যানেলগুলো কনফিগার করা যেতে পারে — উদাহরণস্বরূপ, পারফরম্যান্সের চেয়ে নির্ভরযোগ্য ডেলিভারিকে অগ্রাধিকার দেওয়া। আপনি মোজিলা ডেভেলপার নেটওয়ার্ক- এ অপশনগুলো সম্পর্কে আরও তথ্য জানতে পারবেন।
বোনাস পয়েন্ট
- WebRTC ডেটা চ্যানেল দ্বারা ব্যবহৃত প্রোটোকল SCTP- তে, নির্ভরযোগ্য এবং সুশৃঙ্খল ডেটা ডেলিভারি ডিফল্টরূপে চালু থাকে। কখন RTCDataChannel-এর নির্ভরযোগ্য ডেটা ডেলিভারির প্রয়োজন হতে পারে, এবং কখন পারফরম্যান্স বেশি গুরুত্বপূর্ণ হতে পারে — এমনকি যদি তার জন্য কিছু ডেটা হারাতেও হয়?
- পেজের লেআউট উন্নত করতে CSS ব্যবহার করুন এবং 'dataChannelReceive' টেক্সটএরিয়াতে একটি প্লেসহোল্ডার অ্যাট্রিবিউট যোগ করুন।
- মোবাইল ডিভাইসে পৃষ্ঠাটি পরীক্ষা করুন।
আপনি যা শিখেছেন
এই ধাপে আপনি শিখেছেন কীভাবে:
- দুটি WebRTC পিয়ারের মধ্যে একটি সংযোগ স্থাপন করুন।
- পিয়ারদের মধ্যে টেক্সট ডেটা আদান-প্রদান করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-03 ফোল্ডারে রয়েছে।
আরও জানুন
- WebRTC ডেটা চ্যানেল (দুই বছর আগের লেখা, কিন্তু এখনও পড়ার মতো)
- WebRTC-এর ডেটা চ্যানেলের জন্য SCTP কেন নির্বাচন করা হয়েছিল?
এরপরে
আপনি একই প্ল্যাটফর্মে থাকা পিয়ারদের মধ্যে ডেটা আদান-প্রদান করতে শিখেছেন, কিন্তু ভিন্ন ভিন্ন মেশিনের মধ্যে এটি কীভাবে করবেন? প্রথমত, মেটাডেটা মেসেজ আদান-প্রদানের জন্য আপনাকে একটি সিগন্যালিং চ্যানেল সেট আপ করতে হবে। পরবর্তী ধাপে জানুন কীভাবে তা করবেন!
৭. বার্তা আদান-প্রদানের জন্য একটি সংকেত পরিষেবা স্থাপন করুন।
আপনি যা শিখবেন
এই ধাপে আপনি জানতে পারবেন কীভাবে:
- package.json- এ উল্লেখিত নির্দেশনা অনুযায়ী প্রজেক্টের ডিপেন্ডেন্সিগুলো ইনস্টল করতে
npmব্যবহার করুন। - একটি Node.js সার্ভার চালান এবং স্ট্যাটিক ফাইল পরিবেশন করতে node-static ব্যবহার করুন।
- Socket.IO ব্যবহার করে Node.js-এ একটি মেসেজিং সার্ভিস সেট আপ করুন।
- সেটি ব্যবহার করে 'রুম' তৈরি করুন এবং বার্তা আদান-প্রদান করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-04 ফোল্ডারে রয়েছে।
ধারণা
একটি WebRTC কল স্থাপন ও বজায় রাখার জন্য, WebRTC ক্লায়েন্টদের (পিয়ার) মেটাডেটা আদান-প্রদান করতে হয়:
- প্রার্থী (নেটওয়ার্ক) তথ্য।
- মিডিয়া সম্পর্কিত তথ্য, যেমন রেজোলিউশন এবং কোডেক সংক্রান্ত বার্তা প্রদান করুন এবং উত্তর দিন ।
অন্য কথায়, অডিও, ভিডিও বা ডেটার পিয়ার-টু-পিয়ার স্ট্রিমিং শুরু হওয়ার আগে মেটাডেটার আদান-প্রদান প্রয়োজন। এই প্রক্রিয়াটিকে সিগন্যালিং বলা হয়।
পূর্ববর্তী ধাপগুলোতে, প্রেরক এবং প্রাপক RTCPeerConnection অবজেক্টগুলো একই প্ল্যাটফর্মে থাকে, তাই 'সিগন্যালিং' হলো কেবল অবজেক্টগুলোর মধ্যে মেটাডেটা আদান-প্রদান করার একটি বিষয়।
বাস্তব প্রয়োগে, প্রেরক এবং প্রাপক RTCPeerConnection-গুলো ভিন্ন ভিন্ন ডিভাইসের ওয়েব পেজে চলে, এবং তাদের মধ্যে মেটাডেটা আদান-প্রদানের জন্য একটি উপায় প্রয়োজন হয়।
এর জন্য, আপনি একটি সিগন্যালিং সার্ভার ব্যবহার করেন: এমন একটি সার্ভার যা WebRTC ক্লায়েন্টদের (পিয়ার) মধ্যে বার্তা আদান-প্রদান করতে পারে। প্রকৃত বার্তাগুলো হলো সাধারণ টেক্সট: স্ট্রিং-এ রূপান্তরিত জাভাস্ক্রিপ্ট অবজেক্ট।
পূর্বশর্ত: Node.js ইনস্টল করতে হবে।
এই কোডল্যাবের পরবর্তী ধাপগুলো ( স্টেপ-০৪ থেকে স্টেপ-০৬ ফোল্ডার) চালানোর জন্য আপনাকে নোড.জেএস (Node.js) ব্যবহার করে লোকালহোস্টে একটি সার্ভার চালু করতে হবে।
আপনি এই লিঙ্ক থেকে অথবা আপনার পছন্দের প্যাকেজ ম্যানেজারের মাধ্যমে Node.js ডাউনলোড ও ইনস্টল করতে পারেন।
একবার ইনস্টল হয়ে গেলে, আপনি পরবর্তী ধাপগুলোর জন্য প্রয়োজনীয় ডিপেন্ডেন্সিগুলো ইম্পোর্ট করতে পারবেন ( npm install চালিয়ে), সেইসাথে কোডল্যাবটি চালানোর জন্য একটি ছোট লোকালহোস্ট সার্ভারও চালু করতে পারবেন ( node index.js চালিয়ে)। এই কমান্ডগুলো যখন প্রয়োজন হবে, তখন পরে তা উল্লেখ করা হবে।
অ্যাপটি সম্পর্কে
WebRTC একটি ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট এপিআই ব্যবহার করে, কিন্তু বাস্তব ব্যবহারের জন্য একটি সিগন্যালিং (মেসেজিং) সার্ভার, সেইসাথে STUN এবং TURN সার্ভারেরও প্রয়োজন হয়। আপনি এখানে আরও জানতে পারবেন।
এই ধাপে আপনি মেসেজিংয়ের জন্য Socket.IO Node.js মডিউল এবং জাভাস্ক্রিপ্ট লাইব্রেরি ব্যবহার করে একটি সাধারণ Node.js সিগন্যালিং সার্ভার তৈরি করবেন। Node.js এবং Socket.IO সম্পর্কে অভিজ্ঞতা থাকলে সুবিধা হবে, তবে তা অপরিহার্য নয়; কারণ মেসেজিং উপাদানগুলো খুবই সরল।
এই উদাহরণে, সার্ভারটি (Node.js অ্যাপ্লিকেশন) index.js- এ এবং এর উপর চালিত ক্লায়েন্টটি (ওয়েব অ্যাপ) index.html- এ তৈরি করা হয়েছে।
এই ধাপের Node.js অ্যাপ্লিকেশনটিতে দুটি কাজ রয়েছে।
প্রথমত, এটি বার্তা রিলে হিসেবে কাজ করে:
socket.on('message', function (message) {
log('Got message: ', message);
socket.broadcast.emit('message', message);
});
দ্বিতীয়ত, এটি WebRTC ভিডিও চ্যাট 'রুম' পরিচালনা করে:
if (numClients === 0) {
socket.join(room);
socket.emit('created', room, socket.id);
} else if (numClients === 1) {
socket.join(room);
socket.emit('joined', room, socket.id);
io.sockets.in(room).emit('ready');
} else { // max two clients
socket.emit('full', room);
}
আমাদের সাধারণ WebRTC অ্যাপ্লিকেশনটি সর্বোচ্চ দুইজন পিয়ারকে একটি রুম শেয়ার করার অনুমতি দেবে।
এইচটিএমএল এবং জাভাস্ক্রিপ্ট
index.html ফাইলটি আপডেট করে এইরকম করুন:
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<script src="/socket.io/socket.io.js"></script>
<script src="js/main.js"></script>
</body>
</html>
এই ধাপে আপনি পৃষ্ঠায় কিছুই দেখতে পাবেন না: সমস্ত লগিং ব্রাউজার কনসোলে করা হয়। (ক্রোমে কনসোল দেখতে Ctrl-Shift-J চাপুন, অথবা আপনি যদি Mac ব্যবহার করেন তবে Command-Option-J চাপুন।)
js/main.js ফাইলটিকে নিম্নলিখিত দিয়ে প্রতিস্থাপন করুন:
'use strict';
var isInitiator;
window.room = prompt("Enter room name:");
var socket = io.connect();
if (room !== "") {
console.log('Message from client: Asking to join room ' + room);
socket.emit('create or join', room);
}
socket.on('created', function(room, clientId) {
isInitiator = true;
});
socket.on('full', function(room) {
console.log('Message from client: Room ' + room + ' is full :^(');
});
socket.on('ipaddr', function(ipaddr) {
console.log('Message from client: Server IP address is ' + ipaddr);
});
socket.on('joined', function(room, clientId) {
isInitiator = false;
});
socket.on('log', function(array) {
console.log.apply(console, array);
});
Node.js-এ চালানোর জন্য Socket.IO সেট আপ করুন।
HTML ফাইলে, আপনি হয়তো দেখে থাকবেন যে আপনি একটি Socket.IO ফাইল ব্যবহার করছেন:
<script src="/socket.io/socket.io.js"></script>
আপনার ওয়ার্ক ডিরেক্টরির সর্বোচ্চ স্তরে package.json নামে একটি ফাইল তৈরি করুন এবং তাতে নিম্নলিখিত বিষয়বস্তু রাখুন:
{
"name": "webrtc-codelab",
"version": "0.0.1",
"description": "WebRTC codelab",
"dependencies": {
"node-static": "^0.7.10",
"socket.io": "^1.2.0"
}
}
এটি একটি অ্যাপ ম্যানিফেস্ট যা নোড প্যাকেজ ম্যানেজারকে ( npm ) বলে দেয় যে প্রোজেক্টের কোন কোন ডিপেন্ডেন্সি ইনস্টল করতে হবে।
ডিপেন্ডেন্সি (যেমন /socket.io/socket.io.js ) ইনস্টল করতে, আপনার ওয়ার্ক ডিরেক্টরিতে কমান্ড লাইন টার্মিনাল থেকে নিম্নলিখিত কমান্ডটি চালান:
npm install
আপনি একটি ইনস্টলেশন লগ দেখতে পাবেন যার শেষে এইরকম কিছু থাকবে:

আপনি দেখতে পাচ্ছেন, npm package.json- এ সংজ্ঞায়িত নির্ভরতাগুলো ইনস্টল করেছে।
আপনার ওয়ার্ক ডিরেক্টরির শীর্ষে ( js ডিরেক্টরির ভিতরে নয়) index.js নামে একটি নতুন ফাইল তৈরি করুন এবং নিম্নলিখিত কোডটি যোগ করুন:
'use strict';
var os = require('os');
var nodeStatic = require('node-static');
var http = require('http');
var socketIO = require('socket.io');
var fileServer = new(nodeStatic.Server)();
var app = http.createServer(function(req, res) {
fileServer.serve(req, res);
}).listen(8080);
var io = socketIO.listen(app);
io.sockets.on('connection', function(socket) {
// convenience function to log server messages on the client
function log() {
var array = ['Message from server:'];
array.push.apply(array, arguments);
socket.emit('log', array);
}
socket.on('message', function(message) {
log('Client said: ', message);
// for a real app, would be room-only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', function(room) {
log('Received request to create or join room ' + room);
var clientsInRoom = io.sockets.adapter.rooms[room];
var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
log('Room ' + room + ' now has ' + numClients + ' client(s)');
if (numClients === 0) {
socket.join(room);
log('Client ID ' + socket.id + ' created room ' + room);
socket.emit('created', room, socket.id);
} else if (numClients === 1) {
log('Client ID ' + socket.id + ' joined room ' + room);
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room, socket.id);
io.sockets.in(room).emit('ready');
} else { // max two clients
socket.emit('full', room);
}
});
socket.on('ipaddr', function() {
var ifaces = os.networkInterfaces();
for (var dev in ifaces) {
ifaces[dev].forEach(function(details) {
if (details.family === 'IPv4' && details.address !== '127.0.0.1') {
socket.emit('ipaddr', details.address);
}
});
}
});
});
কমান্ড লাইন টার্মিনাল থেকে, ওয়ার্ক ডিরেক্টরিতে নিম্নলিখিত কমান্ডটি চালান:
node index.js
আপনার ব্রাউজার থেকে localhost:8080 খুলুন।
প্রতিবার এই ইউআরএলটি খোলার সময় আপনাকে একটি রুমের নাম লিখতে বলা হবে। একই রুমে যোগ দেওয়ার জন্য, প্রতিবার একই রুমের নাম বেছে নিন, যেমন 'foo'।
একটি নতুন ট্যাব পেজ খুলুন এবং আবার localhost:8080 খুলুন। একই রুমের নামটি বেছে নিন।
তৃতীয় একটি ট্যাব বা উইন্ডোতে localhost:8080 খুলুন। আবার একই রুমের নামটি বেছে নিন।
প্রতিটি ট্যাবের কনসোলটি দেখুন: সেখানে আপনি উপরের জাভাস্ক্রিপ্টের লগিং দেখতে পাবেন।
বোনাস পয়েন্ট
- আর কী কী বিকল্প বার্তা আদান-প্রদানের পদ্ধতি সম্ভব হতে পারে? 'বিশুদ্ধ' ওয়েবসকেট ব্যবহারে আপনি কী কী সমস্যার সম্মুখীন হতে পারেন?
- এই অ্যাপ্লিকেশনটির পরিধি বাড়াতে গেলে কী কী সমস্যা হতে পারে? আপনি কি একই সাথে হাজার হাজার বা লক্ষ লক্ষ রুমের অনুরোধ পরীক্ষা করার জন্য কোনো পদ্ধতি তৈরি করতে পারেন?
- এই অ্যাপটি রুমের নাম পাওয়ার জন্য একটি জাভাস্ক্রিপ্ট প্রম্পট ব্যবহার করে। URL থেকে রুমের নাম পাওয়ার একটি উপায় বের করুন। উদাহরণস্বরূপ, localhost:8080/foo লিখলে রুমের নাম হবে
foo।
আপনি যা শিখেছেন
এই ধাপে, আপনি শিখেছেন কীভাবে:
- package.json-এ উল্লেখিত নির্দেশনা অনুযায়ী প্রজেক্টের ডিপেন্ডেন্সিগুলো ইনস্টল করতে npm ব্যবহার করুন।
- স্ট্যাটিক ফাইলগুলো পরিবেশন করার জন্য একটি Node.js সার্ভার চালান।
- socket.io ব্যবহার করে Node.js-এ একটি মেসেজিং সার্ভিস সেট আপ করুন।
- সেটি ব্যবহার করে 'রুম' তৈরি করুন এবং বার্তা আদান-প্রদান করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-04 ফোল্ডারে রয়েছে।
আরও জানুন
- সকেট.আইও চ্যাট-উদাহরণ রিপো
- বাস্তব জগতে WebRTC: STUN, TURN এবং সিগন্যালিং
- WebRTC-তে 'সিগন্যালিং' শব্দটি
এরপরে
সিগন্যালিং ব্যবহার করে কীভাবে দুজন ব্যবহারকারীকে পিয়ার কানেকশন স্থাপন করতে সক্ষম করা যায়, তা জেনে নিন।
৮. পিয়ার সংযোগ এবং সিগন্যালিং একত্রিত করুন
আপনি যা শিখবেন
এই ধাপে আপনি জানতে পারবেন কীভাবে:
- Node.js-এ Socket.IO ব্যবহার করে একটি WebRTC সিগন্যালিং সার্ভিস চালান।
- পিয়ারদের মধ্যে WebRTC মেটাডেটা আদান-প্রদান করতে সেই পরিষেবাটি ব্যবহার করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-05 ফোল্ডারে রয়েছে।
HTML এবং জাভাস্ক্রিপ্ট প্রতিস্থাপন করুন
index.html ফাইলের বিষয়বস্তু নিম্নলিখিত দ্বারা প্রতিস্থাপন করুন:
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
<link rel="stylesheet" href="/css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<div id="videos">
<video id="localVideo" autoplay muted></video>
<video id="remoteVideo" autoplay></video>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
js/main.js ফাইলটিকে step-05/js/main.js ফাইলের বিষয়বস্তু দিয়ে প্রতিস্থাপন করুন।
Node.js সার্ভারটি চালান
আপনি যদি আপনার ওয়ার্ক ডিরেক্টরি থেকে এই কোডল্যাবটি অনুসরণ না করেন, তাহলে আপনাকে step-05 ফোল্ডারে বা আপনার বর্তমান ওয়ার্কিং ফোল্ডারে ডিপেন্ডেন্সিগুলো ইনস্টল করতে হতে পারে। আপনার ওয়ার্কিং ডিরেক্টরি থেকে নিম্নলিখিত কমান্ডটি চালান:
npm install
ইনস্টল করার পরে, যদি আপনার Node.js সার্ভারটি চালু না থাকে, তাহলে work ডিরেক্টরিতে নিম্নলিখিত কমান্ডটি চালিয়ে এটি চালু করুন:
node index.js
নিশ্চিত করুন যে আপনি পূর্ববর্তী ধাপের index.js সংস্করণটি ব্যবহার করছেন, যেটি Socket.IO প্রয়োগ করে। Node এবং Socket IO সম্পর্কে আরও তথ্যের জন্য, "বার্তা আদান-প্রদানের জন্য একটি সিগন্যালিং পরিষেবা সেট আপ করুন" বিভাগটি পর্যালোচনা করুন।
আপনার ব্রাউজার থেকে localhost:8080 খুলুন।
একটি নতুন ট্যাব বা উইন্ডোতে localhost:8080 আবার খুলুন। একটি ভিডিও এলিমেন্টে getUserMedia() থেকে আসা লোকাল স্ট্রিমটি প্রদর্শিত হবে এবং অন্যটিতে RTCPeerconnection-এর মাধ্যমে স্ট্রিম করা 'রিমোট' ভিডিওটি দেখানো হবে।
ব্রাউজার কনসোলে লগিং দেখুন।
বোনাস পয়েন্ট
- এই অ্যাপ্লিকেশনটি শুধুমাত্র এক-এক ভিডিও চ্যাট সমর্থন করে। একাধিক ব্যক্তি যাতে একই ভিডিও চ্যাট রুম ব্যবহার করতে পারে, তার জন্য আপনি ডিজাইনটি কীভাবে পরিবর্তন করতে পারেন?
- উদাহরণটিতে ‘foo’ রুমের নামটি হার্ড কোড করা আছে। অন্যান্য রুমের নামগুলো সক্রিয় করার সেরা উপায় কী হবে?
- ব্যবহারকারীরা কীভাবে রুমের নাম শেয়ার করবে? রুমের নাম শেয়ার করার একটি বিকল্প ব্যবস্থা তৈরি করার চেষ্টা করুন।
- আপনি কীভাবে অ্যাপটি পরিবর্তন করতে পারেন
আপনি যা শিখেছেন
এই ধাপে আপনি শিখেছেন কীভাবে:
- Node.js-এ Socket.IO ব্যবহার করে একটি WebRTC সিগন্যালিং সার্ভিস চালান।
- পিয়ারদের মধ্যে WebRTC মেটাডেটা আদান-প্রদান করতে সেই পরিষেবাটি ব্যবহার করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-05 ফোল্ডারে রয়েছে।
টিপস
- WebRTC-এর পরিসংখ্যান ও ডিবাগ ডেটা chrome://webrtc-internals থেকে পাওয়া যায়।
- আপনার স্থানীয় পরিবেশ যাচাই করতে এবং আপনার ক্যামেরা ও মাইক্রোফোন পরীক্ষা করতে test.webrtc.org ব্যবহার করা যেতে পারে।
- ক্যাশিং নিয়ে কোনো অস্বাভাবিক সমস্যা হলে, নিম্নলিখিতগুলি চেষ্টা করুন:
- Ctrl চেপে ধরে রিলোড বাটনে ক্লিক করে হার্ড রিফ্রেশ করুন।
- ব্রাউজারটি পুনরায় চালু করুন
- কমান্ড লাইন থেকে
npm cache cleanচালান।
এরপরে
কীভাবে ছবি তুলতে হয়, ছবির ডেটা সংগ্রহ করতে হয় এবং দূরবর্তী পিয়ারদের মধ্যে তা শেয়ার করতে হয়, তা জেনে নিন।
৯. একটি ছবি তুলুন এবং ডেটা চ্যানেলের মাধ্যমে তা শেয়ার করুন।
আপনি যা শিখবেন
এই ধাপে আপনি শিখবেন কীভাবে:
- একটি ছবি তুলুন এবং ক্যানভাস এলিমেন্ট ব্যবহার করে সেটির ডেটা সংগ্রহ করুন।
- দূরবর্তী ব্যবহারকারীর সাথে ছবির ডেটা আদান-প্রদান করুন।
এই ধাপটির সম্পূর্ণ সংস্করণ step-06 ফোল্ডারে রয়েছে।
এটি কীভাবে কাজ করে
পূর্বে আপনি শিখেছেন কীভাবে RTCDataChannel ব্যবহার করে টেক্সট মেসেজ আদান-প্রদান করতে হয়।
এই ধাপটি সম্পূর্ণ ফাইল শেয়ার করা সম্ভব করে তোলে: এই উদাহরণে, getUserMedia() এর মাধ্যমে তোলা ছবি।
এই ধাপের মূল অংশগুলো নিম্নরূপ:
- একটি ডেটা চ্যানেল স্থাপন করুন। মনে রাখবেন, এই ধাপে পিয়ার কানেকশনে কোনো মিডিয়া স্ট্রিম যোগ করবেন না।
-
getUserMedia()ব্যবহার করে ব্যবহারকারীর ওয়েবক্যাম ভিডিও স্ট্রিম ক্যাপচার করুন:
var video = document.getElementById('video');
function grabWebCamVideo() {
console.log('Getting user media (video) ...');
navigator.mediaDevices.getUserMedia({
video: true
})
.then(gotStream)
.catch(function(e) {
alert('getUserMedia() error: ' + e.name);
});
}
- যখন ব্যবহারকারী স্ন্যাপ বোতামে ক্লিক করেন, তখন ভিডিও স্ট্রিম থেকে একটি স্ন্যাপশট (একটি ভিডিও ফ্রেম) নিন এবং সেটি একটি
canvasএলিমেন্টে প্রদর্শন করুন:
var photo = document.getElementById('photo');
var photoContext = photo.getContext('2d');
function snapPhoto() {
photoContext.drawImage(video, 0, 0, photo.width, photo.height);
show(photo, sendBtn);
}
- যখন ব্যবহারকারী 'Send' বোতামে ক্লিক করেন, তখন ছবিটিকে বাইটে রূপান্তর করে একটি ডেটা চ্যানেলের মাধ্যমে পাঠিয়ে দিন:
function sendPhoto() {
// Split data channel message in chunks of this byte length.
var CHUNK_LEN = 64000;
var img = photoContext.getImageData(0, 0, photoContextW, photoContextH),
len = img.data.byteLength,
n = len / CHUNK_LEN | 0;
console.log('Sending a total of ' + len + ' byte(s)');
dataChannel.send(len);
// split the photo and send in chunks of about 64KB
for (var i = 0; i < n; i++) {
var start = i * CHUNK_LEN,
end = (i + 1) * CHUNK_LEN;
console.log(start + ' - ' + (end - 1));
dataChannel.send(img.data.subarray(start, end));
}
// send the reminder, if any
if (len % CHUNK_LEN) {
console.log('last ' + len % CHUNK_LEN + ' byte(s)');
dataChannel.send(img.data.subarray(n * CHUNK_LEN));
}
}
- প্রাপক প্রান্ত ডেটা চ্যানেল মেসেজ বাইটগুলোকে পুনরায় একটি ছবিতে রূপান্তর করে এবং ছবিটি ব্যবহারকারীকে প্রদর্শন করে:
function receiveDataChromeFactory() {
var buf, count;
return function onmessage(event) {
if (typeof event.data === 'string') {
buf = window.buf = new Uint8ClampedArray(parseInt(event.data));
count = 0;
console.log('Expecting a total of ' + buf.byteLength + ' bytes');
return;
}
var data = new Uint8ClampedArray(event.data);
buf.set(data, count);
count += data.byteLength;
console.log('count: ' + count);
if (count === buf.byteLength) {
// we're done: all data chunks have been received
console.log('Done. Rendering photo.');
renderPhoto(buf);
}
};
}
function renderPhoto(data) {
var canvas = document.createElement('canvas');
canvas.width = photoContextW;
canvas.height = photoContextH;
canvas.classList.add('incomingPhoto');
// trail is the element holding the incoming images
trail.insertBefore(canvas, trail.firstChild);
var context = canvas.getContext('2d');
var img = context.createImageData(photoContextW, photoContextH);
img.data.set(data);
context.putImageData(img, 0, 0);
}
কোডটি নিন
আপনার work ফোল্ডারের বিষয়বস্তু ধাপ-০৬ এর বিষয়বস্তু দিয়ে প্রতিস্থাপন করুন। আপনার work ফোল্ডারের index.html ফাইলটি এখন দেখতে এইরকম হবে:
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
<link rel="stylesheet" href="/css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<h2>
<span>Room URL: </span><span id="url">...</span>
</h2>
<div id="videoCanvas">
<video id="camera" autoplay></video>
<canvas id="photo"></canvas>
</div>
<div id="buttons">
<button id="snap">Snap</button><span> then </span><button id="send">Send</button>
<span> or </span>
<button id="snapAndSend">Snap & Send</button>
</div>
<div id="incoming">
<h2>Incoming photos</h2>
<div id="trail"></div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
আপনি যদি আপনার ওয়ার্ক ডিরেক্টরি থেকে এই কোডল্যাবটি অনুসরণ না করেন, তাহলে আপনাকে step-06 ফোল্ডারে বা আপনার বর্তমান ওয়ার্কিং ফোল্ডারে ডিপেন্ডেন্সিগুলো ইনস্টল করতে হতে পারে। আপনার ওয়ার্কিং ডিরেক্টরি থেকে কেবল নিম্নলিখিত কমান্ডটি চালান:
npm install
ইনস্টল করার পরে, যদি আপনার Node.js সার্ভারটি চালু না থাকে, তাহলে আপনার ওয়ার্ক ডিরেক্টরি থেকে নিম্নলিখিত কমান্ডটি কল করে এটি চালু করুন:
node index.js
নিশ্চিত করুন যে আপনি index.js- এর সেই সংস্করণটি ব্যবহার করছেন যা Socket.IO প্রয়োগ করে, এবং কোনো পরিবর্তন করলে আপনার Node.js সার্ভারটি পুনরায় চালু করতে মনে রাখবেন। Node এবং Socket IO সম্পর্কে আরও তথ্যের জন্য, "বার্তা আদান-প্রদানের জন্য একটি সিগন্যালিং পরিষেবা সেট আপ করুন" বিভাগটি পর্যালোচনা করুন।
প্রয়োজনে, অ্যাপটিকে আপনার ওয়েবক্যাম ব্যবহার করার অনুমতি দিতে Allow বাটনে ক্লিক করুন।
অ্যাপটি একটি র্যান্ডম রুম আইডি তৈরি করবে এবং সেই আইডিটি ইউআরএল-এ যোগ করবে। অ্যাড্রেস বার থেকে ইউআরএলটি একটি নতুন ব্রাউজার ট্যাব বা উইন্ডোতে খুলুন।
Snap & Send বোতামটি ক্লিক করুন এবং তারপরে পৃষ্ঠার নীচে অন্য ট্যাবের Incoming অংশটি দেখুন। অ্যাপটি ট্যাবগুলির মধ্যে ছবি স্থানান্তর করে।
আপনার এইরকম কিছু দেখা উচিত:

বোনাস পয়েন্ট
- যেকোনো ধরনের ফাইল শেয়ার করা সম্ভব করতে আপনি কোডটি কীভাবে পরিবর্তন করতে পারেন?
আরও জানুন
- মিডিয়াস্ট্রিম ইমেজ ক্যাপচার এপিআই : ছবি তোলা ও ক্যামেরা নিয়ন্ত্রণের একটি এপিআই — শীঘ্রই আপনার ব্রাউজারে আসছে!
- অডিও এবং ভিডিও রেকর্ডিংয়ের জন্য MediaRecorder API: ডেমো , ডকুমেন্টেশন ।
আপনি যা শিখেছেন
- ক্যানভাস এলিমেন্ট ব্যবহার করে কীভাবে একটি ছবি তোলা যায় এবং তার থেকে ডেটা পাওয়া যায়।
- দূরবর্তী ব্যবহারকারীর সাথে সেই ডেটা কীভাবে আদান-প্রদান করা যায়।
এই ধাপটির সম্পূর্ণ সংস্করণ step-06 ফোল্ডারে রয়েছে।
১০. অভিনন্দন
আপনি রিয়েলটাইম ভিডিও স্ট্রিমিং এবং ডেটা আদান-প্রদানের জন্য একটি অ্যাপ তৈরি করেছেন!
আপনি যা শিখেছেন
এই কোডল্যাবে আপনি শিখেছেন কীভাবে:
- আপনার ওয়েবক্যাম থেকে ভিডিও নিন।
- RTCPeerConnection-এর মাধ্যমে ভিডিও স্ট্রিম করুন।
- RTCDataChannel-এর মাধ্যমে ডেটা স্ট্রিম করুন।
- বার্তা আদান-প্রদানের জন্য একটি সংকেত পরিষেবা স্থাপন করুন।
- পিয়ার সংযোগ এবং সিগন্যালিং একত্রিত করুন।
- একটি ছবি তুলুন এবং ডেটা চ্যানেলের মাধ্যমে শেয়ার করুন।
পরবর্তী পদক্ষেপ
- আদর্শ WebRTC চ্যাট অ্যাপ্লিকেশন AppRTC-এর কোড এবং আর্কিটেকচার দেখুন: অ্যাপ , কোড ।
- github.com/webrtc/samples থেকে লাইভ ডেমোগুলো ব্যবহার করে দেখুন।
আরও জানুন
- WebRTC দিয়ে কাজ শুরু করার জন্য webrtc.org- এ বিভিন্ন ধরনের রিসোর্স পাওয়া যায়।