Webrtc介绍

前言

点对点的流程

image-20220616172846087

多方通讯

WebRTC多方通信的架构

  • Mesh方案 同一个房间支持4-6人
  • MCU方案 适合多人视频会议,对服务器压力较大
  • SFU方案 服务器只做转发不做音视频混流 适合1对多

流程

img

上述序列中,WebRTC并不提供Stun服务器和Signal服务器,服务器端需要自己实现。

Stun服务器可以用google提供的实现stun协议的测试服务器(stun:stun.l.google.com:19302),Signal服务器则完全需要自己实现了,它需要在ClientA和ClientB之间传送彼此的SDP信息和candidate信息,ClientA和ClientB通过这些信息建立P2P连接来传送音视频数据。

上述序列中,标注的场景是ClientA向ClientB发起对聊请求,调用描述如下:

  1. ClientA首先创建PeerConnection对象,然后打开本地音视频设备,将音视频数据封装成MediaStream添加到PeerConnection中。

  2. ClientA调用PeerConnection的CreateOffer方法创建一个用于offer的SDP对象,SDP对象中保存当前音视频的相关参数。

    ClientA通过PeerConnection的SetLocalDescription方法将该SDP对象保存起来,并通过Signal服务器发送给ClientB。

  3. ClientB接收到ClientA发送过的offer SDP对象,通过PeerConnection的SetRemoteDescription方法将其保存起来,并调用PeerConnection的CreateAnswer方法创建一个应答的SDP对象,通过PeerConnection的SetLocalDescription的方法保存该应答SDP对象并将它通过Signal服务器发送给ClientA。

  4. ClientA接收到ClientB发送过来的应答SDP对象,将其通过PeerConnection的SetRemoteDescription方法保存起来。

  5. 在SDP信息的offer/answer流程中,ClientA和ClientB已经根据SDP信息创建好相应的音频Channel和视频Channel并开启Candidate数据的收集,Candidate数据可以简单地理解成Client端的IP地址信息(本地IP地址、公网IP地址、转发服务端分配的地址)。

  6. 当ClientA收集到Candidate信息后,PeerConnection会通过OnIceCandidate接口给ClientA发送通知,ClientA将收到的Candidate信息通过Signal服务器发送给ClientB,ClientB通过PeerConnection的AddIceCandidate方法保存起来。同样的操作ClientB对ClientA再来一次。

  7. 这样ClientA和ClientB就已经建立了音视频传输的P2P通道,ClientB接收到ClientA传送过来的音视频流,会通过PeerConnection的OnAddStream回调接口返回一个标识ClientA端音视频流的MediaStream对象,在ClientB端渲染出来即可。同样操作也适应ClientB到ClientA的音视频流的传输。

stun/turn服务器

STUN服务器

STUN典型组网

服务端

coturn是一个stun和turn服务端

1
2
npm install coturn
turnserver

找到配置文件

1
find /usr -name turnserver.conf

我这的路径为

/usr/share/doc/coturn/etc/turnserver.conf

生成证书

1
openssl req -x509 -newkey rsa:2048 -keyout /usr/local/etc/turn_server_pkey.pem -out /usr/local/etc/turn_server_cert.pem -days 99999 -nodes

在配置文件末尾加入一下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 监听的端口
listening-port=3478
# 监听的内网IP
listening-ip=0.0.0.0
# 监听的外网IP
external-ip=49.4.27.42
# 设置账号密码
user=psvmc:123456

cli-password=123456

#UDP 最小端口和最大端口
min-port=40000
max-port=60000

# 证书
cert=/usr/local/etc/turn_server_cert.pem
pkey=/usr/local/etc/turn_server_pkey.pem

内网地址可以通过

1
ifconfig

找到eth0对应的IP

image-20220616145751913

指定配置文件启动服务

1
2
killall -9 turnserver
turnserver -v -r 49.4.27.42 -a -o -c /usr/share/doc/coturn/etc/turnserver.conf

我们进入这个地址测试

https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

测试stun的时候不需要输入账号密码,只需要输入第一行,以stun:开头

stun:49.4.27.42:3478

需要输入turn地址,以turn:开头,以及账号密码

turn:49.4.27.42:3478
psvmc
123456

如图

image-20220616155306159

注意

只要出现Done即为成功,下面提示的fail不用在意。

客户端

https://www.npmjs.com/package/stun

1
npm i stun

测试

使用谷歌的stun服务器

1
2
3
4
5
6
7
8
const stun = require('stun');

async function getIp() {
const res = await stun.request('stun.l.google.com:19302');
console.log('your ip', res.getXorAddress().address);
}

getIp();

可以用这个网址去测试stun和turn的有效性:
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

使用SRS

https://www.psvmc.cn/article/2021-01-21-webrtc-srs.html