为初学者揭秘 WebRTC 视频通话应用程序

为初学者揭秘 WebRTC 视频通话应用程序

你是一名开发人员(前端/后端/全栈),对使用 WebRTC 开发应用程序感到好奇吗?在过去的几天甚至几个月里,你是否在互联网上搜索学习基础知识并构建一个基本的 WebRTC 视频通话应用程序?

虽然有一些 Github 代码库提供了构建一个非常基本的 p2p 视频通话应用程序的代码,但它们都没有关于代码内部工作原理的详细信息。这些软件库中的代码只是在本地主机上运行一两个命令,就可以连接浏览器的两个标签页进行视频通话。当你试图通读这些代码时,你会发现一堆非常陌生、有时甚至不合逻辑的 API 调用。

为了揭开使用 WebRTC 的基本视频通话应用程序的神秘面纱,我们需要遵循一个对初学者友好的三步方法,这也是常识性的。让我们开始吧。

构建视频通话应用程序的第一步是了解如何获取要使用 Chrome/firefox/edge/safari 浏览器进行通话的设备的摄像头和/或麦克风。它可以是台式机/笔记本电脑/移动设备,只要存在这些浏览器中的任何一种即可。没有摄像头和麦克风,视频通话就没有任何意义。可能会有这样的用例:在 p2p 模式下使用 WebRTC,数据通道仅用于文件共享,但我们今天不打算在这篇文章中讨论这个问题。

从浏览器获取摄像头和麦克风的方法是使用名为 getUserMedia 的 API。下面这行代码将从浏览器中获取摄像头和麦克风。

const stream = await 
navigator.mediaDevices.getUserMedia({audio:true,video:true});

有了上面这行代码,我们就能在一些先决条件下获取摄像头和麦克风。如果不是在 HTTPS 上运行,上述代码将不起作用。

如果已经成功获取了摄像头和麦克风,那么就可以开始构建 WebRTC 视频通话应用程序的第 2 步了。在这一步中,需要构建一个简单的信令服务器,以便在呼叫方和被呼叫方之间交换一些信息。这一步主要是构建一个服务器端应用程序,该应用程序将连接到呼叫方和被呼叫方,并让他们在需要时共享一些秘密信息。Nodejs 是服务器端框架,在本示例中将用作信令服务器,WebSocket 是连接用户的连接机制。

以下是示例代码:

const https=require('https'); const WebSocket=require('ws'); 
const WebSocketServer=WebSocket.Server; 
const httpsServer=https.createServer(serverConfig,handleRequest); 
httpsServer.listen(HTTPS_PORT,'0.0.0.0'); 
const wss=newWebSocketServer({server: httpsServer}); 
 wss.on('connection',function(ws){ 
    ws.on('message',function(message){  
        }) 
})

通过上述几行代码,我们就拥有了一个基本的信令服务器,可以监听来自呼叫者/被呼叫者的消息。

现在已准备好使用我们在最后两个步骤中所做的工作来构建真正的视频通话应用程序。以下是建立呼叫所需的步骤。

  • 呼叫方(对等点 A)连接到信令服务器并等待被叫方(对等点 B)
  • 被叫方(对等点 B)连接信令服务器,并通知对等点 A 他/她可以通话
  • 对等点 B 点击呼叫按钮,”砰 “的一声,呼叫就接通了,对等点 A 和对等点 B 都能看到和听到对方。

以下是建立呼叫的幕后实际步骤。

  • Peer B 首先创建一个新的 PeerConnection 对象,同时将可用的 ICE 服务器作为参数传递,这有助于发送和接收媒体流。
const pc = new RTCPeerConnection({iceServers});
  • 然后,它会获取本地摄像头和麦克风,并将这些摄像头和麦克风轨道添加到 PeerConnection。这将使 PeerConnection 准备好在连接建立后立即发送媒体源,即当两个用户都同意使用双方都可接受的通用网络配置时)
Stream.getTracks().forEach((track) => pc.addTrack(track,stream));
  • 接着它会创建一个offer,生成offer SDP(会话描述协议),其中包含大量纯文本格式的信息(大约80 -100行信息​​)。它包含网络设置、可用媒体流(音频/视频/屏幕共享/其他任何内容)、当前可用于编码和解码媒体数据包的编解码器以及许多其他内容等信息。
const offer = await pc.createOffer().catch(function (error) {
         alert("Error when creating an offer", error);       
});
  • 一旦 SDP 生成,就会使用提议设置 PeerConnection 的本地描述。简单地说,它要求浏览器最终确认 SDP 中所有可用选项的有效性。本地描述设置完成后,SDP 又名设置就不能再更改了,然后 SDP 就会被发送到远程对等点 A,让其浏览器完成对等点 B 浏览器刚刚完成的所有操作。
await pc.setLocalDescription(offer);  
//send the offer to peer A using the signalling channel
  • 一旦设置了本地描述,它就开始生成ice候选(简单来说,即对等点B的当前网络配置)并将其发送到对等点A以检查网络参数是否适合他/她的设备接收媒体流。
pc.onicecandidate = function (event) {
       if (event.candidate) {
        //send the ice candidate to the other peer using the
           //signalling channel
     }       
};
  • 当对等点 A 的浏览器接收到通过信令服务器发送的 SDP,对等点 A 首先创建一个 PeerConnection 对象,同时将其作为参数传递给 ICE 服务器以实现相同目的。一旦创建了 PeerConnection,它就会使用对等体 A 提供的 Offer SDP 来设置其远程描述。需要这样做是为了让浏览器知道其他对等点的详细信息,以便浏览器可以在稍后阶段创建应答 SDP 作为对报价的应答。
const pc = new RTCPeerConnection({iceServers}); pc.setRemoteDescription(new RTCSessionDescription(offer));
  • 对于对等点 A 来说,重复步骤 3,它获取自己的媒体流并将其添加到对等连接中,以便在建立连接后准备发送。
Stream.getTracks().forEach((track) => pc.addTrack(track,stream));
  • 然后,它通过调用 PeerConnection 对象上的创建应答 API 来创建应答,并生成应答 SDP。生成应答 SDP 后,在对等点 A 端设置本地描述,要求浏览器进行最后一次确认。确认后,答案将通过信令通道发送给对等点 B,以便对等点 B 的浏览器接受该答案。
const answer = await pc.createAnswer().catch(function (error) {
         alert("Error when creating an answer", error);
       }); 
await pc.setLocalDescription(answer); 
//send the offer to peer A using the signalling channel
  • 一旦用户B端收到应答SDP,它就调用设置远程描述API来请求浏览器接受其他用户的SDP。一旦浏览器确认,媒体传输连接就已建立。
pc.setRemoteDescription(new RTCSessionDescription(answer));
  • 出于完全相同的目的,对等点 A 的浏览器会重复步骤 2。到目前为止,两个浏览器都了解彼此的网络配置。之后,双方同意在浏览器提供的所有可能的网络配置选项中使用一种网络配置。然后,双方选定的网络配置(又称 ice candidate)将用于双方用户之间的实际媒体传输。
pc.onicecandidate = function (event) {
       if (event.candidate) {
        //send the ice candidate to the other peer using the 
          //signalling channel 
       }     
};
  • 一旦建立连接,每个 PeerConnection 对象就开始向远程用户发送各自的媒体流。一旦媒体到达另一端,PeerConnection 对象上就会触发一个名为 ontrack 的事件,让浏览器知道其他对等媒体已经到达并准备好被使用。然后,本地浏览器从其 PeerConnection 对象中提取媒体并将其显示在视频元素中。
pc.ontrack = (event) => {
      if(event.streams && event.streams[0]){
     //The remote stream is now available at event.streams[0]. It
          //can be attached to the srcObject of a video element to
      //display the remote stream to the peer.
     }
  }
  • 现在呼叫已成功建立,对等点 A 和对等点 B 都可以使用各自的摄像头和麦克风进行实时通信。

正确完成上述所有步骤,就能成功建立 WebRTC 视频通话。这是 Github 的链接,所有上述步骤和工作代码都创建在不同的文件夹中,供你参考。为本示例创建的 Github 代码库中的代码仅供学习之用,并不适合用于生产。如果您有兴趣构建生产级应用,可以访问 Web实现视频通话

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/webrtc/30372.html

(0)

相关推荐

发表回复

登录后才能评论