我向哈勃的所有读者致以问候。 今年,我有机会为一个培训门户网站编写了一个视频通信模块,以便直接在教师和学生的网站上通过视频通信进行打电话。 没有必要解决这样的早期任务。 简短搜索后,我发现有两种方法:Flash和
WebRTC 。 纯粹的WebRTC变得很复杂,并且通常很自然,因为视频通信的任务并不简单。 但是后来我遇到了
PeerJS ,它是WebRTC的包装。 在本文中,我将告诉您如何快速组织浏览器拨号器。
为了重复该示例,将需要通过https协议访问您的测试页面(因为该页面将请求访问摄像头和麦克风,并且在没有安全协议的情况下,浏览器只会给出错误)
起始布局将如下所示:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Peer</title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <p><h3> ID: </h3><span id=myid ></span></p> <input id=otherPeerId type=text placeholder="otherPeerId" > <button onclick="callToNode(document.getElementById('otherPeerId').value)"></button> <br> <video id=myVideo muted="muted" width="400px" height="auto" ></video> <div id=callinfo ></div> <video id=remVideo width="400px" height="auto" ></video> </body>
在头部,我们远程连接PeerJS。 也可以下载脚本并将其本地连接。
输入id = otherPeerId-旨在输入我们将要呼叫的宴会(您可以将其作为索引或电话号码)。
两个视频标签分别用于显示您自己的视频和对话者的视频。
现在介绍一下WebRTC技术以及如何进行呼叫。 WebRTC直接在客户端之间进行呼叫,而无需服务器参与,因此第一步中,浏览器应该彼此找到对方。 为此,传统的WebRTC需要一个信号服务器,即,一个服务器告诉一个浏览器另一浏览器的参数,而在WebRTC中,您必须自己组织这样的服务器。 但是,PeerJS开发人员提供了自己的信号服务器。 您需要做的就是将peerID传递给潜在的对话者,即在PeerJS系统中接收到的唯一索引。 在工作草案中,我这样组织它:
- 加载页面后,将创建一个Peer对象
- 它的peerID写入mysql数据库
- 当按下“呼叫”按钮时,对话者的peerID被从数据库中拉出并用于建立连接
在当前测试用例中,我们将在otherPeerId文本字段中输入对话者的peerID
因此,让我们开始编写代码。1.创建主要的对等对象
var peer = new Peer();
2.在宴会开始时,我们将收到令人垂涎的peerID,必须将其转移给合作伙伴,以便他可以与我们联系
peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; });
3.为了接听电话,我们挂断了电话事件的处理程序
var peercall; peer.on('call', function(call) {
有了来电,我们得到一个
通话对象,该对象保存在
peercall全局变量中。 此外,在信息栏中,还会显示有关来电的通知,并显示两个按钮:接受和拒绝
4.我们为“
接受”按钮编写一个函数
function callanswer() { navigator.mediaDevices.getUserMedia ({ audio: true, video: true }).then(function(mediaStream) { var video = document.getElementById('myVideo'); peercall.answer(mediaStream);
navigator.mediaDevices.getUserMedia-请求访问摄像头和麦克风。 因此,在传递给此方法的对象的数据中
{audio:true,video:true},您可以仅请求访问摄像机或麦克风。 进一步的注释直接添加到代码中。
setTimeout是根据经验添加的:合作伙伴的视频未开始播放,但是可以超时。
5.按
通话键拨号的功能
function callToNode(peerId) {
与上一段一样,我们要求您提供媒体流。 在调用对等对象的调用函数之后,它将调用对象返回给我们,并将其保存在peercall中。 我们处理流事件以找出答案,并将传入流放入相应的视频对象中
仅此而已...
如果两个呼叫者都位于NATth后面,则呼叫不会通过。 (为什么?请在此处阅读
habr.com/en/company/yandex/blog/419951 )
为了克服这一障碍,在创建对等对象时必须指定TURN服务器(在何处获取它不是最简单的问题。我们必须提出自己的问题:在Ubuntu 16.04上使用VPS。使用命令安装
apt install coturn
)
然后,宴会的创建将如下所示:
var callOptions={'iceServers': [ {url: 'stun:95.xxx.xx.x9:3479', username: "user", credential: "xxxxxxxxxx"}, { url: "turn:95.xxx.xx.x9:3478", username: "user", credential: "xxxxxxxx"}] }; peer= new Peer({config: callOptions});
最后,整个代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Peer</title> <script src="https://unpkg.com/peerjs@1.0.0/dist/peerjs.min.js"></script> </head> <body> <p><h3> ID: </h3><span id=myid ></span></p> <input id=otherPeerId type=text placeholder="otherPeerId" > <button onclick="callToNode(document.getElementById('otherPeerId').value)"></button> <br> <video id=myVideo muted="muted" width="400px" height="auto" ></video> <div id=callinfo ></div> <video id=remVideo width="400px" height="auto" ></video> <script> var callOptions={'iceServers': [ {url: 'stun:95.xxx.xx.x9:3479', username: "user", credential: "xxxxxxxxxx"}, { url: "turn:95.xxx.xx.x9:3478", username: "user", credential: "xxxxxxxx"}] }; peer= new Peer({config: callOptions}); peer.on('open', function(peerID) { document.getElementById('myid').innerHTML=peerID; }); var peercall; peer.on('call', function(call) { </script> </body>
此解决方案已在Windows7和Ubuntu 18.04的Chrome,Opera,Firefox中成功测试。 Chrome也可以在Android和MacOS上运行,但不能在iPhone和iPad上运行。