webrtc学习记录(一)

1,101 阅读9分钟

1. 什么是 WebRTC?

WebRTC(Web Real-Time Communications)是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC 包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建点对点(Peer-to-Peer)的数据分享和电话会议成为可能。

2.WebRTC架构(标准网图)

v2-9cfb8117f41f93e8825afb68bc32b384_r.jpg.png

3. WebRTC 建连流程(标准网图)

20200618134458727.png

4. NAT 四种类型

NAT(Network Address Translation)是网络地址转换技术,用于将内部网络的私有 IP 地址转换为公网 IP 地址,以便访问互联网。在 WebRTC 中,NAT 会带来建立 P2P 连接的难题。根据 NAT 的不同类型,WebRTC 中的 NAT 分为以下四种类型:

  1. Full Cone NAT(全锥型):内部 IP 地址和端口的任何外部请求都可以通过 NAT。如下图,

A只和C建立过通道,但是路由也会转发来自B、D的消息,不限IP、端口

企业微信截图_20230530140729.png

  1. Restricted Cone NAT(受限锥型):内部 IP 地址和端口只允许收到先前已发送数据包的外部 IP 地址的请求。如下图,A只和C建立过通道,路由只会转发C的消息,不限端口,限IP 企业微信截图_20230530141342.png

  2. Port Restricted Cone NAT(端口受限锥型):内部 IP 地址和端口只允许收到先前已发送数据包的外部 IP 地址和端口的请求。如下图,A只和cIp:cPort1建立过通道,路由只会转发cIp:cPort1的消息,限端口,限Ip

企业微信截图_20230530142451.png 4. Symmetric NAT(对称型):相同的内部 IP 地址和端口发送给不同的外部 IP 地址和端口时,NAT 会为每个请求分配不同的外部 IP 地址和端口。如下图

企业微信截图_20230530143149.png

除了全锥型,其他类型nat都会让p2p变得更困难,如何解决?

5. STUN 和 TURN

STUN(Session Traversal Utilities for NAT)和 TURN(Traversal Using Relay NAT)是 WebRTC 技术中用于解决 NAT(Network Address Translation)穿透问题的协议。

STUN:

  • 客户端发送STUN请求到公共STUN服务器。
  • 服务器返回响应,其中包含客户端的公共IP地址和端口映射信息。
  • 客户端获取这些信息,并将其用于建立对等连接。

TURN:

  • 设备A无法直接与设备B通信,因此设备A将数据发送到TURN服务器。
  • TURN服务器接收数据,并为设备A分配一个临时的公共地址和端口映射。
  • 然后,TURN服务器将数据转发给设备B。
  • 设备B接收到数据后,可以通过TURN服务器将响应发送回设备A。
  • 这样,通过TURN服务器作为中继,设备A和设备B可以进行间接的通信。

6.ICE和SDP

ICE(Interactive Connectivity Establishment)是一个框架,其目标是允许两个网络节点找到并使用最有效的方式进行直接通信。这个过程包括穿越NAT设备和防火墙。它试图使用STUN服务器和TURN服务器来找到可以接受传入和传出连接的地址。下面是一个简单的示例(web端投屏到客户端):

# web端
"candidate" : "candidate:2642342510 1 udp 1677729535 58.248.106.93 55720 typ srflx raddr 0.0.0.0 rport 0 generation 0 ufrag D5CQ network-cost 999"
"candidate" : "candidate:2642342510 1 udp 1677729535 58.248.106.93 55721 typ srflx raddr 0.0.0.0 rport 0 generation 0 ufrag D5CQ network-cost 999"
# 客户端
"candidate":"candidate:350089694 1 udp 2122260223 xx.xx.xx.xx 53217 typ host generation 0 ufrag u/Pq network-id 3"

SDP (Session Description Protocol) 是用于描述和初始化媒体会话的格式,包括媒体流的各种参数,如编码格式,媒体类型,传输协议,IP 地址和端口等。下面是一个简单的sdp示例(客户端):

v=0
o=- 8482858385230299196 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=extmap-allow-mixed
a=msid-semantic: WMS
# 视频媒体流的描述
# UDP/TLS/RTP/SAVPF:UDP传输,TLS加密,使用SAVPF进行RTP数据包的安全传输
# 96(VP8),优先VP8编码,可更改
m=video 9 UDP/TLS/RTP/SAVPF 96 97 102 103 104 105 106 107 108 109 98 99 100 101 116 117 118
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:u/Pq
a=ice-pwd:Oh7EsEl1ls+3c9kDO4qzbvpA
a=ice-options:trickle
a=fingerprint:sha-256 52:97:C7:35:86:0A:0E:EB:C1:2C:14:B8:31:0C:89:4C:1F:63:FA:1C:F2:5B:24:28:2B:58:43:D1:10:39:D8:21
a=setup:active
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 <http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time>
a=extmap:3 urn:3gpp:video-orientation
a=extmap:4 <http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01>
a=extmap:5 <http://www.webrtc.org/experiments/rtp-hdrext/playout-delay>
a=extmap:6 <http://www.webrtc.org/experiments/rtp-hdrext/video-content-type>
a=extmap:7 <http://www.webrtc.org/experiments/rtp-hdrext/video-timing>
a=extmap:8 <http://www.webrtc.org/experiments/rtp-hdrext/color-space>
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=recvonly
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:102 H264/90000
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=102
a=rtpmap:104 H264/90000
a=rtcp-fb:104 goog-remb
a=rtcp-fb:104 transport-cc
a=rtcp-fb:104 ccm fir
a=rtcp-fb:104 nack
a=rtcp-fb:104 nack pli
a=fmtp:104 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:105 rtx/90000
a=fmtp:105 apt=104
a=rtpmap:106 H264/90000
a=rtcp-fb:106 goog-remb
a=rtcp-fb:106 transport-cc
a=rtcp-fb:106 ccm fir
a=rtcp-fb:106 nack
a=rtcp-fb:106 nack pli
a=fmtp:106 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=106
a=rtpmap:108 H264/90000
a=rtcp-fb:108 goog-remb
a=rtcp-fb:108 transport-cc
a=rtcp-fb:108 ccm fir
a=rtcp-fb:108 nack
a=rtcp-fb:108 nack pli
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
a=rtpmap:109 rtx/90000
a=fmtp:109 apt=108
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 profile-id=0
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 profile-id=2
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:116 red/90000
a=rtpmap:117 rtx/90000
a=fmtp:117 apt=116
a=rtpmap:118 ulpfec/90000
# 音频媒体流的描述
# UDP/TLS/RTP/SAVPF:UDP传输,TLS加密,使用SAVPF进行RTP数据包的安全传输
# 111(opus),优先opus编码
m=audio 9 UDP/TLS/RTP/SAVPF 111 9 0 8 13 110 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:u/Pq
a=ice-pwd:Oh7EsEl1ls+3c9kDO4qzbvpA
a=ice-options:trickle
a=fingerprint:sha-256 52:97:C7:35:86:0A:0E:EB:C1:2C:14:B8:31:0C:89:4C:1F:63:FA:1C:F2:5B:24:28:2B:58:43:D1:10:39:D8:21
a=setup:active
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 <http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time>
a=extmap:4 <http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01>
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=inactive
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:126 telephone-event/8000
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:u/Pq
a=ice-pwd:Oh7EsEl1ls+3c9kDO4qzbvpA
a=ice-options:trickle
a=fingerprint:sha-256 52:97:C7:35:86:0A:0E:EB:C1:2C:14:B8:31:0C:89:4C:1F:63:FA:1C:F2:5B:24:28:2B:58:43:D1:10:39:D8:21
a=setup:active
a=mid:2
a=sctp-port:5000
a=max-message-size:262144

想要深入学习webrtc,怎么能不尝试编一手webrtc呢?

7. WebRTC 编译(Windows端)

一、环境准备

1、vs2019 + ninja

2、1个100G+的空盘

二、代码拉取

1、下载depot_tools

2、配置环境变量,把depot_tools目录配到path中

3、创建目录,用来存放webrtc源码

mkdir webrtc
cd webrtc
fetch --nohooks webrtc
gclient sync
  • 拉代码过程比较漫长,网络正常的话一两个小时的样子
  • 如果中途失败了,那大概率就是网络问题,重来一遍,直到成功

4、切分支,目前所用的是m92,对应的就是4515

git branch -r
git checkout -b m92 branch-heads/4515
gclient sync

三、编译

cd webrtc
set DEPOT_TOOLS_WIN_TOOLCHAIN=0
gn gen --ide=vs2019 out/Debug --args="is_debug=true enable_iterator_debugging=true target_cpu=\"x64\" is_clang=false rtc_include_tests=false symbol_level=2 rtc_use_h264=true"
ninja -C out\Debug
  • is_debug : true表示编译debug版本,false表示release

  • enable_iterator_debugging : debug版本必需位true

  • target_cpu : x86/x64

  • is_clang : 是否使用clang编译,windows下建议设为false,用vs编译

  • rtc_include_tests : 是否编译测试项目

  • symbol_level

    • 1 表示根据不同环境自动设置
    • 0 表示不生产debug符号
    • 1 表示生成mini符号,满足堆栈回溯
    • 2 表示生成完整debug符号
  • rtc_use_h264 : 是否支持h264

更多参数,参考webrtc编译参数

8.总结

至此,我们已经初步探索了 WebRTC 的一些基础知识,包括其基本原理,以及如何从源码开始进行编译,这其实还谈不上入门,还有很多值得研究的地方,比如让p2p通信变的可能的nat穿透技术等等。

总的来说,WebRTC很强,也很庞大,有待继续学习。