SSD Nodes Learn 🎉 VPS $5.50/মাস থেকে
নির্দেশিকা Matt Connorদ্বারা Matt Connor

VPS-এ self-hosted video conferencing: bandwidth হিসাব

VPS বাছার আগে participant সংখ্যা অনুযায়ী bandwidth হিসাব করুন। Jitsi, BigBlueButton ও Galène-এর RAM, open UDP ports এবং NAT-এর পেছনে কী ভাঙে তা তুলনা করুন।

VPS-এ self-hosted video conferencing মূলত bandwidth-এর সমস্যা

ছোট server-এ self-hosted video conferencing ব্যর্থ হওয়ার একটি প্রধান কারণ আছে, এবং সেটি প্রায় কখনোই install নয়। আধুনিক প্রায় সব tool যে server component ব্যবহার করে, সেটি হলো SFU (selective forwarding unit)। এটি প্রতিটি participant-এর কাছ থেকে একটি video stream নেয় এবং সেটির একটি copy অন্য প্রতিটি participant-এর কাছে forward করে। ফলে server থেকে বের হওয়া traffic participant-এর সংখ্যা বাড়ার সঙ্গে square অনুপাতে বৃদ্ধি পায়। Shared uplink-সহ 1 GB বা 2 GB VPS-এ software ঠিকভাবে চলবে। কিন্তু আপনি যে all-hands meeting কল্পনা করছেন, সেটির traffic বহন করতে পারবে না।

তাই কাজের ধাপ এই ক্রমে রাখুন। কতজন মানুষ অংশ নেবে তা গণনা করুন, কত megabits প্রয়োজন তা হিসাব করুন, তারপর server নির্বাচন করুন। Install করতে copy ও paste-এর মাধ্যমে বিশ মিনিট লাগে। আপনি কথা বললে অন্যরা শুনতে পারবে কি না, তা uplink নির্ধারণ করে।

অংশগ্রহণকারীর সংখ্যার বর্গের সঙ্গে bandwidth কেন বাড়ে?

Mesh দিয়ে শুরু করা যাক। প্রতিটি browser তার camera-এর video encode করে এবং অন্য প্রতিটি browser-এ সরাসরি একটি করে copy পাঠায়। কোনো media server video-তে হস্তক্ষেপ করে না। দুই ব্যক্তির mesh call-এর জন্য signalling server ছাড়া আর কিছু লাগে না। তাই one-to-one call host করা প্রায় বিনামূল্যে। প্রায় চার বা পাঁচজন হলে mesh কাজ করা বন্ধ করে। কারণ home connection-এ থাকা একটি laptop-কে একই সময়ে নিজের video-এর চার বা পাঁচটি আলাদা copy upload করতে হয়।

SFU ভিন্নভাবে কাজ করে। প্রতিটি browser server-এ একটি copy upload করে। Server RTP (real-time transport protocol) header পড়ে এবং video decode না করেই সেই packet-গুলো অন্য অংশগ্রহণকারীদের কাছে forward করে। এটাই মূল কৌশল। তাই SFU-এর CPU ব্যবহার কম, কিন্তু network ব্যবহার বেশি।

পুরোনো ব্যবস্থা হলো MCU (multipoint control unit)। এটি প্রতিটি incoming stream decode করে, সবগুলোকে একটি ছবিতে composite করে এবং সেই ছবি আবার encode করে। Outbound bandwidth খুব কম। CPU cost অত্যন্ত বেশি। বর্তমানে video-এর জন্য প্রায় কোনো system MCU ব্যবহার করে না। এই guide-ও করে না।

এখন SFU-এর হিসাব করা যাক। ধরে নিন, প্রত্যেকে 1.2 Mbps-এ video পাঠাচ্ছে এবং কারও camera বন্ধ নেই। Server N গুণ 1.2 Mbps গ্রহণ করে। এই পরিমাণ linear এবং সাধারণত সমস্যা তৈরি করে না। Server N গুণ (N minus 1) গুণ 1.2 Mbps পাঠায়। কারণ N জনের প্রত্যেককে অন্য N minus 1টি stream গ্রহণ করতে হয়। দ্বিতীয় সংখ্যাটিই project শেষ করে দেয়।

ChartSFU outbound traffic, arithmetic model at 1.2 Mbps per sender
The data behind this chart
[
  {
    "label": "4 people",
    "sfu_egress_mbps": 14.4,
    "egress_gb_per_hour": 6.5,
    "monthly_volume_tb": 0.13
  },
  {
    "label": "8 people",
    "sfu_egress_mbps": 67.2,
    "egress_gb_per_hour": 30.2,
    "monthly_volume_tb": 0.6
  },
  {
    "label": "15 people",
    "sfu_egress_mbps": 252,
    "egress_gb_per_hour": 113.4,
    "monthly_volume_tb": 2.3
  },
  {
    "label": "30 people",
    "sfu_egress_mbps": "1,044",
    "egress_gb_per_hour": 469.8,
    "monthly_volume_tb": 9.4
  },
  {
    "label": "50 people",
    "sfu_egress_mbps": "2,940",
    "egress_gb_per_hour": "1,323",
    "monthly_volume_tb": 26.5
  }
]

এই সারিগুলো arithmetic, কোনো নির্দিষ্ট server-এর measurement নয়। Monthly column-এ একটি মাসে বিশ ঘণ্টার call ধরা হয়েছে। শেষ সারিটি আগে দেখুন। Camera চালু থাকা পঞ্চাশজনের জন্য একটি machine থেকে স্থায়ীভাবে 2,940 Mbps outbound traffic প্রয়োজন। ত্রিশজনের জন্য প্রয়োজন 1,044 Mbps। চারজনের জন্য প্রয়োজন 14.4 Mbps, যা যেকোনো VPS সহজেই পরিচালনা করতে পারে। চারজনের সারি থেকে ত্রিশজনের সারি পর্যন্ত participant-এর সংখ্যা সাড়ে সাত গুণ বাড়ে, কিন্তু outbound traffic সত্তরেরও বেশি গুণ বাড়ে।

বাস্তব deployment-এ এই সংখ্যার চেয়ে কম traffic লাগে। কীভাবে কমে, তা নির্দিষ্টভাবে জানা গুরুত্বপূর্ণ। Jitsi এবং LiveKit উভয়ই simulcast ব্যবহার করে। Sender একই সময়ে বিভিন্ন quality layer publish করে। Screen-এ না থাকা ব্যক্তিদের কাছে SFU একটি low layer forward করে। Jitsi-তে last-N setting-ও আছে। এটি কেবল সাম্প্রতিক speaker-দের video forward করে। উভয় পদ্ধতিই অনেক traffic সাশ্রয় করে। তবে কোনো পদ্ধতিই curve-এর ধরন পরিবর্তন করে না। সবাই camera চালু করে একে অপরকে pin করলে উভয় পদ্ধতির সুবিধা আর থাকে না।

একটি plan page-এ “1 Gbps port” লেখা থাকতে পারে। এটি virtual network card-এর গতি, next hop সম্পর্কে কোনো নিশ্চয়তা নয়। একই physical host-এর অন্য tenant-দের সঙ্গে এই link ভাগ করা থাকে। তাই ব্যস্ত সময়ে sustained throughput port speed-এর চেয়ে কম হয়, আর conference call ঠিক এমনই sustained load তৈরি করে। বেশিরভাগ plan-এ মাসিক transfer allowance-ও থাকে। এই সীমা অতিক্রম করলে আপনার গতি কমিয়ে দেওয়া হয় অথবা অতিরিক্ত বিল নেওয়া হয়।

Invoice-এ অপ্রত্যাশিত বড় খরচ সাধারণত এই allowance থেকেই আসে। এক মাসে thirty-person call-এর বিশ ঘণ্টায় server থেকে 9.4 TB data বের হয়, প্রতি ঘণ্টায় 469.8 GB হারে। fifty-person call-এর বিশ ঘণ্টায় বের হয় 26.5 TB। RAM-এর পরিমাণ দেখার আগে transfer allowance পরীক্ষা করুন। plan page-এ এটি স্পষ্ট না থাকলে, সেই অস্পষ্টতাই আপনার উত্তর। সস্তা VPS offer সঠিকভাবে পড়া এই workload-এর ক্ষেত্রে প্রায় অন্য যেকোনো workload-এর চেয়ে বেশি গুরুত্বপূর্ণ।

Jitsi Meet: ডিফল্ট পছন্দ, এবং এর প্রয়োজনীয়তা

অধিকাংশ ব্যবহারকারীর Jitsi Meet দিয়েই শুরু করা উচিত। এটি প্রকল্পটির নিজস্ব Debian repository থেকে ইনস্টল হয়, ইনস্টলের সময় nginx ও একটি certificate কনফিগার করে, এবং videobridge (JVB) একটি মাত্র UDP port ব্যবহার করে। ফলে firewall rule-এর সংখ্যা কম থাকে। এর জন্য Debian 11 বা পরবর্তী সংস্করণ, অথবা Ubuntu 22.04 বা পরবর্তী সংস্করণ প্রয়োজন।

sudo apt update
sudo apt install -y apt-transport-https curl gnupg
sudo add-apt-repository universe
sudo apt update
sudo curl -sL https://prosody.im/files/prosody-debian-packages.key -o /usr/share/keyrings/prosody-debian-packages.key
echo "deb [signed-by=/usr/share/keyrings/prosody-debian-packages.key] http://packages.prosody.im/debian $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/prosody-debian-packages.list
sudo apt install -y lua5.2
curl -sL https://download.jitsi.org/jitsi-key.gpg.key | sudo sh -c 'gpg --dearmor > /usr/share/keyrings/jitsi-keyring.gpg'
echo "deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/" | sudo tee /etc/apt/sources.list.d/jitsi-stable.list
sudo apt update
sudo apt install -y jitsi-meet

Installer প্রথমে একটি hostname জানতে চাইবে এবং এরপর certificate-এর ধরন বেছে নেওয়ার সুযোগ দেবে। Let's Encrypt option বেছে নিন এবং এমন একটি domain name দিন, যা ইতিমধ্যে এই server-এর public address-এ resolve হয়। Certificate একটি HTTP challenge-এর মাধ্যমে issue হয়। তাই অন্য কোথাও নির্দেশ করা name দিলে এই ধাপে ব্যর্থ হবে।

এরপর port-গুলো খুলুন। Handbook-এ যে port-গুলো উল্লেখ করা হয়েছে, সেগুলো হলো। প্রথমে SSH রাখুন, যাতে ufw enable আপনাকে server থেকে বিচ্ছিন্ন করে না দেয়:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/udp
sudo ufw allow 3478/udp
sudo ufw allow 5349/tcp
sudo ufw enable

TCP 80 এবং 443 web app চালায় এবং certificate renewal-এর সুযোগ দেয়। সব audio ও video UDP 10000 দিয়ে যায়। এই port-টিই মানুষ প্রায়ই ভুলে যায়। UDP 3478 এবং TCP 5349 সেই coturn server-এর জন্য, যা Jitsi package bridge-এর সঙ্গে ইনস্টল করে। UDP অবরুদ্ধ থাকা network-এর ব্যবহারকারীদের জন্য এটিই fallback path।

sudo systemctl status jitsi-videobridge2
sudo ss -ulnp | grep 10000

প্রথম command-এ service-টির অবস্থা active দেখানো উচিত। দ্বিতীয় command-এ bridge-কে UDP 10000-এ listening অবস্থায় দেখানো উচিত। কোনো output না এলে bridge start হয়নি। /var/log/jitsi/jvb.log কারণটি জানাবে।

Resource sizing-এর ক্ষেত্রে Jitsi-এর handbook নিজস্ব প্রাথমিক নির্দেশনা প্রকাশ করে, আর BigBlueButton তুলনামূলকভাবে অনেক বড় নির্দেশিত আকার প্রকাশ করে:

ChartSizing each project publishes for one production server
The data behind this chart
[
  {
    "label": "Jitsi Meet",
    "ram_gb": 8,
    "cpu_cores": 4,
    "uplink_mbps": "1,000"
  },
  {
    "label": "BigBlueButton 3.0",
    "ram_gb": 16,
    "cpu_cores": 8,
    "uplink_mbps": 250
  }
]

Jitsi-এর handbook একটি production server-এর জন্য 8 GB RAM এবং 4টি dedicated core প্রস্তাব করে। প্রায়ই 1,000 Mbps network uplink যথেষ্ট হয়। একই পৃষ্ঠায় বলা হয়েছে, ছোট setup 4 GB বা 2 GB RAM-এও চলতে পারে। ওই পৃষ্ঠার একটি তথ্য মনে রাখা গুরুত্বপূর্ণ: signalling পরিচালনাকারী XMPP server Prosody মাত্র একটি core ব্যবহার করতে পারে। অতিরিক্ত core bridge-কে সহায়তা করে, কিন্তু signalling-এ কোনো কাজে আসে না।

সবাই কল-এ যোগ দিলেও কেউ ভিডিও দেখতে পাচ্ছে না কেন?

এটি VPS-এ Jitsi-এর সাধারণ সমস্যা। অংশগ্রহণকারীদের তালিকা পূর্ণ হয়, chat কাজ করে, কিন্তু প্রতিটি video tile কালো থাকে। videobridge নিজস্ব interface-এ পাওয়া address-গুলো client-দের জানায়। কোনো provider virtual machine-কে private address দিয়ে তার ওপর public address map করলে JVB শুধু private address-টি খুঁজে পায়। ফলে প্রতিটি client 10.0.0.5-এর মতো কোনো address-এ media পাঠানোর চেষ্টা করে, কিন্তু packet গন্তব্যে পৌঁছায় না।

bridge-কে উভয় address জানান। /etc/jitsi/videobridge/jvb.conf-এ একটি static mapping যোগ করুন:

ice4j {
  harvest {
    mapping {
      static-mappings = [
        {
          local-address = "10.0.0.5"
          public-address = "203.0.113.10"
        }
      ]
    }
  }
}

sudo systemctl restart jitsi-videobridge2 ব্যবহার করে restart করুন। স্থানীয় address ip -4 addr show থেকে নিন এবং public address provider-এর control panel থেকে নিন। পুরোনো guide-গুলো /etc/jitsi/videobridge/sip-communicator.properties-এ org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS এবং org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS key ব্যবহার করে একই configuration করত। সেগুলো এখনও কাজ করে। তবে নতুন install-এ উপরের mapping block ব্যবহার করা উচিত।

অন্য কারণ হতে পারে এমন একটি firewall, যেটি আপনি configure করেননি। অধিকাংশ provider control panel-এ একটি network firewall চালায়, যা server-এ থাকা ufw থেকে আলাদা। UDP 10000 উভয় firewall-এই open থাকতে হবে। কোন layer packet drop করছে তা জানতে, বাইরে থেকে কেউ join করার সময় server-এ sudo tcpdump -ni any udp port 10000 চালান। একটিও packet না এলে machine-এ কিছুই পৌঁছাচ্ছে না। অর্থাৎ block-টি operating system-এর আগের স্তরে আছে। tile কালো থাকা অবস্থায় packet এলে bridge এমন address দিয়ে response দিচ্ছে, যেটিতে client পৌঁছাতে পারছে না। সে ক্ষেত্রে সমস্যা mapping-এ। ufw-এর configuration নিয়ে অনিশ্চিত হলে VPS-এর জন্য আসলে প্রয়োজনীয় ufw rule-এ এমন rule ordering ব্যাখ্যা করা হয়েছে, যা প্রায়ই সমস্যার কারণ হয়।

BigBlueButton: ভারী, নির্দিষ্ট নকশার, এবং এটি পুরো সার্ভার ব্যবহার করতে চায়

BigBlueButton শিক্ষাদানের জন্য তৈরি। এতে whiteboard, breakout room, poll এবং presentation area রয়েছে। এর recording pipeline কোনো অতিরিক্ত সুবিধা নয়; এটি মূল বৈশিষ্ট্যের অংশ। এই তালিকার অন্য বিকল্পগুলোর তুলনায় এটি অনেক বেশি ভারী। এটি বিদ্যমান সার্ভারে যোগ করার মতো কোনো package নয়।

August 2026 অনুযায়ী সমর্থিত পদ্ধতি হলো Ubuntu 22.04-এ BigBlueButton 3.0 ব্যবহার করা। এটি jammy-300 version flag দিয়ে নির্বাচন করা হয়। প্রকল্পের প্রকাশিত production requirement অনুযায়ী swap সক্রিয় রেখে 16 GB memory, উচ্চ single-thread performance-সহ 8 CPU core, 250 Mbps symmetric bandwidth এবং recording সংরক্ষণ করলে 500 GB disk প্রয়োজন। Recording নিষ্ক্রিয় করলে 50 GB disk যথেষ্ট। Port হলো TCP 80 এবং 443, সঙ্গে UDP range 16384 থেকে 32768।

wget -q https://raw.githubusercontent.com/bigbluebutton/bbb-install/v3.0.x-release/bbb-install.sh
less bbb-install.sh
bash bbb-install.sh -w -v jammy-300 -s bbb.example.com -e info@example.com -g

প্রকল্পের নিজস্ব উদাহরণে ওই script সরাসরি bash-এ pipe করা হয়। এর পরিবর্তে script-টি আগে download করে পড়ুন। কারণ এটি আপনার nginx configuration পুনর্লিখে, নিজস্ব media ও audio stack install করে, package version নির্দিষ্ট করে এবং hostname-এর দায়িত্ব নেয়। এটি কোনো ত্রুটি নয়; এটাই নকশা। BigBlueButton ধরে নেয় যে পুরো machine-টির নিয়ন্ত্রণ তার কাছে থাকবে। -w flag firewall configure করে, -s hostname নির্ধারণ করে, -e হলো Let's Encrypt যে address নিবন্ধন করে, এবং -g Greenlight front end যোগ করে। একই box যদি অন্য service-এর জন্যও TLS termination করে, তাহলে BigBlueButton অন্যত্র সরান। অন্যথায় script পরিবর্তন করার আগে আপনার nginx reverse proxy config কী করছে তা ভালোভাবে বুঝে নিন।

ওই chart-এর দুটি row সতর্কতার সঙ্গে তুলনা করুন। Jitsi-এর পরামর্শের তুলনায় BigBlueButton দ্বিগুণ memory এবং দ্বিগুণ core চায়, কিন্তু bandwidth চায় এক-চতুর্থাংশ। দুটি figure একই পদ্ধতিতে মাপা নয় এবং এগুলো ভিন্ন room size ধরে নেওয়া হয়েছে। তাই সরাসরি তুলনা না করে প্রতিটিকে সংশ্লিষ্ট প্রকল্পের প্রাথমিক নির্দেশনা হিসেবে বিবেচনা করুন। CPU-এর পার্থক্য বাস্তব। কারণ BigBlueButton video forward করা ছাড়াও আরও অনেক কাজ করে।

Galène: ছোট বিকল্প

Galène হলো Go-তে লেখা একটি ছোট SFU। এটি একটি একক static binary হিসেবে build হয়, নিজের web client সরবরাহ করে এবং একটি TURN server অন্তর্ভুক্ত করে। তাই চালু রাখার জন্য কোনো XMPP server, Java runtime বা Rails application লাগে না। আপনার প্রয়োজন যদি একটি সীমিত ক্ষমতার server-এ নির্ভরযোগ্য দশজনের call হয়, তাহলে আরও hardware প্রয়োজন বলে সিদ্ধান্ত নেওয়ার আগে এটি চেষ্টা করুন।

sudo apt update && sudo apt install -y git golang-go
git clone https://github.com/jech/galene
cd galene
CGO_ENABLED=0 go build -ldflags='-s -w'
mkdir groups

Ubuntu 24.04-এর golang-go package-এ Go 1.22 রয়েছে। go build যদি module-এর জন্য আরও নতুন Go প্রয়োজন বলে জানায়, distribution package নিয়ে কাজ না করে go.dev থেকে বর্তমান toolchain install করুন।

একটি group হলো Galène-এ room-এর নাম, এবং একটি group একটি JSON file:

echo '{"users": {"vimes": {"password":"sybil", "permissions":"op"}}}' > groups/night-watch.json
./galene &

https://your.server:8443/group/night-watch/ খুলে vimes হিসেবে log in করুন। এই credentials প্রকল্পের README থেকে সরাসরি নেওয়া হয়েছে। তাই port-টি অন্য কোনো স্থান থেকে reachable হওয়ার আগে এগুলো পরিবর্তন করুন। বাস্তব deployment-এর জন্য প্রকল্পটি একটি systemd unit-এর নির্দেশনা দেয়:

[Unit]
Description=Galene
After=network.target

[Service]
Type=simple
WorkingDirectory=/home/galene
User=galene
Group=galene
ExecStart=/home/galene/galene
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Web interface-এর জন্য port হলো TCP 8443। Built-in TURN server-এর জন্য TCP এবং UDP 1194 ব্যবহৃত হয়। Media-এর জন্য high UDP port-এর একটি range ব্যবহৃত হয়। এই range নির্দিষ্ট করে দিন, যাতে এর জন্য একটি firewall rule লিখতে পারেন:

./galene -udp-range 40000-40100

VPS-এ -turn option-টিই গুরুত্বপূর্ণ। -turn ':1194' সব public IPv4 address-এ listen করে। -turn '203.0.113.1:1194' Galène-কে সেই address জানায়, যা client-রা বাস্তবে দেখতে পাবে। Machine-এর নিজস্ব address private হলে এটিই প্রয়োজন। -turn '' built-in server নিষ্ক্রিয় করে, যাতে data/ice-servers.json-এর মাধ্যমে external server নির্ধারণ করতে পারেন। Default হলো auto। কোনো ice-servers.json না থাকলে এটি :1194-এর মতো আচরণ করে।

data/config.json-এ proxyURL সেট করে এবং WebSocket upgrade header-সহ /ws location proxy করে web interface-এর সামনে nginx বসাতে পারেন। এটি কী নিয়ন্ত্রণ করে তা বুঝে নিন। Client-রা এখনও TURN port-এ সরাসরি UDP flow এবং সরাসরি TCP connection খুলবে। তাই reverse proxy শুধু page এবং signalling পরিচালনা করে। Media এর মধ্য দিয়ে যায় না।

Galène-এর documentation অনুযায়ী এর server resource-এর প্রয়োজন খুবই সীমিত। তবে documentation কোনো নির্দিষ্ট সংখ্যা প্রকাশ করে না, তাই নির্দিষ্ট figure আশা করবেন না। উপরের bandwidth-এর হিসাব সম্পূর্ণভাবে প্রযোজ্য। আপনি যে সাশ্রয়টি পান, তা হলো SFU নয় এমন সব কিছুর memory ব্যবহার এবং পরিচালনাগত অতিরিক্ত উপাদান কমে যাওয়া।

Owncast: এক থেকে অনেক, যেখানে bandwidth সরলরৈখিক থাকে

অনেক "video conferencing" প্রয়োজন আসলে এমন একজনের উপস্থাপনা, যা দর্শকেরা chat-এ লিখে অনুসরণ করে। আপনার প্রয়োজন এমন হলে SFU সঠিক tool নয়, এবং খরচের হিসাবও সম্পূর্ণ বদলে যায়। Owncast OBS বা অনুরূপ encoder থেকে একটি RTMP stream গ্রহণ করে এবং সাধারণ HTTPS-এর মাধ্যমে HLS সরবরাহ করে। প্রতি viewer-এর জন্য bandwidth quadratic না হয়ে linear থাকে। Output সাধারণ HTTP segment হওয়ায় এটি object storage বা CDN-এর পিছনে স্থানান্তর করা যায় এবং origin server-এ এর জন্য অর্থ প্রদান বন্ধ করা যায়।

curl -sL https://owncast.online/install.sh -o install-owncast.sh
less install-owncast.sh
bash install-owncast.sh

প্রকল্পটির documentation-এ root হিসেবে এটি চালাতে নিষেধ করা হয়েছে। কোনো remote script চালানোর আগে সেটি পরীক্ষা করতেও বলা হয়েছে। এই কারণে download ধাপটি উপরে আলাদা রাখা হয়েছে। আপনার কাছে আগে থেকেই না থাকলে installer বর্তমান release এবং একটি ffmpeg binary download করে। Install directory থেকে ./owncast চালান। এরপর port 8080-এ /admin খুলে admin panel-এ প্রবেশ করুন। Default login user হলো admin, আর default stream key abc123 হলো password। Server-এর দিকে domain নির্দেশ করার আগে এটি পরিবর্তন করুন।

HLS design থেকে দুটি ফলাফল আসে। Viewers live stream থেকে কয়েক সেকেন্ড বা কয়েক মিনিট পিছিয়ে থাকবেন, কারণ HLS সম্পূর্ণ segment সরবরাহ করে। তাই সরাসরি দ্বিমুখী কথোপকথন সম্ভব নয়। এই path-এ কোথাও UDP বা TURN নেই। ফলে যেসব network-এ WebRTC call একেবারেই connect করতে পারে না, সেখানেও এটি পৌঁছাতে পারে।

এখানে Owncast-ই একমাত্র tool, যা ইচ্ছাকৃতভাবে transcode করে। আপনি যে প্রতিটি output quality চালু করবেন, incoming stream-এর জন্য আরেকটি ffmpeg encode শুরু হবে এবং broadcast চলার পুরো সময় তা চলবে। ছোট VPS-এ এক বা দুটি quality দিন। পাঁচটি quality চালু করলে network idle থাকা অবস্থায় CPU সম্পূর্ণ ব্যবহৃত হবে।

একটি ইতিমধ্যে চালু Matrix server-এ Element Call

আপনি যদি ইতিমধ্যে Matrix চালান, তাহলে video পরিচালনার জন্য দ্বিতীয় কোনো product চালানোর বদলে এটি একটি অতিরিক্ত সুবিধা হিসেবে যোগ হয়। তবে এটি একটির বেশি package নিয়ে গঠিত। Element Call-এর জন্য আপনার homeserver-এর পেছনে দুটি উপাদান দরকার। প্রথমটি হলো একটি LiveKit SFU, যা media forwarding করে। দ্বিতীয়টি হলো MatrixRTC authorisation service, element-hq/lk-jwt-service, যা client-কে সংযোগের জন্য LiveKit WebSocket URL এবং একটি signed JWT (JSON web token) দেয়। এই service Matrix federation API ব্যবহার করে। তাই এর সামনে একটি TLS reverse proxy এবং federation থেকে পৌঁছানো যায় এমন একটি name দরকার।

LiveKit-এর নথিভুক্ত port:

  • TCP 7880 API এবং client WebSocket-এর জন্য, এমন একটি proxy-এর পেছনে যা TLS termination করে
  • TCP 7881 ICE over TCP-এর জন্য, যখন কোনো client UDP-এর মাধ্যমে বাইরে সংযোগ করতে পারে না
  • UDP 50000 থেকে 60000 media-এর জন্য, যেখানে একটি room-এর প্রতিটি participant দুটি port ব্যবহার করে
  • embedded TURN server চালু করলে UDP 3478 এবং TCP 5349; load balancer সামনে না থাকলে 5349-কে 443-এ সরাতে হবে

প্রতিটি participant-এর জন্য দুটি port শুনতে উদ্বেগজনক লাগতে পারে, কিন্তু তা নয়। 10,000 port-এর range-এ হাজার হাজার participant রাখা যায়, এবং range শেষ হওয়ার অনেক আগেই আপনার uplink-এর capacity শেষ হয়ে যাবে। তবুও সম্পূর্ণ range খুলুন। আংশিক range খোলা থাকলে কিছু মানুষের ক্ষেত্রে সংযোগ ব্যর্থ হয় এবং অন্যদের ক্ষেত্রে কাজ করে। এ ধরনের fault debug করা সবচেয়ে কঠিন। এর homeserver অংশটি আলাদা কাজ। এটি VPS-এ Synapse homeserver চালানো অংশে ব্যাখ্যা করা হয়েছে।

কেন একজন ব্যক্তি কখনও সংযোগ করতে পারেন না? TURN এবং UDP ব্লক করা নেটওয়ার্ক

প্রথমে কিছু পরিভাষা জেনে নিন। প্রতিটি এখানে একবার ব্যবহার করা হয়েছে। ICE (interactive connectivity establishment) হলো সেই প্রক্রিয়া, যার মাধ্যমে দুটি WebRTC endpoint তাদের মধ্যে কার্যকর একটি পথ খুঁজে নেয়। STUN (session traversal utilities for NAT) হলো একটি ছোট service, যা client-কে জানায় বাইরের দিক থেকে তার নিজের public address কেমন দেখা যায়। TURN (traversal using relays around NAT) হলো একটি relay: সরাসরি পথ না থাকলে উভয় দিক তাদের media TURN server-এ পাঠায়, এবং server তা forward করে।

যেসব participant-এর network আপনি দেখতে পান না, তাদের জন্য TURN প্রয়োজন। তাদের একজন এমন corporate বা campus network-এ থাকতে পারেন, যেখানে outbound UDP সম্পূর্ণভাবে blocked। আরেকজন এমন carrier-grade NAT-এর পেছনে থাকতে পারেন, যা প্রতিটি destination-এর জন্য আলাদা source port দেয়। এটিকে symmetric NAT বলা হয়, এবং এর ফলে STUN যে address জানায়, তা আর কার্যকর থাকে না।

সমস্যাটির লক্ষণ নির্দিষ্ট। অধিকাংশ ব্যক্তি join করেন এবং সবকিছু কাজ করে। কিন্তু একজন participant list দেখতে পান, chat দেখতে পান, এবং একটি কালো tile ও spinner পান। তার browser candidates সংগ্রহ করেছে, কিন্তু কোনো pair কাজ করেনি এবং ICE failed state-এ শেষ হয়েছে। Chrome-এ, চেষ্টা চলাকালে chrome://webrtc-internals খুললে candidate pairs এবং সেই failure দেখা যায়। ওই ব্যক্তিকে mobile data ব্যবহার করে phone থেকে আবার চেষ্টা করতে বলুন। সেখানে কাজ করলে বোঝা যাবে, তার network-ই কারণ এবং TURN-ই সমাধান।

443 বা 5349 port-এ TCP-এর মাধ্যমে TURN প্রায় সর্বত্র কাজ করা fallback, কারণ 443 port-এ TLS block করা network web-ও block করেছে। Jitsi-এর package আপনার জন্য coturn install ও configure করে। এই কারণেই তার documented firewall rules-এ UDP 3478 এবং TCP 5349 অন্তর্ভুক্ত থাকে। Galène-এর মধ্যে 1194 port-এ TURN built in আছে। LiveKit-এর embedded TURN server রয়েছে, যা config-এ চালু করতে হয়। আপনি নিজে coturn চালালে:

sudo apt install -y coturn
sudo systemctl enable --now coturn
listening-port=3478
tls-listening-port=5349
fingerprint
use-auth-secret
static-auth-secret=REPLACE_WITH_A_LONG_RANDOM_STRING
realm=turn.example.com
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
min-port=49152
max-port=65535
no-multicast-peers

Debian এবং Ubuntu-তে /etc/default/coturn-এ TURNSERVER_ENABLED=1 সেট না করা পর্যন্ত packaged service start হবে না। coturn install করা থাকলেও enable না করলে বাইরে থেকে সেটি সম্পূর্ণভাবে TURN না থাকার মতোই দেখায়। এ কারণেই এই একটি line মানুষের পুরো সন্ধ্যা নষ্ট করে।

এবার সেই খরচের কথা, যা কেউ হিসাবের মধ্যে লেখে না। একটি relay প্রতিটি relayed participant-এর সম্পূর্ণ media উভয় দিকে বহন করে। coturn যদি SFU-এর সঙ্গে একই box-এ থাকে, সেই traffic-এর বেশিরভাগ loopback-এর মধ্য দিয়ে যায় এবং uplink-এর বদলে CPU খরচ করে। উপরন্তু TLS listener media ইতিমধ্যে যে DTLS ব্যবহার করছে, তার ওপর প্রতিটি packet দ্বিতীয়বার encrypt করে। TURN আলাদা machine-এ সরালে সেই machine-এর জন্য SFU-এর মতো একই পদ্ধতিতে নির্ধারিত bandwidth plan প্রয়োজন। আর TCP-এর মাধ্যমে TURN real-time media-কে একটি reliable stream-এ পরিণত করে। ফলে হারানো packet বাদ না পড়ে retransmit হয়, এবং lossy link-এ থাকা relayed participant-এর ক্ষেত্রে সাময়িক glitch-এর বদলে delay জমতে থাকে। Relay হলো এমন একটি fallback, যা connection স্থাপন করে, কিন্তু direct path যে quality দিতে পারত, তা সাধারণত দিতে পারে না।

SFU কখন transcode করে, এবং এর খরচ কী?

SFU packet forward করে এবং কখনও video decode করে না। এই কারণেই কাগজে অসম্ভব মনে হওয়া একটি room চারটি core দিয়েও চালানো যায়। দুটি feature এই বৈশিষ্ট্য নষ্ট করে। Checkbox থেকে এগুলো চালু করা ব্যবহারকারীদের অনেকেই বিষয়টি আগে বুঝতে পারেন না।

প্রথমটি হলো recording। Jitsi, Jibri ব্যবহার করে recording করে। Jibri-এর নিজস্ব documentation-এ কাজটি স্পষ্টভাবে বলা আছে: এটি virtual framebuffer-এ render করা একটি Chrome instance চালু করে এবং ffmpeg দিয়ে সেই output capture ও encode করে। অর্থাৎ পুরো meeting ক্রমাগত render করার জন্য একটি পূর্ণ browser এবং একটি video encoder call চলাকালীন পুরো সময় চালু থাকে। একই documentation-এ বলা আছে, একটি Jibri-তে একসঙ্গে মাত্র একটি recording সমর্থিত। আরও বলা আছে, Jibri আলাদা machine বা virtual machine-এ চালানোর জন্য তৈরি, যেখানে অন্য কোনো application display বা audio device ব্যবহার করবে না। Recording কোনো checkbox নয়; এর জন্য দ্বিতীয় server লাগে।

দ্বিতীয়টি হলো telephone dial-in। একটি phone line-কে conference-এ যুক্ত করতে হলে Opus-এর 48 kHz audio-কে telephone network যে format গ্রহণ করে, সাধারণত 8 kHz-এর G.711, তাতে উভয় দিকে এবং পুরো call জুড়ে ক্রমাগত রূপান্তর করতে হয়। Audio transcoding, video transcoding-এর তুলনায় অনেক কম ব্যয়বহুল। তবে এটি প্রতিটি call leg-এর জন্য চলে এবং কখনও বিরত হয় না। তাই caller-এর সংখ্যা বাড়লে খরচও বাড়ে। Dial-in number চাইলে একটি self-hosted VoIP server এই কাজটি করে। Jibri-এর মতো একই কারণে এটিও আলাদা box-এ রাখা উচিত।

আপনার আসলে কত বড় সার্ভার দরকার?

দুজনের জন্য প্রায় কিছুই দরকার হয় না। অংশগ্রহণকারী ঠিক 2 জন হলে Jitsi ডিফল্টভাবে peer-to-peer mode চালু করে। এই mode-এ conference videobridge-এর মাধ্যমে data পাঠানো বন্ধ করে এবং সরাসরি connection ব্যবহার করে। তৃতীয় ব্যক্তি যোগ দিলে এটি আবার bridge-এ ফিরে যায়। তাই Jitsi চালানো 1 GB VPS এক-একজনের call server হিসেবে ভালো, কিন্তু 4 জনের call-এর জন্য দুর্বল। এ কারণেই “পরীক্ষা করার সময় কাজ করেছিল” এমন প্রতিবেদন এত সাধারণ।

ক্যামেরা চালু রেখে প্রায় 10 জন পর্যন্ত অংশগ্রহণকারীর ক্ষেত্রে, 8 জন অংশগ্রহণকারী থাকলে 67.2 Mbps একটি সাধারণ VPS-এর uplink যে পরিমাণ network traffic চালাতে পারে, তার মধ্যেই থাকে। recording না করলে 2টি virtual CPU এবং 4 GB RAM এই আকারের Jitsi বা Galène চালাতে পারবে। CPU graph-এর বদলে transfer counter পর্যবেক্ষণ করুন।

30 জনের ক্ষেত্রে worst case-এ sustained traffic হবে 1,044 Mbps, এবং 20 ঘণ্টায় এর পরিমাণ হবে 9.4 TB। এই আকারে server-এর দাম হিসাব করার আগে bandwidth-এর দাম হিসাব করুন। last-N চালু করুন, যাতে bridge শুধু সাম্প্রতিক speakers-দের forward করে। attendees-দের জন্য camera-off default করুন। SFU এমন জায়গায় রাখুন, যেখানে transfer allowance এই হিসাব সামলাতে পারে।

এর বেশি হলে একটি VPS উপযুক্ত কাঠামো নয়। হয় event-টি আসলে broadcast, সে ক্ষেত্রে Owncast এবং CDN-এর খরচ এর একটি অংশমাত্র; অথবা single signalling layer-এর পেছনে একাধিক videobridge দরকার হবে। সেটি আপনার শুরু করা project থেকে আলাদা।

Routing-এর আরেকটি বিষয় আছে। বেশিরভাগ team-এর দিনে video-এর চেয়ে অনেক বেশি সময় chat দরকার হয়। chat host করা সস্তা এবং চালু রাখা সহজ। দৈনন্দিন traffic-এর জন্য একটি self-hosted Slack বিকল্প চালু করে, শুধু নির্ধারিত call-এর জন্য conferencing server রাখা—ছোট VPS budget-এর সঙ্গে বাস্তবে টেকসই arrangement এটি।

FAQ

কেন মানুষ আমার Jitsi meeting-এ যোগ দিতে পারে, কিন্তু একে অপরকে দেখতে বা শুনতে পারে না?

Chat এবং participant list signalling channel-এর মাধ্যমে যায়, যা 443 port-এ TCP ব্যবহার করে। Audio এবং video videobridge-এ UDP 10000 ব্যবহার করে। Participant list পূর্ণ হলেও যদি প্রতিটি tile কালো থাকে, তাহলে signalling path ঠিক আছে, কিন্তু media path কাজ করছে না। উভয় firewall-এ UDP 10000 পরীক্ষা করুন: সার্ভারের firewall এবং provider-এর control panel-এ থাকা আলাদা network firewall। এরপর bridge তার public address জানে কি না পরীক্ষা করুন। Private address এবং mapped public address থাকা virtual machine-এ /etc/jitsi/videobridge/jvb.conf-এর মধ্যে ice4j.harvest.mapping-এর অধীনে static mapping যোগ করে jitsi-videobridge2 restart করুন। কেউ join করার সময় sudo tcpdump -ni any udp port 10000 চালালে কোন সমস্যা হচ্ছে তা বোঝা যায়। একেবারেই কোনো packet না এলে block-টি operating system-এর আগের কোনো স্তরে আছে।

30 জনের video call-এ কত bandwidth লাগে?

সবচেয়ে খারাপ পরিস্থিতিতে, যখন সবার camera চালু থাকে এবং SFU প্রত্যেকের কাছে পূর্ণ quality layer পাঠায়, তখন server থেকে আনুমানিক 1,044 Mbps বের হয়। এটি প্রতি ঘণ্টায় 469.8 GB। এই হিসাবটি প্রত্যেক stream-এর জন্য 1.2 Mbps ধরে N গুণ (N minus 1) stream-এর গাণিতিক হিসাব। এটি আপনার setup-এর পরিমাপ নয়। স্বাভাবিক ব্যবহারে simulcast এবং last-N setting এই পরিমাণ অনেক কমায়, কারণ যেকোনো সময়ে অধিকাংশ participant screen-এ থাকে না। তবু worst case-এর কাছাকাছি capacity ধরে পরিকল্পনা করুন। কারণ all-hands call-এ সবাই একই সময়ে camera চালু করতে পারে।

আমি কি 1 GB VPS-এ Jitsi Meet চালাতে পারি?

এটি install হবে, এবং 2 জনের call কাজ করবে। এর একটি কারণ হলো, ঠিক 2 জন participant থাকলে Jitsi peer to peer mode ব্যবহার করে এবং videobridge পুরোপুরি এড়িয়ে যায়। তবে এটি group call server হিসেবে ব্যবহারযোগ্য নয়। Prosody, videobridge এবং Java runtime—সবগুলোর memory দরকার। Serious deployment-এর জন্য handbook-এ 8 GB RAM ব্যবহারের পরামর্শ দেওয়া হয়েছে। Memory শেষ হওয়ার আগেই bandwidth-এর হিসাব সমস্যা তৈরি করবে। আপনার কাছে যদি 1 GB box-ই থাকে, তাহলে ওই আকারের server-এ Jitsi-এর চেয়ে Galène বেশি উপযোগী।

আমার VPS-এ public IP address থাকলেও কি TURN server দরকার?

হ্যাঁ। TURN যে সমস্যার সমাধান করে, সেটি call-এর অপর প্রান্তে থাকে। Corporate network থেকে outbound UDP block করা কোনো participant, অথবা এমন carrier-grade NAT-এর পেছনে থাকা participant যা প্রতিটি destination-এর জন্য আলাদা source port দেয়, আপনার server-এর address যতই public হোক না কেন, সরাসরি media path তৈরি করতে পারে না। 443 বা 5349 port-এ TCP-এর মাধ্যমে TURN তাদের এমন একটি relay দেয়, যা firewall-এর কাছে সাধারণ web traffic-এর মতো দেখায়। Jitsi-এর package install এ জন্য defaultভাবে coturn setup করে। তাই এর documented firewall rules-এ UDP 3478 এবং TCP 5349 খোলা থাকে।

Jitsi Meet-এর তুলনায় BigBlueButton-এর এত বেশি hardware কেন দরকার?

কারণ এটি শুধু video forward করে না। BigBlueButton-এর প্রকাশিত production requirement হলো 16 GB RAM এবং 8 core। Jitsi-এর handbook-এ requirement হলো 8 GB RAM এবং 4 core। BigBlueButton একই machine-এ পূর্ণ audio conferencing stack, shared whiteboard ও presentation layer, recording ও post-processing pipeline এবং user account-সহ web front end চালায়। এটি platform সম্পর্কেও নির্দিষ্ট: August 2026 অনুযায়ী supported install হলো Ubuntu 22.04-এ version 3.0। উভয় project-এর নিজস্ব documentation থেকে এই figures নেওয়া হয়েছে। এগুলো আপনার workload-এর পরিমাপ নয়, বরং প্রাথমিক planning-এর ভিত্তি।

#jitsi#webrtc#video-conferencing#self-hosting#bandwidth