WebRTC Faire une application avec blackjack et appels vidéo

Cher lecteur, avant de commencer à écrire le code, examinons le concept des appels vidéo.

Imaginez la situation: nous avons une plate-forme de chat et nous devons y attacher des appels vidéo, c'est-à-dire qu'un certain Vasya est assis en ligne et qu'il veut appeler Petya, pour implémenter une telle fonctionnalité, nous avons besoin de la technologie WebSocket .

Eh bien, élevons notre serveur WebSocket, node.js nous aidera avec cela;
Créez le fichier sockets.js et écrivez-y le code de socket du serveur:

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);
//   
})

Créez un fichier index.html et écrivez-y le code pour ouvrir une connexion 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> <!--  -->

Maintenant, créez et connectez le fichier script.js à notre fichier 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)
       //  ,   
      };

Revenons donc à nos Vasya et Petya


image

Il s'agit de l'étape initiale à laquelle Vasya et Petya échangent simplement JSON pour savoir si nous recevrons un appel ou non. C'est-à-dire que lorsque nous visitons notre page, nous devons ouvrir une connexion WebSocket pour communiquer avec notre serveur de socket.

  1. Nous envoyons d'abord un casque au socket du serveur JSON afin que nous voulions appeler Petya depuis le compte de Vasya

    connection.send(JSON.stringify({
    //  
    }))
    
  2. Nous devons accepter ce JSON sur le serveur de socket, après avoir reçu la demande, nous attachons l'événement de message à notre serveur :

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

Après avoir parlé et décidé que les deux utilisateurs sont prêts pour une conversation, nous devons comprendre comment fonctionne la communication vidéo dans un navigateur, un module pour cela est construit en js - RTCPeerConnection


image

Nous devons ouvrir RTCPeerConnection, avec lequel nous pouvons générer une offre et l'envoyer à l'utilisateur dont nous avons besoin, à nouveau via notre serveur de socket, qui, à sa réception, générera une réponse et la renverra, après quoi nous commencerons à échanger des paquets de glace contenant des informations sur l'environnement cet ordinateur, qui est nécessaire pour la mise en place réussie des communications vidéo.

Nous générons et envoyons une offre


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();
            }
 

Nous traitons l'offre et générons la réponse


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")});
          }
        }

Nous acceptons la réponse et créons un flux vidéo


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

Et la dernière chose que nous devons faire est de traiter les paquets de glace


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

All Articles