Aplikacja do wideorozmów

0

Serdecznie witam i pozdrawiam wszystkich. Otóż od dzisiaj rana, zaczęło chodzić mi po głowie, aby na swoim blogu, zastosować pewnego rodzaju funkcjonalność znaną z Twitter Space, czyli swobodnego dostępu do "nasłuchu" (tego co mówią "aktywni" użytkownicy) oraz możliwość samemu wzięcia udziału w otwartej dyskusji po naciśnięciu i przytrzymaniu prawego klawisza myszy.

To jest wizja koncepcyjna. Na pewno wszystko jest możliwe do zastosowania, tylko zupełnie nie wiem jak się do tego zabrać. Jakbyście Szanowni Państwo mieli jakieś pomysły lub uwagi na ten temat, to bardzo proszę o podpowiedzi. Do tej pory zgromadziłem takie informacje:

navigator.mediaDevices.getUserMedia( MediaStreamConstraints )
   .then(MediaStream => {
      // Code that uses the MediaStream
   })
   .catch( error => {
      // Code to handle the error
   });

Co to jest? Czy mam to wrzucić w <script> prosto do kodu HTML? Jestem laikiem, dlatego proszę mi, możliwie w 2 zdaniach, wyjaśnić nawet najprostsze kwestie. Serdecznie dziękuję za pomoc i pozdrawiam.

James

0

Kopiąc dalej w tym temacie doszedłem do tego co zaraz wkleje. Nie ukrywam, że korzystam z pomocy "chat.openai.com", ale proszę was o komentarz. No wiec moj plik audio.html jest taki...

<html>
<head>
<script>
navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => {
    // Step 2 goes here
    const videoElement = document.querySelector('video');
		videoElement.srcObject = stream;
		videoElement.play();
  })
  .catch(error => {
    console.error(error);
  });
</script>
<body>
	
<video autoplay></video>
	
</body>
</head>
</html>

...i nie działa. Dzięki za pomoc!

1

Czy masz swój backend? Taki voice chat będzie potrzebowal backendu i komunikacji na żywo za pomocą WebSocketow. Może sa jakies SaaS które to ogarniają i trzeba by poszperać w internecie, jednak kod aplikacji frontendowej tego sam z siebie nie ogarnie 😛

A co do przechwytywania obrazu i dźwięku za pomocą JavaScriptu to odsyłam do dokumentacji tu: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

0

Oto co powiedział mi chat.openai.com...

Oto ogólne kroki, które możesz podjąć, aby zbudować backend dla aplikacji czatu wideo za pomocą PHP:

Skonfiguruj środowisko serwera: Aby zbudować swój backend, będziesz potrzebować serwera z zainstalowanym PHP. Możesz użyć lokalnego serwera, takiego jak XAMPP, lub skonfigurować serwer prywatny wirtualny (VPS), aby hostować swój backend.

Wybierz bibliotekę czatu wideo: Istnieje wiele dostępnych bibliotek, które możesz wykorzystać do zaimplementowania funkcjonalności czatu wideo w swojej aplikacji. Niektóre popularne opcje to WebRTC, Twilio i Jitsi. Każda biblioteka ma własny zestaw funkcji i możliwości, więc powinieneś wybrać taką, która spełni potrzeby twojej aplikacji.

Skonfiguruj swoją bazę danych: Będziesz potrzebować bazy danych, aby przechowywać informacje o użytkownikach i sesjach czatu wideo. Możesz użyć systemu zarządzania bazami danych (DBMS), takiego jak MySQL lub MariaDB, aby utworzyć i zarządzać bazą danych.

Zaprojektuj swoje API: Twój backend będzie musiał posiadać interfejs programowania aplikacji (API), który będzie używany przez frontend aplikacji do komunikacji z serwerem. Możesz użyć PHP, aby utworzyć punkty końcowe API, które będzie mógł używać frontend do inicjowania i zarządzania sesjami czatu wideo.

Przetestuj i wdróż backend: Po zaimplementowaniu wszystkich niezbędnych funkcji powinieneś przetestować backend, aby upewnić się, że działa zgodnie z oczekiwaniami. Następnie możesz wdrożyć backend w środowisku serwera, gdzie będzie dostępny dla twojego frontendu.

Mam nadzieję, że to pomoże! Daj mi znać, jeśli masz inne pytania.

2

Ok. Jaki język polecacie do obsługi BackEndu? PHP da radę? Jakich funkcji muszę użyć? No i bardzo proszę mi wyjaśnić do to są WebSockety. Dziękuję serdecznie. —

Jak umiesz JSa to zamiast uczyć się kolejnego języka IMHO lepiej wziąć node.js. Nawet zapytanie https://www.google.com/search?q=node.js+websocket+server zwraca jakieś sensowne wyniki. np:

0

Ok... więc mamy coś takiego. Co nie działa. Nawet nie wiem co to jest. Czy może ktoś mi omówić poszczególne fragmenty tego kodu, aby wszystko stało się dla mnie ociupinkę bardziej przejrzyste. Serdecznie dziękuje!

<html>
<head>
	
<!-- Dołącz bibliotekę WebRTC do swojego pliku HTML -->	
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

<script>
	
	// Utwórz instancję RTCPeerConnection i zapewnij jej niezbędne opcje konfiguracyjne:
	const peerConnection = new RTCPeerConnection({
  iceServers: [{
    urls: 'stun:stun.l.google.com:19302'
  	}]
	});
	
	// Dodaj detektory zdarzeń dla kluczowych zdarzeń dostarczonych przez RTCPeerConnection:
	
	peerConnection.onicecandidate = (event) => {
  // obsługiwać zdarzenie icecandidate
	};
	
	peerConnection.oniceconnectionstatechange = (event) => {
  // iceconnectionstatechange
	};

	peerConnection.onicegatheringstatechange = (event) => {
  // obsłużyć zdarzenie icegatheringstatechange event
	};

	peerConnection.onnegotiationneeded = (event) => {
  // obsłużyć zdarzenie negotiationneeded event
	};
	
	// Użyj metody createOffer(), aby utworzyć ofertę opisującą lokalny koniec połączenia:
	
	peerConnection.createOffer().then((offer) => {
  // ustaw opis lokalny za pomocą oferty
  return peerConnection.setLocalDescription(offer);
	}).then(() => {
		
  // wyślij ofertę do zdalnego peera
  sendMessage(peerConnection.localDescription);
	}).catch((error) => {
  console.error(error);
	});
	
	// Use the createAnswer() method to create an answer based on an offer received from the remote peer:
	
	peerConnection.setRemoteDescription(offer).then(() => {
  return peerConnection.createAnswer();
	}).then((answer) => {
		
  // Użyj metody createAnswer(), aby utworzyć odpowiedź na podstawie oferty otrzymanej od zdalnego peera:
  return peerConnection.setLocalDescription(answer);
	}).then(() => {
  // send the answer to the remote peer
  sendMessage(peerConnection.localDescription);
	}).catch((error) => {
  console.error(error);
	});
	
</script>
<body>
	
<video id="localVideo" autoplay playsinline controls="false"/>
	
</body>
</head>
</html>

Kurcze. Jestem noga w JS! W sumie to proszę bardzo o wyjaśnienie mi filozofii. Mówimy tutaj o połączeniu peer-to-peer tak? Czyli z pominięciem serwera? Tak? Bo ja nie wiem. Co to jest to...

 urls: 'stun:stun.l.google.com:19302'

?

0

Czas poruszyć temat tego czym są serwery TURN. Może najpierw trochę informacji bezpośrednio z https://webrtc.org/getting-started/turn-server

Serwer TURN

Większość aplikacji WebRTC działa na serwerze, aby przekazywać ruch między połączeniami równorzędnymi, ponieważ gniazdo bezpośrednie nie jest często przesyłane między klientami (chyba że znajdują się w tej samej sieci lokalnej). Typowym rozwiązaniem tego problemu jest użycie serwera turn. Ten skrót to skrót od Traversal Use Relays wokół NAT, czyli protokół przekazujący ruch w sieci.

Obecnie dostępnych jest online kilka opcji serwerów turn, zarówno jako aplikacje wewnętrzne (np. projekt COPT typu open source), jak i usługi w chmurze.

Gdy serwer turn jest dostępny online, potrzebujesz tylko RTCConfiguration do prawidłowego użycia jego aplikacji klienckiej. Poniższy fragment kodu ilustruje przykładową konfigurację serwera RTCPeerConnection, w przypadku którego serwer turystyczny ma nazwę hosta my-turn-server.mycompany.com i działa na porcie 19403. Obiekt konfiguracji obsługuje też właściwości username i credentials umożliwiające zabezpieczenie dostępu do serwera. Są one wymagane podczas nawiązywania połączenia z serwerem turn.

const iceConfiguration = {
    iceServers: [
        {
            urls: 'turn:my-turn-server.mycompany.com:19403',
            username: 'optional-username',
            credentials: 'auth-token'
        }
    ]
}

const peerConnection = new RTCPeerConnection(iceConfiguration);
0

Serwery TURN (Traversal Using Relays around NAT) są używane do umożliwienia komunikacji między urządzeniami znajdującymi się za zaporami NAT (Network Address Translation) i nieosiągalnymi bezpośrednio z Internetu. Serwery TURN działają jako przekaźnik, przekazując dane audio i wideo między urządzeniami.

Oto kilka serwerów TURN zlokalizowanych w Polsce lub Europie, które możesz użyć w swojej aplikacji:

webrtc.pl: Zapewnia serwery TURN z globalnym zasięgiem i niskim opóźnieniem.

turn.eu: Oferuje serwery TURN z globalnym zasięgiem i obsługą IPv6.

turnserver.org: Zapewnia serwery TURN z globalnym zasięgiem i obsługą wielu protokołów.

restund.net: Oferuje darmowy serwer TURN, który może być używany do testów i rozwoju.

Pamiętaj, że serwery TURN mogą być intensywne pod względem zasobów i mogą wiązać się z dodatkowymi kosztami, w zależności od dostawcy i wykorzystania. Powinieneś dokładnie rozważyć swoje potrzeby i wybrać serwer TURN, który spełni wymagania twojej aplikacji.

0

Różnica pomiędzy serwerami TURN (Traversal Using Relays around NAT) i serwerami ICECAST to nie to samo.

Serwery TURN służą do umożliwienia komunikacji w czasie rzeczywistym przez Internet, gdy istnieją NAT (Network Address Translation) lub firewalle, które uniemożliwiają bezpośrednie połączenia pomiędzy dwoma urządzeniami. Serwery TURN pełnią rolę pośrednika pomiędzy dwoma urządzeniami, umożliwiając im komunikację za pośrednictwem serwera TURN.

Icecast to serwer transmisji mediów o otwartym kodzie źródłowym, który umożliwia nadawanie treści audio i wideo przez Internet. Jest on często używany do transmisji muzyki, podcastów i innych rodzajów treści audio. Serwery Icecast otrzymują strumienie audio od klientów źródłowych i dystrybuują je do słuchaczy za pośrednictwem różnych protokołów, w tym HTTP, HTTPS i ICY (proprietary protokół używany przez niektóre odtwarzacze multimedialne).

Więc chociaż serwery TURN i serwery Icecast oba dotyczą przesyłania audio i wideo przez Internet, służą one różnym celom i wykorzystują różne technologie. Serwery TURN służą do umożliwienia komunikacji w czasie rzeczywistym pomiędzy urządzeniami, podczas gdy serwery Icecast służą do nadawania strumieni audio i wideo słuchaczom.

4

No dobra, ale po co wklejasz definicje z internetu? :) Każdy sobie je znajdzie. WebRtc to peer to peer, czyli jeden user rozmawia z jednym. To można zrobić łatwo, ale wersja dla wielu użytkowników wymaga duuużo większej pracy. Są gotowce, ale pomyśl, czy faktycznie chcesz budować infrastrukturę dla bloga, zamiast ogarnąć konferencję na jakimś gotowym komunikatorze :D

1

Jak najbardziej Ci kibicuję, ale wydaje mi się, że musisz poznać więcej języka i nabyć umiejętności odpowiedniego filtrowania informacji, żeby od razu wiedzieć, czy to co czytasz jest Ci potrzebne.
Jak sam napisałeś jesteś początkującym w JS, a Twoje zadanie wymaga większego doświadczenia. Oczywiście nie chodzi mi o to, że jesteś początkującym więc tego nie zrobisz, ale uważam, że jest małe prawdopodobieństwo, że zrobisz to dobrze. Sama funkcja mówienia po naciśnięciu przycisku w stylu "walkie talkie" prawdopodobnie będzie wymagała dużego nakładu pracy, bo wątpię, że jakaś usługa to oferuje
Nie ma co rzucać się na głęboką wodę - twórz nowe projekty, w każdym z nich implementuj nowe funkcjonalności, co pozwoli Ci na nabycie wiedzy i doświadczenia, a dopiero później zajmij się skomplikowanymi zadaniami. Ten komentarz nie ma na celu Cię zniechęcić, ale skłonić do refleksji, że warto zaoszczędzić czas i nerwy i podejść do tego zadania będąc bardziej doświadczonym.

0

Witam dzisiaj! Oto co udało mi się wykopać odnośnie alternatyw dla WebRTC:

WebSockets: WebSockets to protokół służący do ustanawiania dwukierunkowego, pełnego dupleksu kanału komunikacyjnego za pośrednictwem pojedynczego połączenia TCP. Można go wykorzystać do budowy systemów komunikacji w czasie rzeczywistym, takich jak aplikacje do czatowania i gry online.

Server-Sent Events (SSE): SSE to technologia, która umożliwia serwerowi wysyłanie danych do strony internetowej w czasie rzeczywistym. Działa poprzez ustanowienie długotrwałego połączenia między serwerem a klientem, a serwer może użyć tego połączenia do wypychania danych do klienta, gdy tylko staną się dostępne.

Długie sondowanie: Długie sondowanie to technika, która pozwala klientowi żądać danych z serwera w sposób, który pozwala serwerowi „wstrzymać” żądanie, dopóki nie będzie miał nowych danych do wysłania z powrotem do klienta. Można to wykorzystać do osiągnięcia komunikacji w czasie rzeczywistym między klientem a serwerem, ale wymaga to większego narzutu i może nie być tak wydajne, jak inne alternatywy.

Websockets over TLS (WSS): WSS to bezpieczna wersja WebSockets, która wykorzystuje TLS (Transport Layer Security) do szyfrowania danych przesyłanych między klientem a serwerem. Można to wykorzystać do budowy bezpiecznych systemów komunikacji w czasie rzeczywistym, takich jak aplikacje do wideokonferencji.

Trochę śmieszą mnie takie "oklepane lingwistycznie stwierdzenia" jak "bezpieczne systemy komunikacji". LoL. Może porozmawiajmy o tych niebezpiecznych systemach komunikacji. LoL To jest po prostu taki sobie technologiczny truizm.

Jeśli chodzi natomiast o to "menu" które przedstawił mi chat.openai.com - to oczywiście od razu zabieram się za WebSockets! I od razu pytania:

  1. Czy mogę ustanowić dwukierunkowe głosowe połączenie poprzez WebSocket.
  2. Jak mogę ustanowić 10 kierunkowe głosowe połączenie przez WebSocket?
  3. Jeśli mogę to czy muszę mieć serwer który centralizuje wszystko? - Czy też jak to i jakim cudem, mogę zrobić inaczej?

To może tak na początek. Jakby ktoś miał jakiekolwiek uwagi wynikające z jego doświadczenia, to bardzo proszę śmiało. :-D Dziękuję serdecznie!

0

To może na potrzeby segregacji faktów odnośnie omawianego właśnie zagadnienia:

WebSockets to protokół umożliwiający nawiązanie dwukierunkowej, pełnej duplexowej komunikacji pomiędzy klientem (np. przeglądarką internetową) a serwerem. Służy do budowy aplikacji zrealizowanych w czasie rzeczywistym, takich jak czat, gry online i inne interaktywne systemy.

WebSockets wykorzystuje mechanizm handshake do nawiązania połączenia pomiędzy klientem a serwerem, a po nawiązaniu połączenia dane mogą być przesyłane w obie strony (tzn. od klienta do serwera i od serwera do klienta) bez konieczności wysyłania dodatkowych żądań HTTP. To sprawia, że WebSockets jest znacznie bardziej wydajny niż inne techniki, takie jak long polling, które wymagają od klienta wysyłania powtarzających się żądań HTTP w celu otrzymania danych z serwera.

WebSockets jest obsługiwany przez większość nowoczesnych przeglądarek internetowych i może być używany z dowolnym językiem programowania obsługującym protokół TCP. Często jest używany w połączeniu z innymi technologiami, takimi jak WebRTC, do budowy bardziej złożonych systemów komunikacji w czasie rzeczywistym.

Czyli wygląda na to, że bez wykupionego serwera WebRTC się nie obejdzie? Tak?

0

Interfejs API WebSockets jest standardową częścią nowoczesnych przeglądarek internetowych i jest opisany w oficjalnej specyfikacji HTML5. Oto link do dokumentacji WebSockets na stronie Mozilla Developer Network (MDN):

https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API

Ta strona zawiera szczegółowe informacje o interfejsie API WebSockets, w tym informacje o tym, jak go używać do tworzenia połączeń WebSockets i wysyłania i odbierania danych za pośrednictwem tych połączeń. Zawiera również przykłady użycia WebSockets w różnych językach programowania, takich jak JavaScript i Python.

Oprócz dokumentacji interfejsu API WebSockets może być również pomocne zapoznanie się ze specyfikacją protokołu WebSockets, która definiuje podstawowy protokół używany przez WebSockets:

https://tools.ietf.org/html/rfc6455

Ta specyfikacja zawiera szczegółowy opis protokołu WebSockets, w tym mechanizm handshake używany do nawiązywania połączeń WebSockets oraz format ramek używany do transmisji danych za pośrednictwem tych połączeń.

0

Hand-shake od klienta - do serwera:

        GET /chat HTTP/1.1
        Host: server.example.com
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
        Origin: http://example.com
        Sec-WebSocket-Protocol: chat, superchat
        Sec-WebSocket-Version: 13

Hand-shake od serwera do klienta:

        HTTP/1.1 101 Switching Protocols
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
        Sec-WebSocket-Protocol: chat

Może na razie bez omawiania poszczególnych elementów.

0

Ok... https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API - mamy tutaj menu z którego każdy może wybrać coś dla siebie. Nie wiem za co się zabrać, więc wybieram trochę na ślepo dwa dania główne. I tak będę sobie nad nimi siedział, dopóki czegoś nie uda mi się zbudować. Pomożecie? - Pomożemy! :-D

PHP WebSocket Server: Serwer napisany w PHP do obsługi połączeń przez websockets wss:// lub ws://i normalne gniazda przez ssl:// ,tcp://

i

cowboy: Cowboy is a small, fast and modern HTTP server for Erlang/OTP with WebSocket support.

Ok! So let's start with PHP WebSocket! Wish me good luck!

0

Ok Proszę o pomoc w objaśnieniu co to jest... :-) Lecimy z tym PHP WebSocket

To get an idea how things work and relate to each other
on the server side,have a look into runSocketServer.php.

Oto cała zawartość tego pliku. Jest się nad czym pozastanawiać.

<?php

class runSocketServer {

    function __construct() {
        /*
         * ***********************************************
         * the runtime
         * ***********************************************
         */
        require __DIR__ . '/errorHandler.php';
        require __DIR__ . '/logToFile.php';
        /*
         * ***********************************************
         * inlcude the core server
         * ***********************************************
         */
        require __DIR__ . "/getOptions.php";
        require __DIR__ . "/webSocketServer.php";
        /*
         * **********************************************
         *  your backend applications
         * **********************************************
         */
        require __DIR__ . '/resource.php';
        require __DIR__ . '/resourceDefault.php';
        require __DIR__ . '/resourceWeb.php';
        require __DIR__ . '/resourcePHP.php';
    }

    function run() {
        global $logger;
        /*
         * ***********************************************
         * check for parameters 
         * ***********************************************
         */

        $o = new getOptions();
        $option = $o->default;
        /*
         * ***********************************************
         * create a logger
         * set directory for logfiles and 
         * log to console
         * ***********************************************
         */

        $logger = new logToFile($option['logfile'], 'phpwebsocketserver','',$option['console']);
        
        /*
         * *****************************************
         * create server 
         * *****************************************
         */
        $server = new websocketServer($option['adress'], $logger, $option['certFile'], $option['pkFile']);
        /*
         * ***********************************************
         * set some server variables
         * ***********************************************
         */
        $server->maxPerIP = 0;   // 0=unlimited 
        $server->maxClients = 0; // 0=unlimited 
        $server->pingInterval=0; // unit is seconds; 0=no pings to clients
        /*
         * ***********************************************
         * instantiate backend 'applications'
         * ***********************************************
         */
        $resDefault = new resourceDefault();
        $resWeb = new resourceWeb();
        $resPHP = new resourcePHP();
        /*
         * ***********************************************
         * register backend 'applications' with server
         * ***********************************************
         */
        $server->registerResource('/', $resDefault);
        $server->registerResource('/web', $resWeb);
        $server->registerResource('/php', $resPHP);
        /*
         * ***********************************************
         * now start it to have the server handle
         * requests from clients
         * ***********************************************
         */

        $server->Start();
    }

}

/*
 * ***********************************************
 * start 
 * ***********************************************
 */
(new runSocketServer())->run();
0

Dobra... zostawmy PHP WebSocket na chwilę, zanim wrócimy do niego z kredą i tablicą... Skoncentrujmy się na tym co tutaj... Procedura WebRTC...

Może zacznijmy od podstaw: MediaDevices.getUserMedia()

navigator.mediaDevices.getUserMedia({ audio: true, video: false })
  .then(function(stream) {
    // Do something with the stream, e.g. create an audio element and play the stream
  })
  .catch(function(error) {
    // Handle error
  });

Czy możecie podać mi jakiś przykład co zrobić w dziale "do something with the stream"? Dziękuję. Pozdrawiam.

I może bardziej kompleksowe rozwiązanie, z ustawieniami parametrów audio:

navigator.mediaDevices.getUserMedia({
  audio: {
    deviceId: 'your-microphone-device-id',
    echoCancellation: true,
    sampleRate: 44100
  },
  video: false
})
  .then(function(stream) {
    // Do something with the stream
  })
  .catch(function(error) {
    // Handle error
  });

Pozwolę sobie przytoczyć co powiedział mi chat.openai.com Przytaczam to bo będę miał kilka pytań odnośnie poszczególnych etapów wyszczególnionych poniżej. Pojawia się jeszcze zagadnienie, jak skleić getUserMedia z... "procedurą" WebRTC. Hmm... no w takim razie zawieśmy się na chwilę nad tym co mamy. Oto co wypluł mi OpenAI :-)

Dołącz bibliotekę WebRTC do swojej aplikacji internetowej. Możesz to zrobić, dodając następujący tag skryptu do pliku HTML:

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

Utwórz nowy obiekt RTCPeerConnection, aby nawiązać połączenie typu peer-to-peer. Obiekt RTCPeerConnection jest używany do zarządzania połączeniem i obsługi strumieni audio, wideo i danych.

const pc = new RTCPeerConnection();

Dodaj nasłuchiwacze zdarzeń do obiektu RTCPeerConnection, aby obsłużyć różne etapy połączenia. Najważniejsze zdarzenia to onicecandidate, które jest wywoływane, gdy lokalny peer generuje kandydata ICE, oraz ontrack, które jest wywoływane, gdy otrzymano nowy ślad od zdalnego peer-a.

pc.onicecandidate = function(event) {
  // Obsłuż zdarzenie kandydata ICE
};

pc.ontrack = function(event) {
  // Obsłuż zdarzenie śladu
};

Użyj metody createOffer(), aby utworzyć ofertę, którą można wysłać do zdalnego peer-a. Oferta zawiera informacje o możliwościach i preferencjach mediów lokalnego peer-a.

pc.createOffer()
  .then(function(offer) {
    // Wyślij ofertę do zdalnego peer-a
  })
  .catch(function(error) {
    // Obsłuż błąd
  });

Gdy zdalny peer otrzyma ofertę, może utworzyć odpowiedź za pomocą metody createAnswer(). Odpowiedź zawiera informacje o możliwościach i preferencjach mediów zdalnego peer-a.

pc.createAnswer()
  .then(function(answer) {
    // Wyślij odpowiedź do lokalnego peer-a
  })
  .catch(function(error) {
    // Obsłuż błąd

Hmm... Teraz trzeba pomedytować trochę nad tym!

1 użytkowników online, w tym zalogowanych: 0, gości: 1