Caro leitor, antes de começarmos a escrever o código, vamos dar uma olhada no conceito de vídeo chamadas.Imagine a situação: temos uma plataforma de bate-papo e precisamos anexar videochamadas, ou seja, um certo Vasya está sentado online e ele quer ligar para Petya, para implementar esse recurso, precisamos da tecnologia WebSocket .Bem, vamos aumentar nosso servidor WebSocket, o node.js nos ajudará com isso;Crie o arquivo sockets.js e escreva o código do soquete do servidor: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);
})
Crie um arquivo index.html e escreva o código para abrir uma conexão de soquete: <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>
Agora crie e conecte o arquivo script.js ao nosso arquivo 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)
};
Então, de volta aos nossos Vasya e Petya
Esse é o estágio inicial no qual Vasya e Petya simplesmente trocam JSON sobre a possibilidade de recebermos uma chamada ou não, ou seja, ao entrar em nossa página, precisamos abrir uma conexão WebSocket para se comunicar com nosso servidor de soquete.- Primeiro enviamos um capacete para o soquete do servidor JSON, para que desejemos ligar para Petya da conta de Vasya
connection.send(JSON.stringify({
}))
- Devemos aceitar esse JSON no servidor de soquete. Após recebermos a solicitação, anexamos o evento de mensagem ao nosso servidor :
connection.on('message',function(message){
let self = JSON.parse(message.utf8Data);
})
Depois de conversar e decidir que os dois usuários estão prontos para uma conversa, precisamos descobrir como a comunicação por vídeo funciona em um navegador, um módulo para isso é construído em js - RTCPeerConnection
Precisamos abrir o RTCPeerConnection, com o qual podemos gerar uma oferta e enviá-la ao usuário de que precisamos, novamente através do nosso servidor de soquete, que, ao recebê-la, gerará uma resposta e a enviará de volta, após o que começamos a trocar pacotes de gelo contendo informações sobre o ambiente este computador, necessário para o estabelecimento bem-sucedido de comunicações de vídeo.Geramos e enviamos ofertas
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();
}
Processamos ofertas e geramos respostas
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")});
}
}
Aceitamos a resposta e criamos um fluxo de vídeo
pc.setRemoteDescription(new RTCSessionDescription(data.answer), function() { }, error);
E a última coisa que precisamos fazer é processar os pacotes de gelo
pc.addIceCandidate(new RTCIceCandidate(ice))