Saludo a todos los lectores de Habr. Este año tuve la oportunidad de escribir un módulo de comunicación por video para un portal de capacitación para llamar por medio de comunicación por video directamente en el sitio web del maestro y del alumno. No fue necesario resolver una tarea tan temprana. Después de una breve búsqueda, descubrí que hay 2 formas: Flash y
WebRTC . WebRTC en su forma pura resultó ser complicado, y en general es natural, ya que la tarea de la comunicación por video no es simple. Pero luego me encontré con
PeerJS , que es un contenedor para WebRTC. En este artículo te diré cómo organizar rápidamente el marcador de tu navegador.
Para repetir el ejemplo, se requerirá acceso a su página de prueba a través del protocolo https (ya que la página solicitará acceso a la cámara y al micrófono, y sin un protocolo seguro, el navegador simplemente dará un error)
El diseño inicial se verá así:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Peer</title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <p><h3> ID: </h3><span id=myid ></span></p> <input id=otherPeerId type=text placeholder="otherPeerId" > <button onclick="callToNode(document.getElementById('otherPeerId').value)"></button> <br> <video id=myVideo muted="muted" width="400px" height="auto" ></video> <div id=callinfo ></div> <video id=remVideo width="400px" height="auto" ></video> </body>
En la sección principal, conectamos PeerJS de forma remota. También es posible descargar el script y conectarlo localmente.
input id = otherPeerId: diseñado para ingresar la fiesta de la que llamaremos (puede tomarlo como un índice o como un número de teléfono).
Dos etiquetas de video están diseñadas para mostrar su propio video y para el video del interlocutor, respectivamente.
Ahora un poco sobre la tecnología WebRTC y cómo se realiza la llamada. WebRTC realiza una llamada de cliente a cliente directamente, sin la participación del servidor, por lo que en el primer paso 2 los navegadores deben encontrarse entre sí. Para hacer esto, un WebRTC clásico requiere un servidor de señal, es decir, un servidor que le dice a un navegador los parámetros de otro navegador, y en WebRTC debe organizar dicho servidor usted mismo. Sin embargo, los desarrolladores de PeerJS proporcionan su propio servidor de señales. Todo lo que necesita hacer es pasar el peerID al interlocutor potencial, es decir, el índice único recibido en el sistema PeerJS. En un borrador de trabajo, lo organicé así:
- Después de cargar la página, se crea un objeto Peer
- Su peerID está escrito en la base de datos mysql
- Cuando se presiona el botón Llamar, el ID del interlocutor se extrae de la base de datos y se usa para establecer una conexión
En el caso de prueba actual, ingresaremos el ID de par del interlocutor en el campo de texto otherPeerId
Entonces, comencemos a escribir código.1. Crear el objeto par principal
var peer = new Peer();
2. En la apertura de la fiesta, recibiremos el codiciado ID de igual, que debe ser transferido al socio para que pueda contactarnos
peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; });
3. Para recibir una llamada, colgamos el controlador para el evento de llamada
var peercall; peer.on('call', function(call) {
Con una llamada entrante, obtenemos un objeto de
llamada , que guardamos en la variable global
peercall . También en el bloque de información se mostrará una notificación sobre una llamada entrante y se mostrarán 2 botones: Aceptar y rechazar
4. Escribimos una función para el botón
Aceptar function callanswer() { navigator.mediaDevices.getUserMedia ({ audio: true, video: true }).then(function(mediaStream) { var video = document.getElementById('myVideo'); peercall.answer(mediaStream);
navigator.mediaDevices.getUserMedia: solicita acceso a la cámara y al micrófono. En los datos del objeto que se pasa a este método
{audio: true, video: true}, puede solicitar acceso solo a la cámara o solo al micrófono. Comentarios adicionales agregados directamente al código.
setTimeout se agregó empíricamente: el video del socio no comenzó a reproducirse, pero funcionó con un tiempo de espera.
5. La función de marcar con el botón
Llamar function callToNode(peerId) {
Como en el párrafo anterior, solicitamos su transmisión de medios. Después de llamar a la función de llamada del objeto par, que nos devolverá el objeto de llamada, guárdelo en perercall. Procesamos el evento de transmisión para averiguar qué respondieron y colocar la transmisión entrante en el objeto de video correspondiente
Eso es todo, pero ...
Si ambas personas que llaman están detrás de la llamada NATth no se realizará. (¿Por qué? Lea aquí
habr.com/en/company/yandex/blog/419951 )
Para superar este obstáculo, debe especificar un servidor TURN al crear un objeto par (La cuestión de dónde conseguirlo no fue la más fácil. Tuvimos que plantear el nuestro: VPS en Ubuntu 16.04. Instalación con el comando
apt install coturn
)
Entonces la creación de la fiesta se verá así:
var callOptions={'iceServers': [ {url: 'stun:95.xxx.xx.x9:3479', username: "user", credential: "xxxxxxxxxx"}, { url: "turn:95.xxx.xx.x9:3478", username: "user", credential: "xxxxxxxx"}] }; peer= new Peer({config: callOptions});
Finalmente, el código completo:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Peer</title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <p><h3> ID: </h3><span id=myid ></span></p> <input id=otherPeerId type=text placeholder="otherPeerId" > <button onclick="callToNode(document.getElementById('otherPeerId').value)"></button> <br> <video id=myVideo muted="muted" width="400px" height="auto" ></video> <div id=callinfo ></div> <video id=remVideo width="400px" height="auto" ></video> <script> var callOptions={'iceServers': [ {url: 'stun:95.xxx.xx.x9:3479', username: "user", credential: "xxxxxxxxxx"}, { url: "turn:95.xxx.xx.x9:3478", username: "user", credential: "xxxxxxxx"}] }; peer= new Peer({config: callOptions}); peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; }); var peercall; peer.on('call', function(call) { </script> </body>
Esta solución se probó con éxito en Windows 7 y Ubuntu 18.04 en Chrome, Opera, Firefox. Chrome también funciona en Android y MacOS, pero no funciona en iPhone y iPad.