WebRTC - skalowalna transmisja na żywo / multiemisja


114

PROBLEM:

WebRTC zapewnia nam połączenia wideo / audio peer-to-peer. Jest idealny do połączeń p2p, hangoutów. Ale co z nadawaniem (jeden do wielu, na przykład od 1 do 10000)?

Powiedzmy, że mamy nadawcę „B” i dwóch uczestników „A1”, „A2”. Oczywiście wydaje się, że da się to rozwiązać: po prostu łączymy B z A1, a następnie B z A2. Zatem B wysyła strumień wideo / audio bezpośrednio do A1, a inny strumień do A2. B wysyła strumienie dwukrotnie.

Teraz wyobraźmy sobie 10000 uczestników: A1, A2, ..., A10000. Oznacza to, że B musi wysłać 10000 strumieni. Każdy strumień ma ~ 40 KB / s, co oznacza, że ​​B potrzebuje wychodzącej prędkości Internetu 400 MB / s, aby utrzymać tę transmisję. Gorszący.

PYTANIE ORYGINALNE (NIEAKTUALNE)

Czy można to jakoś rozwiązać, więc B wysyła tylko jeden strumień na jakiś serwer, a uczestnicy po prostu pobierają ten strumień z tego serwera? Tak, to znaczy, że prędkość wychodząca na tym serwerze musi być wysoka, ale mogę ją utrzymać.

A może oznacza to zrujnowanie pomysłu WebRTC?

UWAGI

Flash nie działa na moje potrzeby, jak na słaby UX dla klientów końcowych.

ROZWIĄZANIE (NAPRAWDĘ)

26.05.2015 - W tej chwili nie ma takiego rozwiązania do skalowalnego nadawania dla WebRTC, w którym w ogóle nie używasz serwerów multimedialnych. Na rynku dostępne są rozwiązania serwerowe oraz hybrydowe (p2p + serwer w zależności od różnych warunków).

Jest jednak kilka obiecujących technologii, takich jak https://github.com/muaz-khan/WebRTC-Scalable-Broadcast, ale muszą oni odpowiedzieć na te możliwe problemy: opóźnienie, ogólną stabilność połączenia sieciowego, formułę skalowalności (prawdopodobnie nie są one nieskończenie skalowalne ).

PROPOZYCJE

  1. Zmniejsz procesor / przepustowość, dostosowując kodeki audio i wideo;
  2. Zdobądź serwer multimediów.

3
„Jedynym sposobem na zbudowanie skalowalnej aplikacji jest użycie rozwiązania po stronie serwera”. Wydaje się to całkiem jasne ... Jeśli chodzi o WebRTC, nigdy nie był przeznaczony do transmisji na dużą skalę. W tym celu użyj czegoś, co obsługuje multiemisję lub jeśli musisz przejść przez Internet, połączenia jeden do jednego na serwerze, ponieważ dostawcy usług internetowych nie kierują multiemisji.
Dark Falcon

1
Dlaczego nie skorzystać z WebRTC z klienta na serwer? Problem jest w dystrybucji, ponieważ połączenie klienta nie może sobie z tym poradzić, więc wyślij jedną parę na serwer i stamtąd streamuj do klientów. Przepustowość będzie kosztowna, ale nie da się obejść ani wysyłania pojedynczego strumienia do każdego użytkownika, ani zmuszania użytkownika do wysyłania strumienia do innych użytkowników.
Dark Falcon

1
Są co najmniej dwie firmy, o których wiem, że próbują dostarczać wideo p2p w oparciu o webrtc : affovi.com/rtcplayer.html - głównie do wideo na żywo; i peer5.com - głównie dla VOD.
Svetlin Mladenov

1
@igorpavlov Możesz sprawdzić: github.com/muaz-khan/WebRTC-Scalable-Broadcast Chociaż działa tylko w chrome i nie ma jeszcze transmisji audio.
Muaz Khan

4
Nie ma sposobu na osiągnięcie takiej skalowalności bez jakiegoś MCU. WebRTC został zaprojektowany jako peer-to-peer. Nie możesz nadawać z niego bez absolutnego zatrzaśnięcia swojego nadawcy (z unikalnym połączeniem równorzędnym dla każdego strumienia, który stażysta, jest innym kodowanym strumieniem). Jeśli chodzi o przekazywanie mediów z peer-to-peer, mogłoby to być możliwe, ale oczywiście spowodowałoby to dodatkowe opóźnienie dla każdego peera dodanego później do strumienia. Jeśli chodzi o jakość i skalowalność, posiadanie serwera webrtc MCU jest jedynym realistycznym rozwiązaniem.
Benjamin Trent

Odpowiedzi:


66

Ponieważ zostało to prawie omówione tutaj, to, co próbujesz tutaj zrobić, nie jest możliwe w przypadku zwykłego, staromodnego WebRTC (ściśle peer-to-peer). Ponieważ, jak powiedziano wcześniej, połączenia WebRTC renegocjują klucze szyfrowania w celu szyfrowania danych dla każdej sesji. Twój nadawca (B) będzie więc rzeczywiście musiał przesyłać swój strumień tyle razy, ile jest uczestników.

Jest jednak dość proste rozwiązanie, które działa bardzo dobrze: przetestowałem je, nazywa się bramą WebRTC. Janus jest dobrym przykładem. Jest to całkowicie otwarte oprogramowanie ( tutaj repozytorium github ).

Działa to w następujący sposób: Twój nadawca kontaktuje się z bramą (Janus), która mówi w WebRTC . Jest więc negocjacja klucza: B przesyła bezpiecznie (zaszyfrowane strumienie) do Janusa.

Teraz, kiedy uczestnicy łączą się, ponownie łączą się z Janusem: negocjacja WebRTC, zabezpieczone klucze itp. Od tej pory Janus będzie wysyłał strumienie do każdego z uczestników.

Działa to dobrze, ponieważ nadawca (B) przesyła swój strumień tylko raz, do Janusa. Teraz Janus dekoduje dane za pomocą własnego klucza i ma dostęp do surowych danych (czyli pakietów RTP) i może emitować te pakiety z powrotem do każdego uczestnika (Janus zajmie się szyfrowaniem za Ciebie). A ponieważ umieściłeś Janusa na serwerze, ma on świetną przepustowość wysyłania, więc będziesz mógł przesyłać strumieniowo do wielu peerów.

Więc tak, że nie wiążą się z serwerem, ale serwer mówi WebRTC, a ty „własne” go: wdrożyć część Janus, dzięki czemu nie trzeba się martwić o uszkodzenie danych lub mężczyzna w środku. No chyba, że ​​twój serwer jest zagrożony, oczywiście. Ale jest tak wiele, co możesz zrobić.

Aby pokazać ci, jak łatwo jest używać, w Janusie masz funkcję o nazwie incoming_rtp()(i incoming_rtcp()), którą możesz wywołać, która daje wskaźnik do pakietów rt (c) p. Możesz następnie wysłać go do każdego uczestnika (są one przechowywane w sessionstym formacie Janus, który jest bardzo łatwy w użyciu). Spójrz tutaj na jedną implementację incoming_rtp()funkcji , kilka linii poniżej możesz zobaczyć, jak przesyłać pakiety do wszystkich uczestników, a tutaj możesz zobaczyć rzeczywistą funkcję przekazywania pakietu rtp.

Wszystko działa całkiem dobrze, dokumentacja jest dość łatwa do odczytania i zrozumienia. Proponuję zacząć od „najdoskonalszego” przykładu, jest on najprostszy i możesz zrozumieć wewnętrzne działanie Janusa. Proponuję edytować plik testu echa, aby utworzyć własny, ponieważ jest dużo zbędnego kodu do napisania, więc równie dobrze możesz zacząć od pełnego pliku.

Baw się dobrze! Mam nadzieję, że pomogłem.


1
Czy to prawda, że ​​obecnie nie działa to w Safari (lub jakiejkolwiek przeglądarce, która nie obsługuje WebRTC?). Czy ktoś wie o rozwiązaniu hybrydowym, w którym transmitujesz z przeglądarki na serwer za pomocą WebRTC, a następnie transkodujesz wideo do HLS / HDS (lub nawet RTMP), aby dopasować się do tradycyjnego systemu transmisji?
Ben

1
@Ben tak, nie działa z przeglądarkami, które nie obsługują WebRTC. W czasach (kiedy to piszę) Safari najwyraźniej tego nie wspierało. Dziś jednak nie sprawdziłem. Ale nadal uważam, że nie obsługują WebRTC (choć do potwierdzenia). Jeśli chodzi o użycie go w systemie hybrydowym, to jest to jak najbardziej możliwe, właściwie to właśnie zrobiłem dla firmy, w której pracowałem; jak powiedziałeś, nadaję z przeglądarki na serwer, a stamtąd zbudowałem i podłączyłem potok GStreamer, aby transkodować kanał. Ty też możesz to zrobić!
nschoe

masz jakiś pomysł na temat jitsi? czy jitisi też jest tym samym?
ishandutta2007

@nschoe Czy to jest lepsze niż używanie websocket do tego samego?
Navigateur

Właściwie wyjaśniasz, jak działa SFU (Selective Forwarding Unit). Możesz zrobić to samo z mediasoup
Dirk V

11

Jak @MuazKhan zauważył powyżej:

https://github.com/muaz-khan/WebRTC-Scalable-Broadcast

działa w chrome i nie ma jeszcze transmisji audio, ale wydaje się, że jest to pierwsze rozwiązanie.

Scalable WebRTC peer-to-peer demo.

Ten moduł po prostu inicjuje socket.io i konfiguruje go w taki sposób, że pojedyncza transmisja może być przekazywana nieograniczonej liczbie użytkowników bez problemów z przepustowością / wykorzystaniem procesora. Wszystko dzieje się peer-to-peer!

wprowadź opis obrazu tutaj

To zdecydowanie powinno być możliwe do wykonania.
Inni też są w stanie to osiągnąć: http://www.streamroot.io/


1
To wydaje mi się trochę nieaktualne. Jakieś aktualizacje lub przemyślenia na temat tego pomysłu?
igorpavlov

Ponadto, czy w jakikolwiek sposób rozwiązuje problemy z opóźnieniami? Na przykład Peer1 rozmawia z Peer5 i Peer2 ostatecznie traci połączenie. Czy może ta architektura jest dobra tylko dla sieci LAN?
igorpavlov

Czy Streamroot jest podobny do Peer5?
igorpavlov

7

AFAIK, jedyną obecną implementacją, która jest istotna i dojrzała, jest Adobe Flash Player, który od wersji 10.1 obsługuje multiemisję p2p dla transmisji wideo peer to peer.

http://tomkrcha.com/?p=1526 .


1
Ludzie nie zabijają technologii. Technologia sama się zabija, zapewniając bardzo słabe UX, zwłaszcza gdy pozwala na użycie mikrofonu / kamery. Tutaj wygrywa getusermedia.
igorpavlov

Nie mogłem się bardziej zgodzić.
Tom

Czy oprócz złego UX byłoby to rozwiązanie? Serwer mniej?
rubo77

6

Nadawanie „skalowalne” nie jest możliwe w Internecie, ponieważ multiemisja IP UDP jest tam niedozwolona. Ale teoretycznie jest to możliwe w sieci LAN.
Problem z Websockets polega na tym, że nie masz dostępu do RAW UDP z założenia i nie będzie on dozwolony.
Problem z WebRTC polega na tym, że jego kanały danych używają formy SRTP, gdzie każda sesja ma własny klucz szyfrowania . Więc jeśli ktoś nie „wymyśli” lub API pozwoli na współdzielenie jednego klucza sesji pomiędzy wszystkimi klientami, multiemisja jest bezużyteczna.


1
ale czaty już działają z WebRTC, więc każdy widzi każdą wiadomość, więc jeden do wielu powinien jakoś działać również w przypadku wideo
rubo77

@ rubo77 Dane wysyłane za pomocą wiadomości tekstowych to nic w porównaniu z szybkością i ilością danych przesyłanych strumieniami wideo. Dzięki temu czaty mogą z łatwością zawierać więcej użytkowników naraz
Dirk V

5

Istnieje rozwiązanie dostarczania wspomaganego przez rówieśników, co oznacza, że ​​jest to podejście hybrydowe. Zarówno serwer, jak i rówieśnicy pomagają w dystrybucji zasobu. Takie podejście przyjęły peer5.com i peercdn.com .

Jeśli mówimy konkretnie o transmisji na żywo, będzie to wyglądać mniej więcej tak:

  1. Nadawca wysyła wideo na żywo do serwera.
  2. Serwer zapisuje wideo (zwykle również transkoduje je do wszystkich odpowiednich formatów).
  3. Tworzę metadane dotyczące tego strumienia na żywo, zgodne z HLS, HDS lub MPEG_DASH
  4. Konsumenci przeglądają odpowiednią transmisję na żywo, a odtwarzacz pobiera metadane i wie, które fragmenty filmu mają być następne.
  5. W tym samym czasie konsument jest połączony z innymi konsumentami (przez WebRTC)
  6. Następnie gracz pobiera odpowiedni fragment bezpośrednio z serwera lub od rówieśników.

Podążanie za takim modelem może zaoszczędzić do ~ 90% przepustowości serwera w zależności od szybkości transmisji na żywo i wspólnego łącza w górę widzów.

zastrzeżenie: autor pracuje w Peer5


Dziękuję Ci. Wiem o peer5 i uważam to za całkiem atrakcyjne rozwiązanie. Jednak celem tego pytania było znalezienie rozwiązania całkowicie bezserwerowego (dozwolone tylko STUN / TURN).
igorpavlov

5

Moi mistrzowie koncentrują się na rozwoju hybrydowego protokołu transmisji strumieniowej na żywo cdn / p2p przy użyciu WebRTC. Pierwsze wyniki opublikowałem pod adresem adresem http://bem.tv

Wszystko jest open source i szukam współpracowników! :-)


Czy używasz jakiegokolwiek oprogramowania po stronie serwera, takiego jak MCU?
igorpavlov

Właściwie używam niektórych komponentów po stronie serwera od ludzi rtcio: github.com/rtc-io
flavioribeiro

1
Wygląda na to, że używasz ich komponentów do sygnalizacji. A co z przesyłaniem strumieniowym wideo po stronie serwera? A może rozwiązaniem jest absolutnie P2P?
igorpavlov

przepraszam za długie opóźnienie w udzieleniu odpowiedzi @igorpavlov, używam EvoStream do segmentowania filmów i zapętlam źródło wideo i wskazuję EvoStream za pomocą kodera Elemental.
flavioribeiro

Jest dostawcą serwerów multimedialnych. Bardziej wydajny? Prawdopodobnie. Czy tego szukam? Nie.
igorpavlov

2

Odpowiedź udzielona przez Angel Genchev wydaje się być poprawna, jednak istnieje teoretyczna architektura, która umożliwia transmisję z niskim opóźnieniem przez WebRTC. Wyobraź sobie, że B (nadawca) przesyła strumieniowo do A1 (uczestnik 1). Następnie A2 (uczestnik 2) łączy. Zamiast przesyłania strumieniowego z B do A2, A1 rozpoczyna przesyłanie strumieniowe wideo z B do A2. Jeśli A1 się rozłączy, A2 zacznie odbierać od B.

Ta architektura może działać, jeśli nie ma opóźnień i limitów czasu połączenia. Więc teoretycznie jest to słuszne, ale nie praktycznie.

W tej chwili korzystam z rozwiązania po stronie serwera.


A co z prędkością strumienia w rozwiązaniu po stronie serwera? Proszę Podziel się.
user2003356

Rozwiązanie po stronie serwera oznacza? Czego użyłeś? Byłoby to pomocne w moich badaniach. Proszę Podziel się. Dzięki.
user2003356

Rozwiązanie po stronie serwera oznacza Opentok firmy Tokbox. Nie reklamuję ich, na rynku jest mnóstwo takich rozwiązań, ale ja się przy tym trzymam. Działa jak serwer multimediów. PS Co masz na myśli mówiąc o komunikacji wielostronnej? Nie rozumiem.
igorpavlov

@igorpavlov Czy mógłbyś podać listę firm, które zapewniają webrtc po stronie serwera? Znam tylko Flashphonera i Opentoka. Dzięki
Ramil Amerzyanov

Byłbym ciekawy, czy to rzeczywiście się skaluje. Z pewnością wystąpią problemy ze skalowaniem opóźnień w OGROMNYCH grupach (1000+), ale jeśli jest ich tylko 5-10, wyobrażam sobie, że działałoby całkiem nieźle, ale potrzebna byłaby wymyślna praca nóg, gdyby ktoś znajdował się w środku łańcucha rówieśników „opuszcza i ponownie łączy wszystkie kolejne peery, jeśli jest to tylko jeden łańcuch, byłoby OGROMNE. Lepiej byłoby użyć binarnej / trójskładnikowej struktury drzewa.
Benjamin Trent,

2

Na rynku dostępnych jest kilka rozwiązań skalowalnych WebRTC. Zapewniają niskie opóźnienia i skalowalne przesyłanie strumieniowe webrtc. Oto kilka próbek. Janus , Jitsi , Wowza , Red5pro , Ant Media Server

Jestem programistą dla Ant Media Server , dostarczam zarówno wersję dla społeczności, jak i dla przedsiębiorstw, w tym Android i iOS SDK. Daj nam znać, jeśli możemy Ci jakoś pomóc.


1

Opisujesz używanie WebRTC z wymogiem „jeden do wielu”. WebRTC jest przeznaczony do przesyłania strumieniowego peer-to-peer, jednak istnieją konfiguracje, które pozwolą Ci skorzystać z małego opóźnienia WebRTC podczas dostarczania wideo do wielu widzów.

Sztuczka polega na tym, aby nie obciążać klienta przesyłania strumieniowego każdą przeglądarką i, jak wspomniałeś, mieć „przekaźnikowy” serwer multimediów. Możesz to zbudować samodzielnie, ale szczerze mówiąc, najlepszym rozwiązaniem jest często użycie czegoś takiego jak produkt Wowza do przesyłania strumieniowego WebRTC .

Aby wydajnie przesyłać strumieniowo z telefonu, możesz użyć GoCoder SDK firmy Wowza, ale z mojego doświadczenia wynika, że bardziej zaawansowany pakiet SDK, taki jak StreamGears, działa najlepiej.


1

Rozwijam system transmisji WebRTC przy użyciu serwera Kurento Media Server . Kurento Obsługuje kilka rodzajów protokołów przesyłania strumieniowego, takich jak RTSP, WebRTC, HLS. Działa również w czasie rzeczywistym i skalowaniu.

W związku z tym Kurento nie obsługuje RTMP, który jest teraz używany w YouTube lub Twitch. Jednym z problemów ze mną jest liczba użytkowników jednocześnie z tym.

Mam nadzieję, że to pomoże.


0

Ponieważ peer1 jest tylko peerem, który wywołuje getUserMedia (), tj. Peer1 tworzy pokój.

  1. Tak więc peer1 przechwytuje multimedia i rozpoczyna pokój.
  2. peer2 dołącza do pokoju i pobiera strumień (dane) z peer1, a także otwiera połączenie równoległe o nazwie „peer2-connection”
  3. Kiedy peer3 dołącza do pokoju i pobiera strumień (dane) z peer2, a także otwiera połączenie równoległe o nazwie „peer3-connection” i tak dalej.

Ten proces jest ciągły, ponieważ wielu rówieśników łączy się ze sobą.

W związku z tym pojedyncza transmisja może zostać przekazana nieograniczonej liczbie użytkowników bez żadnych problemów z przepustowością / wykorzystaniem procesora.

Wreszcie, wszystko powyżej zawarte jest odniesieniem z Link .


1
To podejście zostało już wspomniane, ale może nie działać w prawdziwym świecie. Jako Peer3, dlaczego powinienem przejmować się przepustowością Peer2? Oczywiście Peer3 może powrócić do Peer1, jeśli Peer2 opuści łańcuch, ale spowoduje to mnóstwo przerw w strumieniu, ponownych połączeń itp. Im dalej jestem w łańcuchu, tym bardziej będę cierpieć. Więc tak, może działać w sieci LAN, ale prawdopodobnie to wszystko.
igorpavlov

Równoległe rozgłaszanie nie zajmuje się przepustowością i jeśli po ustanowieniu połączenia peer3 do peer1 przez peer2 i tak, że peer2 cofnie się, peer3 pozostanie połączony z peer1.
susan097

Nie jestem pewien, czy rozumiem. Właściwie nie odnosiłem się do linku, teraz pozwól mi się odnieść. Ten link github.com/muaz-khan/WebRTC-Scalable-Broadcast zawiera obraz w sekcji „Jak to działa?” Sekcja. Ten obraz jasno pokazuje, że gdy, powiedzmy, Peer5 rozłączy się, Peer8,9 i 10 zostaną odłączone od transmisji. Będą musieli połączyć się z Peer2 lub Peer6, ale spowoduje to opóźnienia. Ponadto ten projekt nie ma ani współautorów, ani aktywności.
igorpavlov
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.