SSD Nodes Learn 🎉 VPS od $5.50/mies.
Przewodniki Matt ConnorAutor: Matt Connor

Własny serwer wideokonferencji na VPS - jak wybrać?

Oblicz wymagane pasmo dla Jitsi, BigBlueButton i Galene. Dowiedz się, dlaczego ruch rośnie kwadratowo, które porty UDP otworzyć i jak uniknąć problemów z NAT na serwerze.

Samodzielnie hostowane wideokonferencje na VPS a problem przepustowości

Samodzielnie hostowane wideokonferencje na małych serwerach zawodzą z jednego powodu i prawie nigdy nie jest to proces instalacji. Elementem serwerowym, którego używa każde nowoczesne narzędzie, jest SFU (Selective Forwarding Unit). Pobiera on jeden strumień wideo od każdego uczestnika i przesyła jego kopię do wszystkich pozostałych, więc ruch wychodzący z serwera rośnie proporcjonalnie do kwadratu liczby osób. Serwer VPS o pamięci 1 GB lub 2 GB z współdzielonym łączem obsłuży oprogramowanie bez problemów. Nie udźwignie jednak spotkania dla całego zespołu, które masz na myśli.

Dlatego wykonaj pracę w tej kolejności. Policz uczestników, oblicz wymagane megabity, a następnie wybierz serwer. Instalacja to dwadzieścia minut kopiowania i wklejania poleceń. To przepustowość łącza decyduje o tym, czy ktokolwiek będzie w stanie Cię usłyszeć.

Dlaczego zapotrzebowanie na pasmo rośnie wraz z kwadratem liczby uczestników?

Zacznijmy od topologii mesh. Każda przeglądarka koduje obraz z kamery i wysyła kopię bezpośrednio do każdej innej przeglądarki; żaden serwer mediów nie przetwarza wideo. Połączenie mesh dla dwóch osób wymaga jedynie serwera sygnalizacyjnego, dlatego rozmowy jeden na jeden są niemal darmowe w utrzymaniu. Topologia mesh przestaje działać przy czterech lub pięciu osobach, ponieważ laptop w domowej sieci musi jednocześnie wysyłać cztery lub pięć oddzielnych kopii własnego obrazu.

SFU działa inaczej. Każda przeglądarka wysyła jedną kopię do serwera. Serwer odczytuje nagłówki RTP (real-time transport protocol) i przekazuje pakiety do pozostałych uczestników bez dekodowania wideo. Na tym polega cały mechanizm; dlatego SFU ma niskie wymagania co do CPU, ale wysokie co do sieci.

Starszym rozwiązaniem jest MCU (multipoint control unit). Dekoduje on każdy przychodzący strumień, łączy je w jeden obraz i ponownie go koduje. Pasmo wyjściowe jest minimalne, ale obciążenie CPU ogromne. Obecnie niemal nic nie używa MCU do wideo i żaden element tego przewodnika go nie wykorzystuje.

Oto obliczenia dla SFU. Załóżmy, że każda osoba wysyła wideo z prędkością 1.2 Mbps i nikt nie wyłącza kamery. Serwer odbiera N razy 1.2 Mbps, co jest wartością liniową i bezpieczną. Serwer wysyła N razy (N minus 1) razy 1.2 Mbps, ponieważ każda z N osób musi otrzymać pozostałe N minus 1 strumieni. Ta druga wartość jest tą, która kończy projekty.

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
  }
]

Te wiersze to obliczenia matematyczne, a nie pomiary konkretnego serwera. Kolumna miesięczna zakłada dwadzieścia godzin rozmów w miesiącu. Przeczytaj najpierw ostatni wiersz. Pięćdziesiąt osób z włączonymi kamerami wymaga 2,940 Mbps stałego ruchu wychodzącego z jednej maszyny. Trzydzieści osób wymaga 1,044 Mbps. Cztery osoby wymagają 14.4 Mbps, co obsłuży każdy VPS bez zauważalnego obciążenia. Pomiędzy wierszem dla czterech osób a wierszem dla trzydziestu osób liczba uczestników rośnie siedmioipółkrotnie, podczas gdy ruch wychodzący rośnie ponad siedemdziesięciokrotnie.

Rzeczywiste wdrożenia mieszczą się w tych liczbach i warto wiedzieć dokładnie dlaczego. Zarówno Jitsi, jak i LiveKit używają simulcast: nadawca publikuje jednocześnie kilka warstw jakości, a SFU przekazuje niską warstwę każdemu, kto nie jest aktualnie wyświetlany. Jitsi posiada również ustawienie last-N, które przekazuje wideo tylko dla osób najaktywniej mówiących. Oba rozwiązania znacznie oszczędzają ruch. Żadne z nich nie zmienia kształtu krzywej i oba przestają pomagać w momencie, gdy wszyscy włączą kamery i przypną swoje okna.

Co w rzeczywistości zapewnia łącze VPS?

Strona z ofertą planu podaje "port 1 Gbps". Jest to prędkość wirtualnej karty sieciowej, a nie gwarancja przepustowości kolejnego przeskoku. Łącze jest współdzielone z innymi użytkownikami na tym samym hoście fizycznym, więc stała przepustowość w godzinach szczytu jest niższa niż prędkość portu, a połączenie konferencyjne stanowi właśnie stałe obciążenie. Większość planów posiada również miesięczny limit transferu, po przekroczeniu którego prędkość jest ograniczana lub naliczane są dodatkowe opłaty.

Ten limit jest miejscem, w którym pojawiają się koszty na fakturze. Dwadzieścia godzin połączenia dla trzydziestu osób w ciągu miesiąca generuje ruch wychodzący z serwera rzędu 9.4 TB, przy 469.8 GB na godzinę. Dwadzieścia godzin połączenia dla pięćdziesięciu osób generuje 26.5 TB. Należy sprawdzić limit transferu przed sprawdzeniem ilości pamięci RAM, a jeśli strona z ofertą jest w tej kwestii niejasna, ta niejasność stanowi odpowiedź. Właściwa interpretacja taniej oferty VPS ma w przypadku tego obciążenia większe znaczenie niż w niemal każdym innym.

Jitsi Meet: domyślny wybór i wymagania

Jitsi Meet to rozwiązanie, od którego większość użytkowników powinna rozpocząć pracę. Instalacja odbywa się z oficjalnego repozytorium Debian projektu, konfiguracja nginx oraz certyfikatu przebiega automatycznie podczas instalacji, a videobridge (JVB) korzysta z pojedynczego portu UDP, co ogranicza liczbę reguł firewalla. Wymagany jest system Debian 11 lub nowszy, bądź Ubuntu 22.04 lub nowszy.

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

Instalator prosi o podanie nazwy hosta, a następnie oferuje wybór certyfikatu. Należy wybrać opcję Let's Encrypt i podać nazwę domeny, która wskazuje na publiczny adres IP serwera. Certyfikat jest wydawany w oparciu o wyzwanie HTTP, więc nazwa wskazująca na inny adres spowoduje błąd na tym etapie.

Następnie należy otworzyć porty. Poniżej znajdują się porty udokumentowane w podręczniku, z SSH na pierwszym miejscu, aby ufw enable nie spowodowało utraty dostępu:

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

Porty TCP 80 i 443 obsługują aplikację webową oraz umożliwiają odnawianie certyfikatu. Port UDP 10000 przesyła cały ruch audio i wideo; jest to port najczęściej pomijany. Porty UDP 3478 oraz TCP 5349 należą do serwera coturn, który pakiet Jitsi instaluje wraz z bridge'em; stanowią one ścieżkę zapasową dla użytkowników, których sieć blokuje ruch UDP.

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

Pierwsze polecenie powinno wskazać, że usługa jest aktywna. Drugie powinno wykazać, że bridge nasłuchuje na porcie UDP 10000. Jeśli wynik jest pusty, oznacza to, że bridge nie uruchomił się, a /var/log/jitsi/jvb.log wskaże przyczynę.

W kwestii doboru zasobów, podręcznik Jitsi publikuje własne wytyczne, a BigBlueButton znacznie wyższe:

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
  }
]

Podręcznik Jitsi sugeruje 8 GB pamięci RAM oraz 4 dedykowane rdzenie dla wydajnego serwera, przy czym przepustowość sieci 1,000 Mbps jest zazwyczaj wystarczająca. Zauważono również, że mniejsze instalacje działają na 4 GB lub 2 GB RAM. Jeden szczegół z tej strony jest istotny: Prosody, serwer XMPP obsługujący sygnalizację, może korzystać tylko z jednego rdzenia. Dodatkowe rdzenie wspomagają bridge, ale nie wpływają na wydajność sygnalizacji.

Dlaczego wszyscy dołączają do rozmowy, ale nikt nie widzi obrazu?

Jest to typowy błąd Jitsi na serwerze VPS. Lista uczestników zapełnia się, czat działa, a wszystkie okna wideo pozostają czarne. Videobridge ogłasza adresy, które znajduje na własnych interfejsach. U dostawcy, który przydziela maszynie wirtualnej adres prywatny i mapuje na niego adres publiczny, JVB znajduje tylko adres prywatny. W rezultacie każdy klient próbuje wysłać media na adres typu 10.0.0.5, a pakiety nie docierają do celu.

Należy poinformować bridge o obu adresach. Dodaj statyczne mapowanie w /etc/jitsi/videobridge/jvb.conf:

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

Zrestartuj usługę za pomocą sudo systemctl restart jitsi-videobridge2. Pobierz adres lokalny z ip -4 addr show, a adres publiczny z panelu sterowania dostawcy. Starsze poradniki zalecają ustawienie tego samego w /etc/jitsi/videobridge/sip-communicator.properties za pomocą kluczy org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS oraz org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS. Te metody nadal działają, jednak w nowych instalacjach należy użyć powyższego bloku mapowania.

Drugą przyczyną jest nieskonfigurowana zapora sieciowa. Większość dostawców stosuje w panelu sterowania firewall sieciowy, który jest niezależny od ufw na serwerze; port UDP 10000 musi być otwarty w obu miejscach. Aby sprawdzić, która warstwa odrzuca pakiety, uruchom sudo tcpdump -ni any udp port 10000 na serwerze w momencie, gdy ktoś dołącza z zewnątrz. Brak jakichkolwiek pakietów oznacza, że nic nie dociera do maszyny, więc blokada znajduje się przed systemem operacyjnym. Jeśli pakiety docierają, a okna wideo pozostają czarne, oznacza to, że bridge odpowiada adresem, do którego klient nie ma dostępu, czyli problem leży w mapowaniu. Jeśli nie masz pewności co do konfiguracji samego ufw, reguły ufw niezbędne na serwerze VPS opisują kolejność reguł, która często sprawia użytkownikom trudności.

BigBlueButton: ciężki, autorski i wymagający całego serwera

BigBlueButton jest zaprojektowany z myślą o nauczaniu. Posiada tablicę, pokoje podgrup, ankiety oraz obszar prezentacji, a mechanizm nagrywania jest kluczową funkcją, a nie dodatkiem. Jest to również zdecydowanie najcięższa opcja w zestawieniu i nie jest to pakiet, który można dodać do istniejącego serwera.

Według stanu na sierpień 2026 wspieraną ścieżką jest BigBlueButton 3.0 na systemie Ubuntu 22.04, wybieranym za pomocą flagi jammy-300. Deklarowane przez projekt wymagania produkcyjne to 16 GB pamięci RAM z włączonym swapem, 8 rdzeni CPU o wysokiej wydajności jednowątkowej, 250 Mb/s symetrycznego łącza oraz 500 GB miejsca na dysku w przypadku przechowywania nagrań (50 GB, jeśli zostaną wyłączone). Wymagane porty to TCP 80 i 443 oraz zakres UDP od 16384 do 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

Oficjalne przykłady projektu przesyłają ten skrypt bezpośrednio do bash. Należy go najpierw pobrać i przeczytać, ponieważ nadpisuje on konfigurację nginx, instaluje własny stos multimediów i audio, przypina wersje pakietów oraz przejmuje nazwę hosta. Jest to założenie projektowe, a nie wada: BigBlueButton wymaga pełnej kontroli nad maszyną. Flaga -w konfiguruje zaporę sieciową, -s określa nazwę hosta, -e to adres rejestrowany w Let's Encrypt, a -g dodaje interfejs Greenlight. Jeśli na tej samej maszynie działa również terminacja TLS dla innych usług, należy przenieść BigBlueButton w inne miejsce lub upewnić się, że rozumiesz działanie konfiguracji reverse proxy nginx przed uruchomieniem skryptu.

Należy uważnie porównać dwa wiersze w tej tabeli. BigBlueButton wymaga dwukrotnie więcej pamięci i rdzeni niż sugeruje Jitsi, przy zapotrzebowaniu na jedną czwartą przepustowości. Obie wartości nie są mierzone w ten sam sposób i zakładają różne rozmiary pokoi, dlatego należy traktować je jako punkt wyjścia dla każdego projektu, a nie jako bezpośrednie porównanie. Różnica w zapotrzebowaniu na CPU jest rzeczywista i wynika ze wszystkich zadań, które wykonuje BigBlueButton poza samym przesyłaniem wideo.

Galène: lekka alternatywa

Galène to kompaktowy serwer SFU napisany w języku Go. Kompiluje się do pojedynczego statycznego pliku binarnego, zawiera własnego klienta webowego oraz wbudowany serwer TURN. Dzięki temu nie wymaga serwera XMPP, środowiska uruchomieniowego Java ani aplikacji Rails, które trzeba utrzymywać w działaniu. Jeśli celem jest niezawodna rozmowa dla dziesięciu osób na skromnym serwerze, warto wypróbować to rozwiązanie przed podjęciem decyzji o zwiększeniu zasobów sprzętowych.

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

Pakiet golang-go w systemie Ubuntu 24.04 zawiera Go 1.22. Jeśli go build zgłasza błąd, że moduł wymaga nowszej wersji Go, należy zainstalować aktualny łańcuch narzędzi z witryny go.dev, zamiast polegać na wersji z repozytorium dystrybucji.

Grupa w terminologii Galène oznacza pokój, a jej definicja znajduje się w pliku JSON:

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

Otwórz https://your.server:8443/group/night-watch/ i zaloguj się jako vimes. Te dane uwierzytelniające pochodzą bezpośrednio z pliku README projektu, dlatego należy je zmienić, zanim port stanie się dostępny z zewnątrz. W przypadku wdrożenia produkcyjnego projekt udostępnia jednostkę systemd:

[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

Wykorzystywane porty to TCP 8443 dla interfejsu webowego, TCP i UDP 1194 dla wbudowanego serwera TURN oraz zakres wysokich portów UDP dla mediów. Warto ograniczyć ten zakres, aby móc utworzyć jedną regułę firewalla:

./galene -udp-range 40000-40100

Opcja -turn jest kluczowa w przypadku serwera VPS. -turn ':1194' nasłuchuje na wszystkich publicznych adresach IPv4. -turn '203.0.113.1:1194' informuje Galène o adresie, który faktycznie zobaczą klienci, co jest niezbędne, gdy adres własny maszyny jest prywatny. -turn '' wyłącza wbudowany serwer, co pozwala wskazać zewnętrzny serwer za pomocą data/ice-servers.json. Wartością domyślną jest auto, która zachowuje się jak :1194, jeśli nie istnieje ice-servers.json.

Można umieścić nginx przed interfejsem webowym, ustawiając proxyURL w data/config.json i przekierowując lokalizację /ws wraz z nagłówkami aktualizacji WebSocket. Należy pamiętać o zakresie działania: klienci nadal otwierają bezpośrednie strumienie UDP i połączenia TCP do portu TURN, więc reverse proxy obsługuje jedynie stronę i sygnalizację. Dane multimedialne nigdy nie przechodzą przez proxy.

Dokumentacja Galène wskazuje na bardzo niskie zapotrzebowanie na zasoby serwera i nie podaje konkretnych wartości, więc nie należy oczekiwać sztywnych wytycznych. Obliczenia dotyczące przepustowości pozostają w pełni aktualne. Oszczędność polega na mniejszym zużyciu pamięci oraz braku konieczności utrzymywania komponentów, które nie są częścią SFU.

Owncast: model jeden do wielu, gdzie zużycie pasma rośnie liniowo

Wiele wymagań dotyczących „wideokonferencji” w rzeczywistości sprowadza się do prezentacji jednej osoby dla publiczności, która komunikuje się poprzez czat. Jeśli tak jest w Twoim przypadku, SFU jest niewłaściwym narzędziem, a rachunek ekonomiczny zmienia się całkowicie. Owncast przyjmuje strumień RTMP z OBS lub podobnego enkodera i udostępnia go przez HLS za pośrednictwem standardowego HTTPS. Zużycie pasma na widza rośnie liniowo, a nie kwadratowo. Ponieważ wyjście składa się ze zwykłych segmentów HTTP, można je przenieść za pamięć obiektową lub CDN, co eliminuje koszty transmisji po stronie serwera źródłowego.

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

Dokumentacja projektu zaleca, aby nie uruchamiać go z uprawnieniami root oraz sprawdzać każdy zdalny skrypt przed jego wykonaniem, dlatego pobieranie jest oddzielnym krokiem opisanym powyżej. Instalator pobiera aktualne wydanie oraz binaria ffmpeg, jeśli nie są one jeszcze zainstalowane. Uruchom ./owncast z katalogu instalacyjnego i otwórz panel administracyjny pod adresem /admin na porcie 8080. Domyślny login to użytkownik admin, a domyślny klucz strumienia abc123 służy jako hasło. Zmień je przed skierowaniem domeny na serwer.

Z architektury HLS wynikają dwie konsekwencje. Widzowie mają opóźnienie wynoszące od kilku sekund do kilku minut względem transmisji na żywo, ponieważ HLS przesyła całe segmenty, co wyklucza konwersację w czasie rzeczywistym. W ścieżce przesyłu nie występuje UDP ani TURN, dzięki czemu usługa działa w sieciach, w których połączenie WebRTC w ogóle nie może zostać nawiązane.

Owncast jest również jedynym narzędziem w tym zestawieniu, które celowo dokonuje transkodowania. Każda włączona jakość wyjściowa to kolejne kodowanie strumienia wejściowego przez ffmpeg, działające przez cały czas trwania transmisji. Na małym VPS oferuj jedną lub dwie jakości. Pięć jakości spowoduje pełne obciążenie procesora, podczas gdy sieć pozostanie niewykorzystana.

Uruchomienie Element Call na własnym serwerze Matrix

Jeśli korzystasz już z serwera Matrix, obsługa wideo stanowi rozszerzenie, a nie odrębny produkt do utrzymania. Nadal jednak wymaga to więcej niż jednego pakietu. Element Call wymaga dwóch komponentów działających za serwerem domowym (homeserver). Pierwszym jest LiveKit SFU, który odpowiada za przekazywanie mediów. Drugim jest usługa autoryzacji MatrixRTC, element-hq/lk-jwt-service, która dostarcza klientowi adres URL WebSocket usługi LiveKit oraz podpisany token JWT (JSON web token) niezbędny do nawiązania połączenia. Usługa ta korzysta z API federacji Matrix, dlatego wymaga umieszczenia przed nią odwrotnego proxy (reverse proxy) z terminacją TLS oraz nazwy hosta dostępnej dla federacji.

Porty udokumentowane dla LiveKit:

  • TCP 7880 dla API oraz klienta WebSocket, za proxy z terminacją TLS
  • TCP 7881 dla ICE over TCP, używany, gdy klient nie może nawiązać połączenia przez UDP
  • UDP 50000 do 60000 dla mediów, gdzie każdy uczestnik rozmowy zajmuje dwa porty
  • UDP 3478 oraz TCP 5349 w przypadku włączenia wbudowanego serwera TURN; port 5349 musi zostać przeniesiony na 443, chyba że przed nim znajduje się load balancer

Dwa porty na uczestnika mogą wydawać się dużą liczbą, jednak w praktyce tak nie jest. Zakres 10000 portów wystarcza dla tysięcy uczestników, a przepustowość łącza wyczerpie się znacznie szybciej niż dostępna pula portów. Należy otworzyć cały zakres, ponieważ częściowe otwarcie portów powoduje, że połączenie działa u niektórych użytkowników, a u innych nie, co jest najtrudniejszym do zdiagnozowania typem awarii. Konfiguracja serwera domowego jest osobnym zagadnieniem, opisanym w uruchamianiu serwera domowego Synapse na VPS.

Dlaczego jedna osoba nigdy nie może się połączyć? TURN i sieci blokujące UDP

Najpierw kilka terminów. ICE (interactive connectivity establishment) to proces, w którym dwa punkty końcowe WebRTC ustalają działającą ścieżkę połączenia. STUN (session traversal utilities for NAT) to niewielka usługa informująca klienta, jaki jest jego publiczny adres IP widziany z zewnątrz. TURN (traversal using relays around NAT) to przekaźnik: gdy bezpośrednia ścieżka nie istnieje, obie strony wysyłają media do serwera TURN, który je przekazuje dalej.

TURN jest niezbędny dla uczestników, których sieci nie pozwalają na bezpośrednie połączenie. Jednym z przypadków jest sieć korporacyjna lub uczelniana, w której ruch wychodzący UDP jest całkowicie blokowany. Innym jest NAT klasy operatorskiej (Carrier-Grade NAT), który przydziela inny port źródłowy dla każdego miejsca docelowego (tzw. symetryczny NAT), co sprawia, że adres zgłoszony przez STUN staje się bezużyteczny.

Objawy są charakterystyczne. Większość osób łączy się bez problemów. Jedna osoba widzi listę uczestników i czat, ale zamiast obrazu widzi czarne pole i ikonę ładowania. Przeglądarka zebrała kandydatów, żadna z par nie zadziałała, a proces ICE zakończył się niepowodzeniem. W przeglądarce Chrome otwarcie chrome://webrtc-internals podczas próby połączenia pokaże pary kandydatów i błąd. Poproś tę osobę o próbę połączenia z telefonu korzystającego z danych komórkowych. Jeśli to zadziała, przyczyną jest sieć, a rozwiązaniem jest TURN.

TURN przez TCP na porcie 443 lub 5349 to mechanizm awaryjny działający niemal wszędzie, ponieważ sieć blokująca TLS na porcie 443 blokowałaby również dostęp do stron WWW. Pakiet Jitsi instaluje i konfiguruje coturn automatycznie, dlatego w dokumentacji reguł zapory sieciowej uwzględniono UDP 3478 oraz TCP 5349. Galène ma wbudowany TURN na porcie 1194. LiveKit posiada wbudowany serwer TURN, który aktywuje się w konfiguracji. Jeśli uruchamiasz coturn samodzielnie:

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

W systemach Debian i Ubuntu dostarczona usługa nie uruchomi się, dopóki nie ustawisz TURNSERVER_ENABLED=1 w pliku /etc/default/coturn. Zainstalowany, lecz niewłączony coturn wygląda z zewnątrz tak samo, jak całkowity brak serwera TURN, dlatego ta jedna linijka konfiguracji kosztuje wielu użytkowników całe wieczory pracy.

Teraz kwestia kosztów, o której rzadko się pisze. Przekaźnik przenosi pełny strumień mediów każdego przekazywanego uczestnika w obu kierunkach. Gdy coturn współdzieli maszynę z SFU, większość tego ruchu przechodzi przez interfejs loopback, obciążając procesor zamiast łącza zewnętrznego, a procesor TLS szyfruje każdy pakiet po raz drugi, dodatkowo do szyfrowania DTLS, które media już posiadają. Po przeniesieniu TURN na osobną maszynę, musi ona dysponować własnym planem przepustowości, zaplanowanym tak samo jak w przypadku SFU. Ponadto TURN przez TCP zamienia media czasu rzeczywistego w strumień niezawodny, więc utracony pakiet jest retransmitowany zamiast pomijany, a uczestnik korzystający z przekaźnika na łączu o słabej jakości odczuje opóźnienie zamiast krótkiego zakłócenia. Przekaźnik to rozwiązanie awaryjne, które zapewnia połączenie, ale o jakości niższej niż w przypadku bezpośredniej ścieżki.

Kiedy SFU wykonuje transkodowanie i jaki jest tego koszt?

SFU przesyła pakiety i nigdy nie dekoduje wideo, dlatego cztery rdzenie procesora mogą obsłużyć pokój, który teoretycznie wydaje się niemożliwy do obsłużenia. Dwie funkcje naruszają tę zasadę i obie zaskakują użytkowników, którzy włączyli je za pomocą pola wyboru.

Pierwszą z nich jest nagrywanie. Jitsi nagrywa za pomocą Jibri, a dokumentacja Jibri dokładnie opisuje, jak to działa: uruchamia instancję Chrome renderowaną w wirtualnym buforze ramki (framebuffer), a następnie przechwytuje i koduje wyjście za pomocą ffmpeg. Jest to pełna przeglądarka renderująca całe spotkanie oraz koder wideo, działające nieprzerwanie przez cały czas trwania połączenia. Ta sama dokumentacja stwierdza, że na pojedynczym Jibri obsługiwane jest tylko jedno nagrywanie jednocześnie i że Jibri powinno działać na oddzielnej maszynie lub maszynie wirtualnej, na której żadne inne aplikacje nie korzystają z urządzeń wyświetlających ani audio. Nagrywanie to drugi serwer, a nie tylko pole wyboru.

Drugą funkcją jest wybieranie numeru telefonicznego. Mostkowanie linii telefonicznej do konferencji oznacza konwersję dźwięku z formatu Opus 48 kHz na standard akceptowany przez sieć telefoniczną, zazwyczaj G.711 8 kHz, w obu kierunkach i w sposób ciągły przez całe połączenie. Transkodowanie audio jest znacznie tańsze niż transkodowanie wideo, ale odbywa się dla każdej odnogi połączenia i nigdy nie jest wstrzymywane, więc koszt rośnie wraz z liczbą dzwoniących. Jeśli potrzebny jest numer do wybierania, samodzielnie hostowany serwer VoIP jest komponentem, który wykonuje tę pracę i z tego samego powodu co Jibri, powinien znajdować się na własnej maszynie.

Jak duży serwer jest faktycznie potrzebny?

Dla dwóch osób wystarczy niemal dowolna maszyna. Jitsi domyślnie włącza tryb peer-to-peer, gdy w konferencji uczestniczą dokładnie dwie osoby. W tym trybie konferencja przestaje przesyłać dane przez videobridge i wykorzystuje bezpośrednie połączenie. Dołączenie trzeciej osoby powoduje powrót do korzystania z mostka. Dlatego VPS z 1 GB RAM jest odpowiedni do połączeń jeden na jeden, ale słabo radzi sobie z czterema osobami. To wyjaśnia, dlaczego tak często słyszy się opinię: „działało, gdy testowałem”.

Dla grupy do około dziesięciu osób z włączonymi kamerami, 67.2 Mbps przy ośmiu uczestnikach mieści się w przepustowości łącza typowego VPS-a. Dwa wirtualne procesory i 4 GB RAM wystarczą do uruchomienia Jitsi lub Galène przy tej skali, o ile nie prowadzisz nagrywania. Monitoruj licznik transferu, a nie wykres użycia procesora.

Dla trzydziestu osób najgorszy scenariusz to 1,044 Mbps stałego obciążenia, co przy dwudziestu godzinach pracy daje 9.4 TB. Przy tej skali najpierw należy wycenić koszt transferu, a dopiero potem koszt serwera. Włącz funkcję last-N, aby mostek przekazywał dane tylko od ostatnich mówców, ustaw domyślnie wyłączone kamery dla uczestników i umieść SFU w lokalizacji z limitem transferu, który wytrzyma takie obliczenia.

Powyżej tej liczby jeden VPS przestaje być odpowiednim rozwiązaniem. Jeśli wydarzenie ma charakter transmisji, lepiej użyć Owncast wraz z CDN, co kosztuje ułamek tej kwoty. W przeciwnym razie potrzebujesz więcej niż jednego videobridge'a za pojedynczą warstwą sygnalizacyjną, co stanowi projekt o znacznie większym stopniu złożoności.

Ostatnia uwaga dotycząca routingu. Większość zespołów potrzebuje czatu przez znacznie więcej godzin dziennie niż wideo, a czat jest tani w utrzymaniu i łatwy w obsłudze. Uruchomienie własnej alternatywy dla Slack do codziennej komunikacji i utrzymywanie serwera konferencyjnego wyłącznie do zaplanowanych rozmów to układ, który pozwala zmieścić się w budżecie małego VPS-a.

FAQ

Dlaczego uczestnicy mogą dołączyć do spotkania Jitsi, ale nie widzą ani nie słyszą się nawzajem?

Czat i lista uczestników przesyłane są kanałem sygnalizacyjnym, który wykorzystuje TCP na porcie 443, natomiast audio i wideo korzystają z UDP 10000 w kierunku videobridge. Jeśli lista uczestników się wypełnia, a okna wideo pozostają czarne, oznacza to, że ścieżka multimedialna jest przerwana, mimo poprawnego działania sygnalizacji. Sprawdź dostępność portu UDP 10000 w obu zaporach sieciowych: systemowej oraz zewnętrznej w panelu sterowania dostawcy usług. Następnie zweryfikuj, czy bridge poprawnie rozpoznaje swój publiczny adres IP: w przypadku maszyny wirtualnej z prywatnym adresem i przypisanym adresem publicznym, dodaj statyczne mapowanie w ice4j.harvest.mapping w pliku /etc/jitsi/videobridge/jvb.conf i zrestartuj jitsi-videobridge2. Uruchomienie sudo tcpdump -ni any udp port 10000 w momencie dołączania uczestnika pozwoli ustalić przyczynę problemu; brak jakichkolwiek pakietów oznacza, że blokada występuje przed systemem operacyjnym.

Jakie pasmo zużywa wideokonferencja dla 30 osób?

W najgorszym scenariuszu, gdy wszyscy mają włączone kamery, a SFU przesyła każdemu strumień o pełnej jakości, z serwera wychodzi około 1,044 Mbps, co przekłada się na 469.8 GB na godzinę. Jest to wynik obliczeń dla N razy (N minus 1) strumieni po 1.2 Mbps każdy, a nie pomiar rzeczywistego obciążenia. Mechanizmy simulcast oraz ustawienie last-N znacząco redukują to zużycie w typowych warunkach, ponieważ większość uczestników nie jest wyświetlana w danym momencie. Należy jednak planować zasoby pod kątem najgorszego scenariusza, ponieważ podczas spotkań ogólnych wszyscy uczestnicy mogą jednocześnie włączyć kamery.

Czy można uruchomić Jitsi Meet na VPS z 1 GB RAM?

Instalacja zakończy się powodzeniem, a połączenie dwuosobowe będzie działać, ponieważ Jitsi wykorzystuje tryb peer-to-peer dla dwóch uczestników, całkowicie pomijając videobridge. Nie jest to jednak wydajne rozwiązanie dla połączeń grupowych. Prosody, videobridge oraz środowisko uruchomieniowe Java wymagają znacznych zasobów pamięci; oficjalna dokumentacja zaleca 8 GB RAM dla stabilnego wdrożenia, a ograniczenia pasma staną się problemem szybciej niż brak pamięci. Jeśli dysponujesz jedynie serwerem 1 GB, lepszym wyborem od Jitsi będzie Galène.

Czy nadal potrzebuję serwera TURN, jeśli mój VPS ma publiczny adres IP?

Tak. Problem, który rozwiązuje TURN, występuje po stronie uczestnika połączenia. Uczestnik znajdujący się w sieci korporacyjnej blokującej ruch wychodzący UDP lub za NAT-em klasy operatorskiej, który przypisuje inny port źródłowy dla każdego miejsca docelowego, nie będzie w stanie nawiązać bezpośredniej ścieżki multimedialnej, niezależnie od tego, jak publiczny jest adres Twojego serwera. TURN przez TCP na porcie 443 lub 5349 zapewnia przekaźnik, który dla zapory sieciowej wygląda jak zwykły ruch internetowy. Pakiet instalacyjny Jitsi domyślnie konfiguruje coturn, dlatego udokumentowane reguły zapory sieciowej otwierają porty UDP 3478 oraz TCP 5349.

Dlaczego BigBlueButton wymaga znacznie mocniejszego sprzętu niż Jitsi Meet?

Ponieważ realizuje znacznie więcej zadań niż tylko przekazywanie wideo. Publikowane wymagania produkcyjne to 16 GB RAM oraz 8 rdzeni procesora, w porównaniu do 8 GB RAM i 4 rdzeni w dokumentacji Jitsi. BigBlueButton uruchamia pełny stos konferencji audio, współdzieloną tablicę, warstwę prezentacji, potok nagrywania i przetwarzania końcowego oraz interfejs webowy z kontami użytkowników – wszystko na tej samej maszynie. Projekt narzuca również konkretne środowisko: na sierpień 2026 wspieraną wersją jest 3.0 na Ubuntu 22.04. Obie wartości pochodzą z dokumentacji poszczególnych projektów i stanowią punkty wyjścia, a nie pomiary Twojego rzeczywistego obciążenia.

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