亲爱的读者,在开始编写代码之前,让我们看一下视频通话的概念。想象一下这种情况:我们有一个聊天平台,我们需要加快对它的视频通话,也就是说,某个Vasya正坐在网上,他想给Petya打电话,要实现这种功能,我们需要WebSocket技术。好吧,让我们提高我们的WebSocket服务器,node.js将帮助我们实现这一点;创建sockets.js文件,并在其中写入服务器套接字代码: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);
})
创建一个index.html文件,并在其中编写代码以打开套接字连接: <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>
现在创建并将script.js文件连接到我们的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)
};
所以,回到我们的Vasya和Petya
这是Vasya和Petya仅交换有关是否接收呼叫的JSON的初始阶段,也就是说,进入页面时,我们必须打开WebSocket连接才能与套接字服务器进行通信。- 我们首先将头盔发送到JSON服务器套接字,以便我们希望通过Vasya的帐户呼叫Petya
connection.send(JSON.stringify({
}))
- 我们必须在套接字服务器上接受此JSON,在收到请求后,我们将message事件附加到我们的服务器上:
connection.on('message',function(message){
let self = JSON.parse(message.utf8Data);
})
讨论并确定两个用户都准备好进行对话后,我们需要弄清楚视频通信在浏览器中的工作方式,为此模块在js中内置-RTCPeerConnection
我们需要打开RTCPeerConnection,通过它我们可以生成一个报价并将其再次通过套接字服务器发送给我们所需的用户,该套接字服务器在收到该报价时将生成响应并将其发送回去,然后我们开始交换包含有关环境信息的冰包。这台计算机,对于成功建立视频通信是必不可少的。我们生成并发送报价
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();
}
我们处理报价并生成答案
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")});
}
}
我们接受答案并创建视频流
pc.setRemoteDescription(new RTCSessionDescription(data.answer), function() { }, error);
最后我们要做的是处理冰袋
pc.addIceCandidate(new RTCIceCandidate(ice))