文章目录
- 基于WebRTC实现音视频通话
- P2P通信原理
- 如何发现对方?
- 不同的音视频编解码能力如何沟通?(媒体协商SDP)
- 如何联系上对方?(网络协商)
- 常用的API
- 音视频采集getUserMedia
- 核心对象RTCPeerConnection
WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。
基于WebRTC实现音视频通话
背景: 随着互联网技术的飞速发展,实时音视频通话已经成为在线教育、远程办公、社交媒体等领域的核心且常用的功能。WebRTC(Web Real-Time Communication)作为一项开放的实时通信标准,为开发者提供了快速构建实时音视频通话系统的能力。在本课程中,我们将从0到1使用 WebRTC构建一个基于P2P 架构的音视频通话的应用案例。
应用场景:
- 点对点视频聊天:如 微信视频 等实时视频通话应用。
- 多人视频会议:企业级多人视频会议系统,如飞书、钉钉、腾讯会议等。
- 在线教育:如腾讯课堂、网易云课堂等。
- 直播:游戏直播、课程直播等。
P2P通信原理
传统通信方式:一个客户端发个消息给服务端,服务端转发给目标客户端
P2P点对点通信:不需要依赖服务器,两个客户端可以直接进行通信,但也并不是完全不需要 不依赖服务器,还需要一个(跟踪服务器 好像是这个名字) 服务器去交换一些元数据。
要实现两个客户端的实时音视频通信 并且这两个客户端可能处于不同的网络环境,使用不同的设备,都需要解决哪些问题?
主要是下面这三个问题:
- 如何发现对方?
- 不同的音视频编码能力如何沟通?
- 如何联系上对方
如何发现对方?
在 P2P 通信的过程中,双方需要交换一些元数据比如媒体信息、网络数据等等信息,我们通常称这一过程叫做”信令(signaling) "。
对应的服务器即“信令服务器(signaling server)",通常也有人将之称为“房间服务器”,因为它不仅可以交换彼此的媒体信息和网络信息,同样也可以管理房间信息。
比如:
1)通知彼此 who 加入了房间;
2)who 离开了房间
3)告诉第三方房间人数是否已满是否可以加入房间。
为了避免出现冗余,并最大限度地提高与已有技术的兼容性,WebRTC标准并没有规定信令方法和协议。在本课程中会使用websocket来搭建一个信令服务器
不同的音视频编解码能力如何沟通?(媒体协商SDP)
不同浏览器对于音视频的编解码能力是不同的。
比如:以日常生活中的例子来讲,小李会讲汉语和英语,而小王会讲汉语和法语。为了保证双方都可以正确的理解
对方的意思,最简单的办法即取他们都会的语言,也就是汉语来沟通。
在 WebRTC 中:有一个专门的协议,称为 Session Description Protocol(SDP),可以用于描述上述这类信息。
因此:参与音视频通讯的双方想要了解对方支持的媒体格式,必须要交换SDP 信息。而交换 SDP 的过程,通常称之为 媒体协商 。
如何联系上对方?(网络协商)
其实就是网络协商的过程,即参与音视频实时通信的双方要了解彼此的网络情况,这样才有可能找到一条相互通讯的链路。
理想的网络情况是每个客户端都有自己的私有公网IP 地址,这样的话就可以直接进行点对点连接。实际上呢,出于网络安全和其他原因的考虑,大多数客户端之间都是在某个局域网内(比如说公司内网),需要 网络地址转换(NAT)
在 WebRTC中我们使用 ICE 机制建立网络连接。ICE 协议通过一系列的技术(如 STUN、TURN服务器)帮助通信双方发现和协商可用的公共网络地址,从而实现 NAT 穿越。(通信双方找到能联系上对方的IP地址)
ICE 的工作原理如下:
1.首先,通信双方收集本地网络地址(包括私有地址和公共地址)以及通过STUN和TURN 服务器获取的候选地址。
2.接下来,双方通过信令服务器交换这些候选地址。
3.通信双方使用这些候选地址进行连接测试,确定最佳的可用地址。
4.一旦找到可用的地址,通信双方就可以开始实时音视频通话。
在WebRTC中,网络信息通常用candidate来描述
针对上面三个问题的总结:就是通过 WebRTC 提供的 API 获取各端的媒体信息SDP 以及 网络信息 candidate并通过信令服务器交换,进而建立了两端的连接通道完成实时视频语音通话。
常用的API
音视频采集getUserMedia
const getLocalStream= async =>{
const stream=await navigator.mediaDevices.getUserMedia({
//获取音视频流,获取到声音和画面 传入两个参数
audio:true,
video:true
})
localVideo.value!.srcObject=stream//进行音视频的播放
localVideo.value.play()
return stream
}
核心对象RTCPeerConnection
RTCPeerConnection作为创建点对点连接的API,是我们实现音视频实时通信的关键
//核心对象RTCPeerConnection
const peer=new RTCPeerConnection({
//构造函数的配置,这里和上面的知识点关联起来(网络协商里面的两个服务)
iceServers:[
{url:"stun:stun.l.google.com:19302"},//谷歌的公共服务
{
urls:"turn:***",
credential:"***",
username:"***",
},
]
})
主要会用到以下爱几个方法:
媒体协商方法:
通过下面这些方法去生成上面的媒体信息SDP和网络信息candidate
- createOffer
- createAnswer
- setLocalDesccription
- setRemoteDesccription
重要事件:
- onicecandidate
- onaddstream
整个媒体协商过程可以简化为三个步骤对应上述四个媒体协商方法:
- 呼叫端创建 Offer(createOffer)井将 offer 消息(内容是呼叫端的 SDP 信息)通过 信令服务器 传送给接收端,同时调用 setLocalDesccription 将含有本地JSDP 信息的 Offer 保存起来
- 接收端收到对端的 Offer 信息后调用 setRemoteDesccription 方法将含有对端 SDP 信息的 Offer 保存起来,并创建 Answer(createAnswer)并将 Answer 消息(内容是接收端的 SDP 信息)通过信令服务器传送给呼叫端
- 呼叫端收到对端的 Answer 信息后调用 setRemoteDesccription 方法将含有对端 SDP 信息的 Answer 保存起来
交换candidate信息的过程:
经经过上述三个步骤,则完成了 P2P 通信过程中的媒体协商部分,实际上在呼叫端以及接收端调用setLocalDesccription 同时也开始了收集各端自己的网络信息(candidate),然后各端通过监听事件onicecandidate 收集到各自的 candidate 并通过信令服务器传送给对端,进而打通 P2P 通信的网络通道,并通过监听 onaddstream 事件拿到对方的视频流进而完成了整个视频通话过程。
完整的通信过程图如下: