WebRTC - Démo vidéo

Dans ce chapitre, nous allons créer une application client qui permet à deux utilisateurs sur des appareils distincts de communiquer à l'aide de WebRTC. Notre application aura deux pages. Un pour la connexion et l'autre pour appeler un autre utilisateur.

Les deux pages seront les balises div . La plupart des entrées sont effectuées via de simples gestionnaires d'événements.

Serveur de signalisation

Pour créer une connexion WebRTC, les clients doivent pouvoir transférer des messages sans utiliser de connexion homologue WebRTC. C'est là que nous utiliserons HTML5 WebSockets - une connexion socket bidirectionnelle entre deux points de terminaison - un serveur Web et un navigateur Web. Commençons maintenant à utiliser la bibliothèque WebSocket. Créez le fichier server.js et insérez le code suivant -

//require our websocket library 
var WebSocketServer = require('ws').Server; 

//creating a websocket server at port 9090 
var wss = new WebSocketServer({port: 9090});
  
//when a user connects to our sever 
wss.on('connection', function(connection) { 
   console.log("user connected"); 
	
   //when server gets a message from a connected user 
   connection.on('message', function(message) { 
      console.log("Got message from a user:", message); 
   }); 
	
   connection.send("Hello from server");
});

La première ligne nécessite la bibliothèque WebSocket que nous avons déjà installée. Ensuite, nous créons un serveur socket sur le port 9090. Ensuite, nous écoutons l' événement de connexion . Ce code sera exécuté lorsqu'un utilisateur établit une connexion WebSocket avec le serveur. Nous écoutons ensuite tous les messages envoyés par l'utilisateur. Enfin, nous envoyons une réponse à l'utilisateur connecté en disant «Bonjour du serveur».

Dans notre serveur de signalisation, nous utiliserons un nom d'utilisateur basé sur une chaîne pour chaque connexion afin que nous sachions où envoyer les messages. Modifions un peu notre gestionnaire de connexion -

connection.on('message', function(message) { 
   var data; 
	
   //accepting only JSON messages 
   try { 
      data = JSON.parse(message); 
   } catch (e) { 
      console.log("Invalid JSON"); 
      data = {}; 
   } 
});

De cette façon, nous n'acceptons que les messages JSON. Ensuite, nous devons stocker tous les utilisateurs connectés quelque part. Nous utiliserons pour cela un simple objet Javascript. Changer le haut de notre fichier -

//require our websocket library 
var WebSocketServer = require('ws').Server; 

//creating a websocket server at port 9090 
var wss = new WebSocketServer({port: 9090}); 

//all connected to the server users 
var users = {};

Nous allons ajouter un champ de type pour chaque message provenant du client. Par exemple, si un utilisateur souhaite se connecter, il envoie le message de type de connexion . Définissons-le -

connection.on('message', function(message) { 
   var data; 
	
   //accepting only JSON messages 
   try { 
      data = JSON.parse(message);
   } catch (e) { 
      console.log("Invalid JSON"); 
      data = {}; 
   } 
	
   //switching type of the user message 
   switch (data.type) { 
      //when a user tries to login 
      case "login": 
         console.log("User logged:", data.name); 
			
         //if anyone is logged in with this username then refuse 
         if(users[data.name]) { 
            sendTo(connection, { 
               type: "login", 
               success: false 
            }); 
         } else { 
            //save user connection on the server 
            users[data.name] = connection; 
            connection.name = data.name; 
				
            sendTo(connection, { 
               type: "login", 
               success: true 
            }); 
         } 
			
         break;
			
      default: 
         sendTo(connection, { 
            type: "error", 
            message: "Command no found: " + data.type 
         }); 
			
         break;
   }  
});

Si l'utilisateur envoie un message avec le type de connexion , nous -

  • Vérifiez si quelqu'un s'est déjà connecté avec ce nom d'utilisateur

  • Si tel est le cas, dites à l'utilisateur qu'il ne s'est pas connecté avec succès

  • Si personne n'utilise ce nom d'utilisateur, nous ajoutons le nom d'utilisateur comme clé à l'objet de connexion.

  • Si une commande n'est pas reconnue, nous envoyons une erreur.

Le code suivant est une fonction d'assistance pour l'envoi de messages à une connexion. Ajoutez-le au fichier server.js -

function sendTo(connection, message) { 
   connection.send(JSON.stringify(message)); 
}

Lorsque l'utilisateur se déconnecte, nous devons nettoyer sa connexion. Nous pouvons supprimer l'utilisateur lorsque l' événement de fermeture est déclenché. Ajoutez le code suivant au gestionnaire de connexion -

connection.on("close", function() { 
   if(connection.name) { 
      delete users[connection.name]; 
   } 
});

Après une connexion réussie, l'utilisateur souhaite en appeler un autre. Il doit faire une offre à un autre utilisateur pour y parvenir. Ajouter le gestionnaire d' offres -

case "offer": 
   //for ex. UserA wants to call UserB 
   console.log("Sending offer to: ", data.name);
	
   //if UserB exists then send him offer details 
   var conn = users[data.name]; 
	
   if(conn != null) { 
      //setting that UserA connected with UserB 
      connection.otherName = data.name; 
		
      sendTo(conn, { 
         type: "offer",
         offer: data.offer, 
         name: connection.name 
      }); 
		
   }  
	
   break;

Premièrement, nous obtenons la connexion de l'utilisateur que nous essayons d'appeler. S'il existe, nous lui envoyons les détails de l' offre . Nous ajoutons également otherName à l' objet de connexion . Ceci est fait pour la simplicité de le trouver plus tard.

Répondre à la réponse a un modèle similaire que nous avons utilisé dans le gestionnaire d' offres . Notre serveur passe simplement tous les messages en réponse à un autre utilisateur. Ajoutez le code suivant après le gestionnaire d' offres -

case "answer": 
   console.log("Sending answer to: ", data.name); 
	
   //for ex. UserB answers UserA 
   var conn = users[data.name]; 
	
   if(conn != null) { 
      connection.otherName = data.name; 
		
      sendTo(conn, { 
         type: "answer", 
         answer: data.answer 
      }); 
   } 
	
   break;

La dernière partie concerne la gestion des candidats ICE entre les utilisateurs. Nous utilisons la même technique en passant simplement des messages entre utilisateurs. La principale différence est que les messages candidats peuvent apparaître plusieurs fois par utilisateur dans n'importe quel ordre. Ajouter le gestionnaire de candidats -

case "candidate": 
   console.log("Sending candidate to:",data.name); 
   var conn = users[data.name];
	
   if(conn != null) { 
      sendTo(conn, { 
         type: "candidate", 
         candidate: data.candidate 
      }); 
   } 
	
   break;

Pour permettre à nos utilisateurs de se déconnecter d'un autre utilisateur, nous devons implémenter la fonction de raccrochage. Il indiquera également au serveur de supprimer toutes les références utilisateur. Ajouter le gestionnaire de congés -

case "leave": 
   console.log("Disconnecting from", data.name); 
   var conn = users[data.name]; 
   conn.otherName = null; 
	
   //notify the other user so he can disconnect his peer connection 
   if(conn != null) { 
      sendTo(conn, { 
         type: "leave" 
      }); 
   } 
	
   break;

Cela enverra également à l'autre utilisateur l' événement de congé afin qu'il puisse déconnecter sa connexion homologue en conséquence. Nous devons également gérer le cas où un utilisateur abandonne sa connexion depuis le serveur de signalisation. Modifions notre gestionnaire de fermeture -

connection.on("close", function() { 

   if(connection.name) { 
      delete users[connection.name]; 
		
      if(connection.otherName) { 
         console.log("Disconnecting from ", connection.otherName); 
         var conn = users[connection.otherName]; 
         conn.otherName = null;  
			
         if(conn != null) { 
            sendTo(conn, { 
               type: "leave" 
            });
         }
			
      } 
   } 
});

Ce qui suit est le code complet de notre serveur de signalisation -

//require our websocket library 
var WebSocketServer = require('ws').Server; 

//creating a websocket server at port 9090 
var wss = new WebSocketServer({port: 9090}); 

//all connected to the server users 
var users = {};
  
//when a user connects to our sever 
wss.on('connection', function(connection) {
  
   console.log("User connected");
	
   //when server gets a message from a connected user 
   connection.on('message', function(message) { 
	
      var data; 
		
      //accepting only JSON messages 
      try { 
         data = JSON.parse(message); 
      } catch (e) { 
         console.log("Invalid JSON"); 
         data = {}; 
      }
		
      //switching type of the user message 
      switch (data.type) { 
         //when a user tries to login
         case "login": 
            console.log("User logged", data.name); 
				
            //if anyone is logged in with this username then refuse 
            if(users[data.name]) { 
               sendTo(connection, { 
                  type: "login", 
                  success: false 
               }); 
            } else { 
               //save user connection on the server 
               users[data.name] = connection; 
               connection.name = data.name; 
					
               sendTo(connection, { 
                  type: "login", 
                  success: true 
               }); 
            } 
				
            break;
				
         case "offer": 
            //for ex. UserA wants to call UserB 
            console.log("Sending offer to: ", data.name);
				
            //if UserB exists then send him offer details 
            var conn = users[data.name]; 
				
            if(conn != null) { 
               //setting that UserA connected with UserB 
               connection.otherName = data.name; 
					
               sendTo(conn, { 
                  type: "offer", 
                  offer: data.offer, 
                  name: connection.name 
               }); 
            }
				
            break;
				
         case "answer": 
            console.log("Sending answer to: ", data.name); 
            //for ex. UserB answers UserA 
            var conn = users[data.name]; 
				
            if(conn != null) { 
               connection.otherName = data.name; 
               sendTo(conn, { 
                  type: "answer", 
                  answer: data.answer 
               }); 
            } 
				
            break; 
				
         case "candidate": 
            console.log("Sending candidate to:",data.name); 
            var conn = users[data.name];
				
            if(conn != null) { 
               sendTo(conn, { 
                  type: "candidate", 
                  candidate: data.candidate 
               }); 
            } 
				
            break;
				
         case "leave": 
            console.log("Disconnecting from", data.name); 
            var conn = users[data.name]; 
            conn.otherName = null; 
				
            //notify the other user so he can disconnect his peer connection 
            if(conn != null) {
               sendTo(conn, { 
                  type: "leave" 
              }); 
            }
				
            break;
				
         default: 
            sendTo(connection, { 
               type: "error", 
               message: "Command not found: " + data.type 
            }); 
				
            break; 
      }
		
   }); 
	
   //when user exits, for example closes a browser window 
   //this may help if we are still in "offer","answer" or "candidate" state 
   connection.on("close", function() { 
	
      if(connection.name) { 
         delete users[connection.name]; 
			
         if(connection.otherName) { 
            console.log("Disconnecting from ", connection.otherName); 
            var conn = users[connection.otherName]; 
            conn.otherName = null;
				
            if(conn != null) { 
               sendTo(conn, { 
                  type: "leave" 
               }); 
            }
         } 
      }
		
   });  
	
   connection.send("Hello world");  
});
  
function sendTo(connection, message) { 
   connection.send(JSON.stringify(message)); 
}

Application client

Une façon de tester cette application consiste à ouvrir deux onglets de navigateur et à essayer de s'appeler.

Tout d'abord, nous devons installer la bibliothèque bootstrap . Bootstrap est un framework frontal pour le développement d'applications Web. Vous pouvez en savoir plus surhttp://getbootstrap.com/.Créez un dossier appelé, par exemple, «vidéochat». Ce sera notre dossier d'application racine. Dans ce dossier, créez un fichier package.json (il est nécessaire pour gérer les dépendances npm) et ajoutez ce qui suit -

{ 
   "name": "webrtc-videochat", 
   "version": "0.1.0", 
   "description": "webrtc-videochat", 
   "author": "Author", 
   "license": "BSD-2-Clause" 
}

Ensuite, exécutez npm install bootstrap . Cela installera la bibliothèque d'amorçage dans le dossier videochat / node_modules .

Nous devons maintenant créer une page HTML de base. Créez un fichier index.html dans le dossier racine avec le code suivant -

<html> 
 
   <head> 
      <title>WebRTC Video Demo</title>
      <link rel = "stylesheet" href = "node_modules/bootstrap/dist/css/bootstrap.min.css"/>
   </head>
	
   <style>
	
      body { 
         background: #eee; 
         padding: 5% 0; 
      } 
		
      video { 
         background: black; 
         border: 1px solid gray; 
      }
		
      .call-page { 
         position: relative; 
         display: block; 
         margin: 0 auto; 
         width: 500px; 
         height: 500px; 
      } 
		
      #localVideo { 
         width: 150px; 
         height: 150px; 
         position: absolute; 
         top: 15px; 
         right: 15px; 
      }
		
      #remoteVideo { 
         width: 500px; 
         height: 500px; 
      }
		
   </style>
	
   <body>
	
   <div id = "loginPage" class = "container text-center"> 
	
      <div class = "row"> 
         <div class = "col-md-4 col-md-offset-4">
			
            <h2>WebRTC Video Demo. Please sign in</h2> 
            <label for = "usernameInput" class = "sr-only">Login</label> 
            <input type = "email" id = "usernameInput" c
               lass = "form-control formgroup" placeholder = "Login" 
               required = "" autofocus = ""> 
            <button id = "loginBtn" class = "btn btn-lg btn-primary btnblock">
               Sign in</button>
				
         </div> 
      </div> 
		
   </div>
	
   <div id = "callPage" class = "call-page"> 
      <video id = "localVideo" autoplay></video> 
      <video id = "remoteVideo" autoplay></video>
		
      <div class = "row text-center"> 
         <div class = "col-md-12"> 
            <input id = "callToUsernameInput" type = "text"
               placeholder = "username to call" /> 
            <button id = "callBtn" class = "btn-success btn">Call</button> 
            <button id = "hangUpBtn" class = "btn-danger btn">Hang Up</button> 
         </div>	
      </div> 
		
   </div>
	
   <script src = "client.js"></script> 
	
   </body>
	
</html>

Cette page devrait vous être familière. Nous avons ajouté le fichier css bootstrap . Nous avons également défini deux pages. Enfin, nous avons créé plusieurs champs de texte et boutons pour obtenir des informations de l'utilisateur. Vous devriez voir les deux éléments vidéo pour les flux vidéo locaux et distants. Notez que nous avons ajouté un lien vers un fichier client.js .

Nous devons maintenant établir une connexion avec notre serveur de signalisation. Créez le fichier client.js dans le dossier racine avec le code suivant -

//our username 
var name; 
var connectedUser;
  
//connecting to our signaling server 
var conn = new WebSocket('ws://localhost:9090');
  
conn.onopen = function () { 
   console.log("Connected to the signaling server"); 
};
  
//when we got a message from a signaling server 
conn.onmessage = function (msg) { 
   console.log("Got message", msg.data);
	
   var data = JSON.parse(msg.data);
	
   switch(data.type) { 
      case "login": 
         handleLogin(data.success);
         break; 
      //when somebody wants to call us 
      case "offer": 
         handleOffer(data.offer, data.name); 
         break; 
      case "answer": 
         handleAnswer(data.answer); 
         break; 
      //when a remote peer sends an ice candidate to us 
      case "candidate": 
         handleCandidate(data.candidate); 
         break; 
      case "leave": 
         handleLeave(); 
         break; 
      default: 
         break; 
   } 
};
  
conn.onerror = function (err) { 
   console.log("Got error", err); 
};
  
//alias for sending JSON encoded messages 
function send(message) { 
   //attach the other peer username to our messages 
   if (connectedUser) { 
      message.name = connectedUser; 
   } 
	
   conn.send(JSON.stringify(message)); 
};

Exécutez maintenant notre serveur de signalisation via le serveur de nœuds . Ensuite, dans le dossier racine, exécutez la commande statique et ouvrez la page dans le navigateur. Vous devriez voir la sortie de console suivante -

L'étape suivante consiste à implémenter une connexion utilisateur avec un nom d'utilisateur unique. Nous envoyons simplement un nom d'utilisateur au serveur, qui nous dit ensuite s'il est pris ou non. Ajoutez le code suivant à votre fichier client.js -

//****** 
//UI selectors block 
//****** 

var loginPage = document.querySelector('#loginPage'); 
var usernameInput = document.querySelector('#usernameInput'); 
var loginBtn = document.querySelector('#loginBtn'); 

var callPage = document.querySelector('#callPage'); 
var callToUsernameInput = document.querySelector('#callToUsernameInput');
var callBtn = document.querySelector('#callBtn'); 

var hangUpBtn = document.querySelector('#hangUpBtn');
  
//hide call page 
callPage.style.display = "none"; 
 
// Login when the user clicks the button 
loginBtn.addEventListener("click", function (event) { 
   name = usernameInput.value; 
	
   if (name.length > 0) { 
      send({ 
         type: "login", 
         name: name 
      }); 
   } 
	
});
 
function handleLogin(success) { 

   if (success === false) { 
      alert("Ooops...try a different username"); 
   } else { 
      //display the call page if login is successful 
      loginPage.style.display = "none"; 
      callPage.style.display = "block";  
      //start peer connection 
   } 
};

Tout d'abord, nous sélectionnons quelques références aux éléments de la page. Le nous cachons la page d'appel. Ensuite, nous ajoutons un écouteur d'événements sur le bouton de connexion. Lorsque l'utilisateur clique dessus, nous envoyons son nom d'utilisateur au serveur. Enfin, nous implémentons le rappel handleLogin. Si la connexion a réussi, nous affichons la page d'appel et commençons à configurer une connexion homologue.

Pour démarrer une connexion entre pairs, nous avons besoin de -

  • Obtenez un flux de la webcam.
  • Créez l'objet RTCPeerConnection.

Ajoutez le code suivant au "bloc des sélecteurs d'interface utilisateur" -

var localVideo = document.querySelector('#localVideo'); 
var remoteVideo = document.querySelector('#remoteVideo');
 
var yourConn; 
var stream;

Modifier la fonction handleLogin -

function handleLogin(success) { 

   if (success === false) { 
      alert("Ooops...try a different username"); 
   } else { 
      loginPage.style.display = "none"; 
      callPage.style.display = "block";
		  
      //********************** 
      //Starting a peer connection 
      //********************** 
		
      //getting local video stream 
      navigator.webkitGetUserMedia({ video: true, audio: true }, function (myStream) { 
         stream = myStream; 
			
         //displaying local video stream on the page 
         localVideo.src = window.URL.createObjectURL(stream);
			
         //using Google public stun server 
         var configuration = { 
            "iceServers": [{ "url": "stun:stun2.1.google.com:19302" }] 
         }; 
			
         yourConn = new webkitRTCPeerConnection(configuration);
			
         // setup stream listening 
         yourConn.addStream(stream); 
			
         //when a remote user adds stream to the peer connection, we display it 
         yourConn.onaddstream = function (e) { 
            remoteVideo.src = window.URL.createObjectURL(e.stream); 
         };
			
         // Setup ice handling 
         yourConn.onicecandidate = function (event) {
			
            if (event.candidate) { 
               send({ 
                  type: "candidate", 
                  candidate: event.candidate 
               }); 
            } 
				
         };
			
      }, function (error) { 
         console.log(error); 
      }); 
   } 
};

Maintenant, si vous exécutez le code, la page devrait vous permettre de vous connecter et d'afficher votre flux vidéo local sur la page.

Nous sommes maintenant prêts à lancer un appel. Tout d'abord, nous envoyons une offre à un autre utilisateur. Une fois qu'un utilisateur reçoit l'offre, il crée une réponse et commence à échanger des candidats ICE. Ajoutez le code suivant au fichier client.js -

//initiating a call 
callBtn.addEventListener("click", function () { 
   var callToUsername = callToUsernameInput.value; 
	
   if (callToUsername.length > 0) {
	
      connectedUser = callToUsername;
		
      // create an offer
      yourConn.createOffer(function (offer) { 
         send({ 
            type: "offer", 
            offer: offer 
         }); 
			
         yourConn.setLocalDescription(offer); 
			
      }, function (error) { 
         alert("Error when creating an offer"); 
      });  
   } 
});
  
//when somebody sends us an offer 
function handleOffer(offer, name) { 
   connectedUser = name; 
   yourConn.setRemoteDescription(new RTCSessionDescription(offer));
	
   //create an answer to an offer 
   yourConn.createAnswer(function (answer) { 
      yourConn.setLocalDescription(answer); 
		
      send({ 
         type: "answer", 
         answer: answer 
      }); 
		
   }, function (error) { 
      alert("Error when creating an answer"); 
   }); 
};
  
//when we got an answer from a remote user 
function handleAnswer(answer) { 
   yourConn.setRemoteDescription(new RTCSessionDescription(answer));
}; 
 
//when we got an ice candidate from a remote user 
function handleCandidate(candidate) { 
   yourConn.addIceCandidate(new RTCIceCandidate(candidate)); 
};

Nous ajoutons un gestionnaire de clics au bouton d'appel, qui lance une offre. Ensuite, nous implémentons plusieurs gestionnaires attendus par le gestionnaire onmessage . Ils seront traités de manière asynchrone jusqu'à ce que les deux utilisateurs aient établi une connexion.

La dernière étape consiste à implémenter la fonction de raccrochage. Cela arrêtera de transmettre des données et demandera à l'autre utilisateur de fermer l'appel. Ajoutez le code suivant -

//hang up 
hangUpBtn.addEventListener("click", function () { 

   send({ 
      type: "leave" 
   });
	
   handleLeave(); 
});
  
function handleLeave() { 
   connectedUser = null; 
   remoteVideo.src = null; 
	
   yourConn.close(); 
   yourConn.onicecandidate = null; 
   yourConn.onaddstream = null; 
};

Lorsque l'utilisateur clique sur le bouton Raccrocher -

  • Il enverra un message «laisser» à l'autre utilisateur
  • Cela fermera le RTCPeerConnection et détruira la connexion localement

Exécutez maintenant le code. Vous devriez pouvoir vous connecter au serveur à l'aide de deux onglets de navigateur. Vous pouvez ensuite appeler l'onglet et raccrocher.

Ce qui suit est le fichier client.js complet -

//our username 
var name; 
var connectedUser;
  
//connecting to our signaling server
var conn = new WebSocket('ws://localhost:9090');
  
conn.onopen = function () { 
   console.log("Connected to the signaling server"); 
};
  
//when we got a message from a signaling server 
conn.onmessage = function (msg) { 
   console.log("Got message", msg.data);
	
   var data = JSON.parse(msg.data); 
	
   switch(data.type) { 
      case "login": 
         handleLogin(data.success); 
         break; 
      //when somebody wants to call us 
      case "offer": 
         handleOffer(data.offer, data.name); 
         break; 
      case "answer": 
         handleAnswer(data.answer); 
         break; 
      //when a remote peer sends an ice candidate to us 
      case "candidate": 
         handleCandidate(data.candidate); 
         break; 
      case "leave": 
         handleLeave(); 
         break; 
      default: 
         break; 
   }
};
  
conn.onerror = function (err) { 
   console.log("Got error", err); 
};
  
//alias for sending JSON encoded messages 
function send(message) { 
   //attach the other peer username to our messages 
   if (connectedUser) { 
      message.name = connectedUser; 
   } 
	
   conn.send(JSON.stringify(message)); 
};
  
//****** 
//UI selectors block 
//******
 
var loginPage = document.querySelector('#loginPage'); 
var usernameInput = document.querySelector('#usernameInput'); 
var loginBtn = document.querySelector('#loginBtn'); 

var callPage = document.querySelector('#callPage'); 
var callToUsernameInput = document.querySelector('#callToUsernameInput');
var callBtn = document.querySelector('#callBtn'); 

var hangUpBtn = document.querySelector('#hangUpBtn');
  
var localVideo = document.querySelector('#localVideo'); 
var remoteVideo = document.querySelector('#remoteVideo'); 

var yourConn; 
var stream;
  
callPage.style.display = "none";

// Login when the user clicks the button 
loginBtn.addEventListener("click", function (event) { 
   name = usernameInput.value;
	
   if (name.length > 0) { 
      send({ 
         type: "login", 
         name: name 
      }); 
   }
	
});
  
function handleLogin(success) { 
   if (success === false) { 
      alert("Ooops...try a different username"); 
   } else { 
      loginPage.style.display = "none"; 
      callPage.style.display = "block";
		
      //********************** 
      //Starting a peer connection 
      //********************** 
		
      //getting local video stream 
      navigator.webkitGetUserMedia({ video: true, audio: true }, function (myStream) { 
         stream = myStream; 
			
         //displaying local video stream on the page 
         localVideo.src = window.URL.createObjectURL(stream);
			
         //using Google public stun server 
         var configuration = { 
            "iceServers": [{ "url": "stun:stun2.1.google.com:19302" }]
         }; 
			
         yourConn = new webkitRTCPeerConnection(configuration); 
			
         // setup stream listening 
         yourConn.addStream(stream); 
			
         //when a remote user adds stream to the peer connection, we display it 
         yourConn.onaddstream = function (e) { 
            remoteVideo.src = window.URL.createObjectURL(e.stream); 
         };
			
         // Setup ice handling 
         yourConn.onicecandidate = function (event) { 
            if (event.candidate) { 
               send({ 
                  type: "candidate", 
                  candidate: event.candidate 
               }); 
            } 
         };  
			
      }, function (error) { 
         console.log(error); 
      }); 
		
   } 
};
  
//initiating a call 
callBtn.addEventListener("click", function () { 
   var callToUsername = callToUsernameInput.value;
	
   if (callToUsername.length > 0) { 
	
      connectedUser = callToUsername;
		
      // create an offer 
      yourConn.createOffer(function (offer) { 
         send({ 
            type: "offer", 
            offer: offer 
         }); 
			
         yourConn.setLocalDescription(offer); 
      }, function (error) { 
         alert("Error when creating an offer"); 
      });
		
   } 
});
  
//when somebody sends us an offer 
function handleOffer(offer, name) { 
   connectedUser = name; 
   yourConn.setRemoteDescription(new RTCSessionDescription(offer));
	
   //create an answer to an offer 
   yourConn.createAnswer(function (answer) { 
      yourConn.setLocalDescription(answer); 
		
      send({ 
         type: "answer", 
         answer: answer 
      }); 
		
   }, function (error) { 
      alert("Error when creating an answer"); 
   }); 
};
  
//when we got an answer from a remote user
function handleAnswer(answer) { 
   yourConn.setRemoteDescription(new RTCSessionDescription(answer)); 
};
  
//when we got an ice candidate from a remote user 
function handleCandidate(candidate) { 
   yourConn.addIceCandidate(new RTCIceCandidate(candidate)); 
};
   
//hang up 
hangUpBtn.addEventListener("click", function () { 

   send({ 
      type: "leave" 
   });  
	
   handleLeave(); 
});
  
function handleLeave() { 
   connectedUser = null; 
   remoteVideo.src = null; 
	
   yourConn.close(); 
   yourConn.onicecandidate = null; 
   yourConn.onaddstream = null; 
};

Sommaire

Cette démo fournit une base de fonctionnalités dont chaque application WebRTC a besoin. Pour améliorer cette démo, vous pouvez ajouter une identification de l'utilisateur via des plates-formes comme Facebook ou Google, gérer la saisie de l'utilisateur pour les données invalides. En outre, la connexion WebRTC peut échouer pour plusieurs raisons, comme ne pas prendre en charge la technologie ou ne pas pouvoir traverser les pare-feu. Un travail considérable a été consacré à la stabilisation de toute application WebRTC.