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) {
});
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
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.- Primero enviamos un casco al socket del servidor JSON para que podamos llamar a Petya desde la cuenta de Vasya
connection.send(JSON.stringify({
}))
- 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){
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
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({
}))
}
};
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
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() {
}))
}, 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();
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) {
}
};
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))