WebRTC to nowy front w długiej wojnie o otwartą i wolną sieć.
Brenan Eich, wynalazca JavaScriptu
Komunikacja w czasie rzeczywistym bez konieczności używania wtyczek
Wyobraź sobie, że Twój telefon, telewizor i komputer mogą komunikować się na wspólnej platformie. Wyobraź sobie, że dodanie do swojej aplikacji internetowej czatu wideo i udostępniania danych peer-to-peer jest proste. To jest wizja WebRTC.
Chcesz wypróbować tę funkcję? WebRTC jest dostępny na komputerach i urządzeniach mobilnych w przeglądarkach Google Chrome, Safari, Firefox i Opera. Na początek możesz skorzystać z aplikacji do czatu wideo dostępnej pod adresem appr.tc:
- Otwórz appr.tc w przeglądarce.
- Kliknij Dołącz, aby dołączyć do pokoju czatu i pozwolić aplikacji na użycie kamery internetowej.
- Otwórz adres URL wyświetlony na końcu strony w nowej karcie, a mimo to na innym komputerze.
Krótkie wprowadzenie
Nie masz czasu na czytanie tego artykułu lub potrzebujesz tylko kodu?
- Aby zapoznać się z omówieniem WebRTC, obejrzyj ten film z Google I/O lub obejrzyj te slajdy:
- Jeśli nie korzystasz jeszcze z interfejsu API
getUserMedia
, zapoznaj się z artykułami Przechwytywanie dźwięku i wideo w HTML5 oraz simpl.info getUserMedia. - Aby poznać interfejs API
RTCPeerConnection
, zobacz przykład poniżej i 'simpl.info RTCPeerConnection'. - Aby dowiedzieć się, jak WebRTC używa serwerów do sygnalizowania oraz omijania zapory sieciowej i NAT, zapoznaj się z kodem i logami konsoli z appr.tc.
- Nie możesz się doczekać i chcesz już teraz wypróbować WebRTC? Wypróbuj ponad 20 prezentacji, w których wykorzystywano interfejsy API JavaScript WebRTC.
- Masz problem z komputerem i WebRTC? Otwórz narzędzie do rozwiązywania problemów z WebRTC.
Możesz też od razu przejść do ćwiczeń w Codelabs, czyli szczegółowego przewodnika, który wyjaśnia, jak stworzyć kompletną aplikację do obsługi czatu wideo, w tym prosty serwer sygnałów.
Bardzo krótka historia WebRTC
Jednym z ostatnich głównych wyzwań związanych z internetem jest umożliwienie komunikacji głosowej i wideo za pomocą komunikacji w czasie rzeczywistym (w skrócie RTC). W aplikacji internetowej RTC powinno być tak samo naturalne, jak wpisywanie tekstu. Bez tego narzędzia Twoje możliwości wprowadzania innowacji i opracowywania nowych sposobów interakcji użytkowników są ograniczone.
W przeszłości RTC było korporacyjnym i złożonym procesem, który wymagał posiadania licencji lub tworzenia kosztownych technologii audio i wideo we własnej firmie. Integracja technologii RTC z istniejącymi treściami, danymi i usługami była trudna i czasochłonna, szczególnie w internecie.
Czat wideo w Gmailu stał się popularny w 2008 roku, a w 2011 roku wprowadziliśmy usługę Hangouts, która używa Google Talk (podobnie jak Gmail). Kupiliśmy GIPS – firmę, która opracowała wiele komponentów wymaganych do działania RTC, takich jak kodeki i techniki usuwania echa. Google udostępnia technologie opracowane przez GIPS na zasadach open source i podejmuje współpracę z odpowiednimi organami ds. standardów w Internet Engineering Task Force (IETF) i W3C (World Wide Web Consortium) w celu osiągnięcia konsensusu w branży. W maju 2011 r. firma Ericsson opracowała pierwszą implementację WebRTC.
WebRTC wdrożył otwarte standardy w czasie rzeczywistym, bez wtyczek do komunikacji wideo, audio i danych w czasie rzeczywistym. Potrzeba była naprawdę realna:
- Wiele usług internetowych używało RTC, ale wymagało pobrania plików, aplikacji natywnych lub wtyczek. takich jak Skype, Facebook i Hangouts.
- Pobieranie, instalowanie i aktualizowanie wtyczek jest skomplikowane, podatne na błędy i irytujące.
- Wtyczki są trudne do wdrożenia, debugowania, rozwiązywania problemów, testowania i utrzymywania oraz mogą wymagać licencjonowania i integracji ze złożoną, kosztowną technologią. Często trudno skłonić ludzi do zainstalowania wtyczek.
W projekcie WebRTC kierujemy się tym, że jego interfejsy API powinny być bezpłatne, ustandaryzowane, wbudowane w przeglądarki i być bardziej wydajne niż istniejące technologie.
Gdzie teraz jesteśmy?
WebRTC jest używany w różnych aplikacjach, takich jak Google Meet. WebRTC został też zintegrowany z aplikacjami natywnymi WebKitGTK+ i Qt.
WebRTC implementuje te 3 interfejsy API:
– MediaStream
(znany też jako getUserMedia
)
– RTCPeerConnection
– RTCDataChannel
Interfejsy API są zdefiniowane w tych 2 specyfikacjach:
Wszystkie 3 interfejsy API są obsługiwane na urządzeniach mobilnych i komputerach przez przeglądarki Chrome, Safari, Firefox, Edge i Opera.
getUserMedia
: wersje demonstracyjne i kod znajdziesz w przykładach z WebRTC lub w niesamowitych przykładach Chrisa Wilsona, w których getUserMedia
jest używany jako dane wejściowe dla audio z internetu.
RTCPeerConnection
: prostą prezentację i w pełni funkcjonalną aplikację do czatu wideo znajdziesz odpowiednio w sekcjach Przykłady połączenia równorzędnego WebRTC i appr.tc. Aplikacja wykorzystuje adapter.js – podkładkę JavaScript obsługiwaną przez Google przy pomocy społeczności WebRTC, aby wyodrębnić różnice między przeglądarkami i zmiany specyfikacji.
RTCDataChannel
: aby zobaczyć, jak to działa w praktyce, zapoznaj się z przykładami z WebRTC w celu zapoznania się z jedną z wersji demonstracyjnych kanału danych.
Ćwiczenie z programowania w WebRTC pokazuje, jak przy użyciu wszystkich 3 interfejsów API stworzyć prostą aplikację do czatu wideo i udostępniania plików.
Twój pierwszy WebRTC
Aplikacje WebRTC muszą wykonać kilka czynności:
- Odtwarzaj strumieniowane dane audio i wideo lub inne dane.
- Pobieraj informacje o sieci, takie jak adresy IP i porty, i wymieniaj je z innymi klientami WebRTC (nazywanymi peerami), aby umożliwić połączenie, nawet przez NAT i zapory sieciowe.
- Skoordynuj komunikację w celu zgłaszania błędów i zainicjowania lub zakończenia sesji.
- Wymiana informacji o multimediach i możliwościach klienta, na przykład o rozdzielczości i kodekach.
- Komunikacja strumieniowych transmisji dźwięku, wideo lub danych.
Aby pozyskać i przekazać strumieniowane dane, WebRTC implementuje te interfejsy API:
MediaStream
uzyskuje dostęp do strumieni danych, np. z kamery i mikrofonu użytkownika.RTCPeerConnection
umożliwia prowadzenie rozmów audio i wideo z funkcjami do szyfrowania i zarządzania przepustowością.RTCDataChannel
umożliwia komunikację peer-to-peer danych ogólnych.
(Później szczegółowo omówiono sieć i sygnały dotyczące aspektów WebRTC).
MediaStream
API (znany też jako getUserMedia
API)
MediaStream
API reprezentuje zsynchronizowane strumienie multimediów. Na przykład strumień przesłany z kamery i mikrofonu ma zsynchronizowane ścieżki wideo i audio. (Nie mylić elementu MediaStreamTrack
z elementem <track>
, który jest zupełnie inny).
Chyba najprostszym sposobem na zrozumienie interfejsu API MediaStream
jest spojrzenie na niego „środowisko”:
- W przeglądarce przejdź do przykładów WebRTC
getUserMedia
. - Otwórz konsolę.
- Sprawdź zmienną
stream
, która znajduje się w zakresie globalnym.
Każdy element MediaStream
ma dane wejściowe, którymi może być MediaStream
wygenerowany przez getUserMedia()
, oraz dane wyjściowe, które mogą być przekazywane do elementu wideo lub RTCPeerConnection
.
Metoda getUserMedia()
pobiera parametr obiektu MediaStreamConstraints
i zwraca wartość Promise
, która zwraca obiekt MediaStream
.
Każdy element MediaStream
ma element label
, np. 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
. Tablica MediaStreamTrack
jest zwracana przez metody getAudioTracks()
i getVideoTracks()
.
W przykładzie dotyczącym getUserMedia
funkcja stream.getAudioTracks()
zwraca pustą tablicę (ponieważ nie ma dźwięku). Jeśli podłączona jest działająca kamera internetowa, stream.getVideoTracks()
zwraca tablicę o wartości MediaStreamTrack
, która reprezentuje strumień z kamery internetowej. Każdy element MediaStreamTrack
ma rodzaj ('video'
lub 'audio'
), label
(np. 'FaceTime HD Camera (Built-in)'
) i reprezentuje co najmniej jeden kanał audio lub wideo. W tym przypadku jest tylko 1 ścieżka wideo bez dźwięku, ale można sobie wyobrazić sytuacje, w których jest ich więcej, np. aplikacja do obsługi czatu, która pobiera strumienie z przedniego aparatu, tylnego aparatu, mikrofonu i aplikacji udostępniającej ekran.
Element MediaStream
można dołączyć do elementu wideo, ustawiając atrybut srcObject
. Wcześniej można było to robić przez ustawienie atrybutu src
adresu URL obiektu utworzonego za pomocą metody URL.createObjectURL()
, ale to ustawienie zostało wycofane.
Interfejsu getUserMedia
można też użyć jako węzła wejściowego interfejsu Web Audio API:
// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
console.log('Sorry! Web Audio not supported.');
}
// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;
// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;
navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
// Create an AudioNode from the stream.
const mediaStreamSource =
audioContext.createMediaStreamSource(stream);
mediaStreamSource.connect(filterNode);
filterNode.connect(gainNode);
// Connect the gain node to the destination. For example, play the sound.
gainNode.connect(audioContext.destination);
});
Aplikacje i rozszerzenia oparte na Chromium mogą też obejmować kod getUserMedia
. Dodanie uprawnień audioCapture
lub videoCapture
do pliku manifestu powoduje, że podczas instalacji można poprosić o uprawnienia i przyznać je tylko raz. Od tego momentu użytkownik nie będzie pytany o zgodę na dostęp do kamery lub mikrofonu.
Uprawnienia można przyznać tylko raz w przypadku aplikacji getUserMedia()
. Za pierwszym razem przycisk Zezwalaj wyświetla się na pasku informacyjnym przeglądarki. Dostęp HTTP do strony getUserMedia()
został wycofany przez Chrome pod koniec 2015 roku, ponieważ został sklasyfikowany jako zaawansowana funkcja.
Potencjalnie ma to na celu włączenie MediaStream
dla dowolnego źródła strumieniowych danych, a nie tylko dla kamery lub mikrofonu. Umożliwi to strumieniowanie danych z przechowywanych danych lub dowolnych źródeł danych, takich jak czujniki i inne dane wejściowe.
getUserMedia()
działa w połączeniu z innymi interfejsami API i bibliotekami JavaScript:
- Webcam Toy to aplikacja do tworzenia fotobudki, która korzysta z WebGL, aby dodawać dziwne i cudowne efekty do zdjęć, które można udostępnić lub zapisać lokalnie.
- FaceKat to gra ze śledzeniem twarzy stworzona za pomocą pliku headtrackr.js.
- Aparat ASCII wykorzystuje interfejs Canvas API do generowania obrazów ASCII.
Ograniczenia
Ograniczenia pozwalają ustawić wartości rozdzielczości wideo w przypadku parametru getUserMedia()
. Pozwala to też obsługiwać inne ograniczenia, takie jak współczynnik proporcji. tryb przedni (przedni lub tylny aparat); liczba klatek, wysokość i szerokość; i applyConstraints()
.
Przykład znajdziesz w sekcji Przykłady WebRTC getUserMedia
: wybierz rozdzielczość.
Ustawienie niedozwolonej wartości ograniczenia daje wartość DOMException
lub OverconstrainedError
, jeśli na przykład żądana rozdzielczość jest niedostępna. Aby zobaczyć, jak to działa, zapoznaj się z przykładami z WebRTC getUserMedia
: wybierz rozdzielczość, aby zobaczyć wersję demonstracyjną.
Zrzut ekranu i karty
Aplikacje Chrome umożliwiają też udostępnianie filmu na żywo z jednej karty przeglądarki lub całego pulpitu za pomocą interfejsów API chrome.tabCapture
i chrome.desktopCapture
. (Demonstrację i więcej informacji znajdziesz w artykule Udostępnianie ekranu za pomocą WebRTC. Artykuł ma już kilka lat, ale nadal jest ciekawy).
Przechwytywania ekranu można też używać jako źródła MediaStream
w Chrome przy użyciu eksperymentalnego ograniczenia chromeMediaSource
. Pamiętaj, że zrzuty ekranu wymagają protokołu HTTPS i należy go używać tylko do programowania, ponieważ umożliwia to włączenie za pomocą flagi wiersza poleceń, co wyjaśniono w tym poście.
Sygnały: kontrola sesji, informacje o sieci i multimediach
WebRTC używa interfejsu RTCPeerConnection
do przekazywania strumieniowych danych między przeglądarkami (nazywanych też „połączeniami równorzędnymi”), ale potrzebuje też mechanizmu koordynowania komunikacji i wysyłania komunikatów kontrolnych. Jest to tzw. przekazywanie sygnałów. Metody i protokoły sygnałów nie są określane przez WebRTC. Sygnały nie są częścią interfejsu API RTCPeerConnection
.
Zamiast tego deweloperzy aplikacji WebRTC mogą wybrać dowolny preferowany protokół przesyłania wiadomości, na przykład SIP lub XMPP, oraz dowolny odpowiedni kanał komunikacji dwukierunkowej (dwukierunkowej). W przykładzie appr.tc jako mechanizmem sygnałowym używany jest XHR i Channel API. Ćwiczenia z programowania korzystają z usługi Socket.io uruchomionej na serwerze węzła.
Za pomocą sygnałów wymieniane są 3 rodzaje informacji:
- Komunikaty dotyczące kontroli sesji: umożliwiają zainicjowanie lub zakończenie komunikacji i zgłoszenie błędów.
- Konfiguracja sieci: na zewnątrz jaki jest adres IP i port Twojego komputera?
- Możliwości związane z multimediami: jakie kodeki i rozdzielczości obsługuje Twoja przeglądarka i przeglądarka, z którą chce się komunikować?
Przed rozpoczęciem strumieniowania peer-to-peer wymagana jest wymiana informacji za pomocą sygnałów.
Załóżmy, że Alicja chce się komunikować z Robertem. Oto przykładowy kod ze specyfikacji W3C WebRTC, który przedstawia proces sygnalizowania w działaniu. Kod zakłada, że istnieje taki mechanizm, który został utworzony w metodzie createSignalingChannel()
. Pamiętaj też, że w Chrome i Operze prefiks RTCPeerConnection
ma obecnie prefiks.
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// Send the offer to the other peer.
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
Najpierw Alicja i Robert wymieniają się informacjami o sieci. Wyrażenie Znajdowanie kandydatów oznacza proces znajdowania interfejsów sieci i portów za pomocą platformy ICE.
- Alicja tworzy obiekt
RTCPeerConnection
z modułem obsługionicecandidate
, który uruchamia się, gdy dostępne są kandydatów do sieci. - Alicja wysyła do Roberta zserializowane dane kandydatów za pomocą dowolnego kanału sygnału, którego używa, np. WebSocket lub innego mechanizmu.
- Gdy Robert otrzyma wiadomość od Alicji, dzwoni pod numer
addIceCandidate
, by dodać kandydata do opisu zdalnego ucznia.
Klienty WebRTC (nazywane w tym przykładzie peerami lub Alicja i Robert) także muszą określić i wymieniać lokalne i zdalne informacje o multimediach (audio i wideo), takie jak funkcje rozdzielczości i kodeków. Sygnał informujący o możliwości wymiany informacji o konfiguracji mediów to proces wymiany oferty i odpowiedzi przy użyciu protokołu Session description Protocol (SDP):
- Alicja uruchamia metodę
RTCPeerConnection
createOffer()
. Zwrot z tego wyniku jest przekazywany doRTCSessionDescription
– opis sesji lokalnej Alicji. - W wywołaniu zwrotnym Alicja ustawia opis lokalny za pomocą pola
setLocalDescription()
, a następnie wysyła opis sesji Robertowi za pomocą swojego kanału sygnału. Pamiętaj, że funkcjaRTCPeerConnection
nie zacznie gromadzić kandydatów, dopóki nie zostanie wywołana funkcjasetLocalDescription()
. Zostało to zakodowane w wersji roboczej IETF JSEP. - Jako opis zdalny Robert ustawia opis przesłany przez Alicję za pomocą funkcji
setRemoteDescription()
. - Robert korzysta z metody
RTCPeerConnection
createAnswer()
, przekazując do niej zdalny opis, który otrzymał od Alicji, aby umożliwić wygenerowanie sesji lokalnej zgodnej z jej. Wywołanie zwrotnecreateAnswer()
jest przekazywane dzięki funkcjiRTCSessionDescription
. Robert ustawia go jako lokalny opis i wysyła go do Alicji. - Gdy Alicja otrzyma opis sesji Michała, ustawia go jako opis zdalny w aplikacji
setRemoteDescription
. - Ping!
Obiekty RTCSessionDescription
to obiekty blob zgodne z protokołem SDP sesji. Zserializowany obiekt SDP wygląda tak:
v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126
// ...
a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810
Pozyskiwanie i wymiana informacji o sieci oraz mediach może odbywać się jednocześnie, ale oba te procesy muszą się zakończyć przed rozpoczęciem strumieniowania audio i wideo między urządzeniami równorzędnymi.
Opisana wcześniej architektura ofert/odpowiedzi nosi nazwę JavaScript Session Development Protocol (JSEP). (W filmie demonstracyjnym Ericssona znajduje się świetna animacja objaśniająca proces sygnalizowania i przesyłania strumieniowego w związku z pierwszą implementacją WebRTC.
Po pomyślnym zakończeniu procesu sygnalizacji dane mogą być przesyłane strumieniowo bezpośrednio peer-to-peer, między elementem wywołującym a wywołującym. Jeśli to się nie uda, możesz też skorzystać z serwera przekazującego pośredniczącego (więcej informacji na ten temat później). Strumieniowe przesyłanie danych jest zadaniem RTCPeerConnection
.
RTCPeerConnection
RTCPeerConnection
to komponent WebRTC, który obsługuje stabilną i wydajną komunikację strumieniowych danych między peerami.
Poniżej znajduje się schemat architektury WebRTC przedstawiający rolę RTCPeerConnection
. Jak widać, fragmenty zielone są złożone!
Z perspektywy języka JavaScript najważniejsze jest to, że ten schemat RTCPeerConnection
chroni programistów przed niezliczonymi zawiłościami, które kryją się pod nimi. Kodeki i protokoły używane przez WebRTC wykonują mnóstwo pracy, aby umożliwić komunikację w czasie rzeczywistym nawet w niezawodnych sieciach:
- Ukrywanie przed utratą pakietów
- Usuwanie echa
- Dostosowanie przepustowości
- Dynamiczne buforowanie zakłóceń
- Automatyczna kontrola wzmocnienia
- Redukcja i wyciszanie szumów
- Czyszczenie obrazów
Poprzedni kod W3C przedstawia uproszczony przykład WebRTC z perspektywy sygnałów. Poniżej znajdziesz przewodniki po 2 działających aplikacjach WebRTC. Pierwszym z nich jest prosty przykład prezentujący usługę RTCPeerConnection
, a drugi to w pełni działającego klienta czatu wideo.
RTCPeerConnection bez serwerów
Następujący kod został pobrany z przykładowych połączeń równorzędnych z WebRTC, które na jednej stronie ma lokalny i zdalny RTCPeerConnection
(oraz lokalny i zdalny film). Nie oznacza to niczego przydatnego – elementy wywołujące i wywołujący są na tej samej stronie, ale sprawia, że działanie interfejsu API RTCPeerConnection
jest nieco bardziej przejrzyste, ponieważ obiekty RTCPeerConnection
na stronie mogą bezpośrednio wymieniać się danymi i wiadomościami bez konieczności używania pośrednich mechanizmów sygnalizowania.
W tym przykładzie pc1
reprezentuje lokalny peer (wywołujący), a pc2
– zdalnym (wywołaniem).
Rozmówca
- Utwórz nowy
RTCPeerConnection
i dodaj strumień z usługigetUserMedia()
: ```js // Serwery to opcjonalny plik konfiguracji. (Zobacz dyskusje TURN i STUN w dalszej części). pc1 = nowe połączenie RTCPeerConnection(serwery); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
- Utwórz ofertę i ustaw ją jako lokalny opis lokalizacji
pc1
oraz jako opis zdalny dla:pc2
. Można to zrobić bezpośrednio w kodzie bez użycia sygnałów, ponieważ rozmówca i odbiorca są na tej samej stronie:js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );
Odbiorca
- Utwórz
pc2
, a po dodaniu strumienia zpc1
wyświetl go w elemencie wideo:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }
RTCPeerConnection
interfejs API plus serwery
W prawdziwym świecie WebRTC potrzebuje serwerów, nawet tych prostych, więc mogą wystąpić takie sytuacje:
- Użytkownicy odkrywają się nawzajem i wymieniają się informacjami ze świata rzeczywistego, takimi jak imiona i nazwiska.
- Aplikacje klienckie WebRTC (równorzędne) wymieniają informacje o sieci.
- Współpracownicy wymieniają się danymi dotyczącymi multimediów, takimi jak format wideo i rozdzielczość.
- Aplikacje klienckie WebRTC przemierzają bramy NAT i zapory sieciowe.
Innymi słowy, WebRTC potrzebuje 4 typów funkcji po stronie serwera:
- Odkrywanie treści przez użytkowników i komunikacja z nimi
- Wysyłanie sygnałów
- Omijanie NAT/zapory sieciowej
- Serwery przekazujące w przypadku niepowodzenia komunikacji peer-to-peer
Przemierzanie NAT, sieci peer-to-peer oraz wymagania związane z tworzeniem aplikacji serwerowej do wykrywania i sygnalizowania użytkowników wykraczają poza zakres tego artykułu. Wystarczy dodać, że protokół STUN i jego rozszerzenie, TURN, są używane przez platformę ICE do umożliwienia usłudze RTCPeerConnection
obsługi translacji NAT i innych wag sieci.
ICE to platforma do łączenia rówieśników, np. 2 klienty czatu wideo. Początkowo ICE próbuje łączyć się z peerami bezpośrednio przy najniższym możliwym czasie oczekiwania przez UDP. W tym procesie serwery STUN muszą wykonać jedno zadanie: umożliwić połączenie równorzędne za NAT w celu uzyskania informacji o jego adresie publicznym i porcie. Więcej informacji o STUN i TURN znajdziesz w artykule o tworzeniu usług backendu potrzebnych do działania aplikacji WebRTC.
Jeśli UDP nie powiedzie się, ICE spróbuje użyć protokołu TCP. Jeśli nie uda się nawiązać połączenia bezpośredniego – szczególnie z powodu omijania NAT i zapór sieciowych – ICE używa pośredniego (przekaźnika) serwera TURN. Inaczej mówiąc, ICE najpierw używa protokołu STUN z protokołem UDP, aby bezpośrednio łączyć się ze sobą, a jeśli to nie pomoże, przełącza się na serwer przekazujący TURN. Wyrażenie znalezienie kandydatów odnosi się do procesu znajdowania interfejsów sieci i portów.
Inżynier WebRTC Justin Uberti podaje więcej informacji o ICE, STUN i TURN w prezentacji WebRTC na Google I/O w 2013 roku. (slajdy prezentacji zawierają przykłady implementacji na serwerze TURN i STUN).
Prosty czat wideo
Dobrym miejscem, w którym warto wypróbować WebRTC, wraz z sygnałami oraz omijaniem zabezpieczeń NAT/zapory sieciowej z wykorzystaniem serwera STUN, jest demonstracja czatu wideo pod adresem appr.tc. Aplikacja wykorzystuje adapter.js, podkładkę, która zabezpiecza aplikacje przed zmianami w specyfikacjach i różnicami w prefiksach.
Kod jest celowo szczegółowy. Sprawdź w konsoli kolejność zdarzeń. Poniżej znajduje się szczegółowy przewodnik po kodzie.
Topologie sieci
WebRTC, obecnie zaimplementowany, obsługuje tylko komunikację jeden do jednego, ale można go używać w bardziej złożonych scenariuszach sieciowych, takich jak połączenie między sobą wielu równorzędnych sieci lub jednostka sterująca wielopunktową (MCU), czyli serwer obsługujący dużą liczbę uczestników i selektywne przekazywanie strumienia, a także miksowanie lub nagrywanie dźwięku i obrazu.
Wiele istniejących aplikacji WebRTC prezentuje jedynie komunikację między przeglądarkami, jednak serwery bramy mogą umożliwić aplikacji WebRTC uruchomionej w przeglądarce interakcję z urządzeniami, takimi jak telefony (znane też jako PSTN) i systemy VOIP. W maju 2012 r. firma Doubango Telecom opublikowała klienta SIPml5 SIP stworzonego w oparciu o WebRTC i WebSocket, który między innymi umożliwia prowadzenie rozmów wideo między przeglądarkami i aplikacjami działającymi na iOS i Androida. Na konferencji Google I/O firmy Tethr i Tropo zaprezentowały platformę do komunikacji w sytuacjach kryzysowych w akterze, wykorzystując komórkę OpenBTS do obsługi komunikacji między telefonami z podstawową przeglądarką a komputerami za pomocą WebRTC. Komunikacja telefoniczna bez operatora!
<RTCDataChannel
API
Oprócz audio i wideo WebRTC obsługuje komunikację w czasie rzeczywistym w przypadku innych typów danych.
Interfejs RTCDataChannel
API umożliwia wymianę dowolnych danych peer-to-peer z krótkim czasem oczekiwania i dużą przepustowością. Aby dowiedzieć się, jak utworzyć prostą aplikację do przenoszenia plików, zapoznaj się odpowiednio z przykładami z WebRTC i ćwiczeniami z programowania dotyczącymi WebRTC (odpowiednio).
Jest wiele potencjalnych zastosowań interfejsu API, w tym:
- Gry
- Aplikacje Pulpitu zdalnego
- Czat tekstowy w czasie rzeczywistym
- Przesyłanie plików
- Zdecentralizowane sieci
Interfejs API ma kilka funkcji, które pozwalają w pełni wykorzystać możliwości RTCPeerConnection
oraz zapewnić zaawansowaną i elastyczną komunikację peer-to-peer:
- Wykorzystanie
RTCPeerConnection
konfiguracji sesji - Kilka kanałów równoczesnych z określaniem priorytetów
- Niezawodna i niewiarygodna semantyka dostarczania
- Wbudowane zabezpieczenia (DTLS) i kontrola zatoru
- Możliwość korzystania z dźwięku lub wideo albo bez nich
Składnia celowo podobna do WebSocket z metodą send()
i zdarzeniem message
:
const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
localConnection.createDataChannel('sendDataChannel');
// ...
remoteConnection.ondatachannel = (event) => {
receiveChannel = event.channel;
receiveChannel.onmessage = onReceiveMessage;
receiveChannel.onopen = onReceiveChannelStateChange;
receiveChannel.onclose = onReceiveChannelStateChange;
};
function onReceiveMessage(event) {
document.querySelector("textarea#send").value = event.data;
}
document.querySelector("button#send").onclick = () => {
var data = document.querySelector("textarea#send").value;
sendChannel.send(data);
};
Komunikacja odbywa się bezpośrednio między przeglądarkami, więc funkcja RTCDataChannel
może działać znacznie szybciej niż WebSocket, nawet jeśli w przypadku niepowodzenia operacji wykonywania dziur w celu radzenia sobie z zaporami sieciowymi i serwerami NAT wymagany jest serwer przekazujący (TURN).
Aplikacja RTCDataChannel
jest dostępna w przeglądarkach Chrome, Safari, Firefox, Opera i Samsung Internet. Gra Cube Slam używa interfejsu API do przekazywania informacji o stanie gry. Zagraj z przyjacielem lub zagraj w niedźwiedzia. Innowacyjna platforma Sharefest włączyła udostępnianie plików przez RTCDataChannel
i peerCDN, a potem pokazuje, jak WebRTC może umożliwić dystrybucję treści metodą peer-to-peer.
Więcej informacji o RTCDataChannel
znajdziesz w wersji roboczej protokołu IETF.
Bezpieczeństwo
Aplikacja lub wtyczka do komunikacji w czasie rzeczywistym mogą zagrozić bezpieczeństwu na kilka sposobów. Na przykład:
- Niezaszyfrowane multimedia lub dane mogą zostać przechwycone między przeglądarkami lub między przeglądarką a serwerem.
- Aplikacja może nagrywać i rozpowszechniać wideo lub dźwięk bez wiedzy użytkownika.
- Wraz z pozornie nieszkodliwą wtyczką lub aplikacją może być instalowane złośliwe oprogramowanie lub wirusy.
WebRTC ma kilka funkcji, które pozwalają uniknąć tych problemów:
- Implementacje WebRTC korzystają z bezpiecznych protokołów, takich jak DTLS i SRTP.
- Szyfrowanie jest obowiązkowe we wszystkich komponentach WebRTC, w tym mechanizmach sygnałów.
- WebRTC nie jest wtyczką. Jego komponenty działają w piaskownicy przeglądarki, a nie w osobnym procesie. Komponenty nie wymagają osobnej instalacji i są aktualizowane wraz z aktualizacją przeglądarki.
- Dostęp do kamery i mikrofonu musi być wyraźnie przyznany. Gdy kamera lub mikrofon jest włączony, musi to być wyraźnie widoczne w interfejsie.
W tym artykule nie omówiono wszystkich kwestii bezpieczeństwa w przypadku strumieniowych transmisji multimedialnych. Więcej informacji znajdziesz w artykule Proponowana architektura zabezpieczeń WebRTC zaproponowana w IETF.
Podsumowanie
Interfejsy API i standardy WebRTC mogą zdemokratyzować i zdecentralizować narzędzia do tworzenia treści i komunikacji, w tym do telefonów, gier, produkcji filmów, tworzenia muzyki i zbierania wiadomości.
Technologia nie jest bardziej uciążliwa niż to.
Jak stwierdził bloger Phil Edholm wyjaśnienie, że WebRTC i HTML5 mogłyby potencjalnie umożliwić takie samo przekształcenie w komunikacji w czasie rzeczywistym jak w przypadku informacji w oryginalnej przeglądarce”.
Narzędzia dla programistów
- Statystyki WebRTC dotyczące trwającej sesji znajdziesz tutaj:
- about://webrtc-internals w Chrome
- opera://webrtc-internals w przeglądarce Opera
- about:webrtc w przeglądarce Firefox
- Notatki dotyczące współpracy w różnych przeglądarkach
- adapter.js to podkładka JavaScript dla WebRTC obsługiwana przez Google przy pomocy społeczności WebRTC, która abstrakcyjne przedrostki dostawców, różnice w przeglądarkach i zmiany specyfikacji.
- Aby dowiedzieć się więcej o procesach sygnalizowania WebRTC, sprawdź dane wyjściowe logu appr.tc w konsoli.
- Jeśli to za dużo, możesz korzystać z platformy WebRTC lub nawet pełnej usługi WebRTC.
- Zachęcamy do zgłaszania błędów i próśb o dodanie funkcji:
Więcej informacji
- Sesja WebRTC Justina Ubertiego na Google I/O 2012
- Alan B. Johnston, Daniel C. Burnett utrzymuje książkę WebRTC, która jest obecnie dostępna w trzecim wydaniu w formacie drukowanym i e-bookowym na stronie webrtcbook.com.
- webrtc.org jest miejscem, w którym znajdują się wszystkie funkcje WebRTC, w tym wersje demonstracyjne, dokumentacja i dyskusje.
- dyskusje-webrtc to grupa dyskusyjna Google do dyskusji na temat WebRTC.
- @webrtc
- Dokumentacja Talk Google Developers zawiera więcej informacji o przemierzaniu NAT, STUN, serwerach przekazujących i gromadzeniu kandydatów.
- WebRTC w GitHubie
- Stack Overflow to dobre miejsce do poszukiwania odpowiedzi na pytania dotyczące WebRTC.
Standardy i protokoły
- Wersja robocza edytora WebRTC W3C
- Wersja robocza W3C: Media Capture i strumienie (znane również jako
getUserMedia
) - Statut grupy roboczej IETF
- Wersja robocza protokołu kanału danych IETF WebRTC
- Wersja robocza IETF JSEP
- Proponowany standard IETF dla ICE
- IETF RTCWEB Grupy Roboczej Internet: wersja robocza przypadków i wymagań dotyczących komunikacji w czasie rzeczywistym w internecie
Podsumowanie obsługi WebRTC
Interfejsy API: MediaStream
i getUserMedia
- Chrome na komputery w wersji 18.0.1008 lub nowszej, Chrome na Androida 29 lub nowszego,
- Opera w wersji 18 lub nowszej; Opera na Androida w wersji 20 lub nowszej
- Opera 12, Opera Mobile 12 (na podstawie silnika Presto)
- Firefox w wersji 17 lub nowszej,
- Microsoft Edge w wersji 16 lub nowszej.
- Safari w wersji 11.2 lub nowszej w systemie iOS oraz w wersji 11.1 lub nowszej w systemie MacOS.
- UC 11.8 lub nowszy na Androidzie
- Samsung Internet 4 lub nowszy,
RTCPeerConnection
interfejs API
- Chrome na komputery w wersji 20 lub nowszej, Chrome na Androida 29 lub nowszego (bez flagi)
- Opera w wersji 18 i nowszych (domyślnie włączona); Opera na Androida w wersji 20 lub nowszej (domyślnie włączona)
- Firefox w wersji 22 i nowszych (domyślnie włączona)
- Microsoft Edge w wersji 16 lub nowszej.
- Safari w wersji 11.2 lub nowszej w systemie iOS oraz w wersji 11.1 lub nowszej w systemie MacOS.
- Samsung Internet 4 lub nowszy,
RTCDataChannel
interfejs API
- eksperymentalna wersja w przeglądarce Chrome 25, ale bardziej stabilna (i współdziałająca z przeglądarką Firefox) w przeglądarce Chrome 26 i nowszych; Chrome na Androida 29 lub nowszego,
- wersja stabilna (oraz obsługa przeglądarki Firefox) w przeglądarce Opera 18 i nowszych; Opera na Androida w wersji 20 lub nowszej
- Firefox w wersji 22 i nowszych (domyślnie włączona)
Szczegółowe informacje o obsłudze interfejsów API na wielu platformach, takich jak getUserMedia
i RTCPeerConnection
, znajdziesz na stronach caniuse.com i stan platformy Chrome.
Natywne interfejsy API dla języka RTCPeerConnection
są też dostępne w dokumentacji na stronie webrtc.org.