WebRTC Hacer una aplicación con blackjack y videollamadas

Estimado lector, antes de comenzar a escribir el código, echemos un vistazo al concepto de videollamadas.

Imagínese la situación: tenemos una plataforma de chat y necesitamos fijarle videollamadas, es decir, cierto Vasya está en línea y quiere llamar a Petya, para implementar tal característica, necesitamos la tecnología WebSocket .

Bueno, aumentemos nuestro servidor WebSocket, node.js nos ayudará con esto;
Cree el archivo sockets.js y escriba el código del socket del servidor allí:

const WebSocketServer = require('websocket').server;
const http = require('http');

const server = http.createServer(function(request, response) {
 //    ,    ,  http
});
server.listen(1337, function() {});

//   
const wsServer = new WebSocketServer({
  httpServer: server
});

wsServer.on('request', function(request) {
  let connection = request.accept(null, request.origin);
//   
})

Cree un archivo index.html y escriba el código allí para abrir una conexión de socket:

     <video autoplay muted height='300' width='300' style="position:fixed;bottom:0;left:0;z-index: 9999;" src="" id='my'>
          </video> <!--   --> 

          <video autoplay height='300' width='300' style="position:fixed;bottom:0;left:300px;z-index: 999999;" src="" id='not_my'>
          </video> <!--  -->

Ahora cree y conecte el archivo script.js a nuestro archivo html:

  let connection = new WebSocket('ws://127.0.0.1:1337');//   -
  connection.onopen = function(){
//  ,  -      
 }
connection.onmessage = function(message){
//        


}
connection.onerror = function (error) {
        console.error(error)
       //  ,   
      };

Entonces, volvamos a nuestra Vasya y Petya


imagen

Esta es la etapa inicial en la que Vasya y Petya simplemente intercambian JSON sobre si recibiremos una llamada o no. Es decir, cuando visitamos nuestra página, debemos abrir una conexión WebSocket para comunicarnos con nuestro servidor de socket.

  1. Primero enviamos un casco al socket del servidor JSON para que podamos llamar a Petya desde la cuenta de Vasya

    connection.send(JSON.stringify({
    //  
    }))
    
  2. Debemos aceptar este JSON en el servidor de socket, después de recibir la solicitud, adjuntamos el evento de mensaje a nuestro servidor :

    connection.on('message',function(message){
    //   message    ,     JSON  JS
    let self = JSON.parse(message.utf8Data);
    })
    

Habiendo hablado y decidido que ambos usuarios están listos para una conversación, necesitamos descubrir cómo funciona la comunicación por video en un navegador, un módulo para esto está integrado en js - RTCPeerConnection


imagen

Necesitamos abrir RTCPeerConnection, con el cual podemos generar una oferta y enviarla al usuario que necesitamos, nuevamente a través de nuestro servidor de socket, que, al recibirla, generará una respuesta y la enviará de regreso, luego de lo cual comenzaremos a intercambiar paquetes de hielo que contienen información sobre el medio ambiente. esta computadora, que es necesaria para el establecimiento exitoso de comunicaciones de video.

Generamos y enviamos oferta


var pc = new RTCPeerConnection();
            
            var peerConnectionConfig = {
              iceServers: [
                  {
                      urls: 'stun:stun.l.google.com:19302'
                  }
                ]
            }
            pc.onicecandidate = function (event) {
              console.log('new ice candidate', event.candidate);

              if (event.candidate !== null) {
                connection.send(JSON.stringify({
                 // json  ice 
                }))
              }
          };

            navigator.getUserMedia = navigator.getUserMedia ||
                         navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia;
                      

            navigator.getUserMedia({video: true,audio:true}, function(stream) {
              //      onaddstream  ,
              //    .
            var my_video = document.getElementById('my')
            my_video.srcObject = stream

              pc.onaddstream = e => {
                document.getElementById('not_my').srcObject = e.stream;
                console.log('not stream is added')
              }
              pc.addStream(stream);   
            
              pc.createOffer(function(offer) {
                pc.setLocalDescription(offer, function() {
                  //  offer  
                  }))
                }, e=> console.log(e));
              }, e=> console.log(e));
            },function (){console.warn("Error getting audio stream from getUserMedia")});

            //  
            function endCall() {
              var videos = document.getElementsByTagName("video");
              for (var i = 0; i < videos.length; i++) {
                videos[i].pause();
              }
            
              pc.close();
            }

            function error(err) {
              endCall();
            }
 

Procesamos oferta y generamos respuesta


var pc = new RTCPeerConnection();// connection
var peerConnectionConfig = { // ice server
              iceServers: [
                  {
                      urls: 'stun:stun.l.google.com:19302'
                  }
                ]
            }
            pc.onicecandidate = function (event) {
              console.log('new ice candidate', event.candidate);

              if (event.candidate !== null) {
                // ice 
              }
          };


            navigator.getUserMedia = navigator.getUserMedia ||
                         navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia;

            navigator.getUserMedia({video: true,audio:true}, function(stream) {//          
              var my_video = document.getElementById('my')
              my_video.srcObject = stream
              console.log('stream is added while offering')

              pc.onaddstream = e => {
                console.log('not my stream is added while offering')
                document.getElementById('not_my').srcObject = e.stream;
                
              }
              pc.addStream(stream);
            
              pc.setRemoteDescription(new RTCSessionDescription(data.offer), function() {
                pc.createAnswer(function(answer) {
                  pc.setLocalDescription(answer, function() {
                    // 
                  }, e => console.log(e));
                }, e => console.log(e));
              }, e => console.log(e));
            },function (){console.warn("Error getting audio stream from getUserMedia")});
          }
        }

Aceptamos la respuesta y creamos una transmisión de video


pc.setRemoteDescription(new RTCSessionDescription(data.answer), function() { }, error);

Y lo último que tenemos que hacer es procesar los paquetes de hielo


pc.addIceCandidate(new RTCIceCandidate(ice))// ice -  ,    

All Articles