实时通信基本原理

  • 在线教育、音视频会议这类直播属于实时互动直播,主要考虑传输的实时性,因此一般使用 UDP 作为底层传输协议而娱乐直播对实时性要求不高,更多关注的是画面的质量、音视频是否卡顿等问题,所以一般采用 TCP 作为传输协议

    • 我们称前者为实时互动直播,后者为传统直播
  • 编码帧

    • I 帧:关键帧
      • 压缩率低,可以单独解码成一幅完整的图像。
    • P 帧:参考帧
      • 压缩率较高,解码时依赖于前面已解码的数据。
    • B 帧:前后参考帧
      • 压缩率最高,解码时不光依赖前面已经解码的帧,而且还依赖它后面的 P 帧。换句话说就是,B 帧后面的 P 帧要优先于它进行解码,然后才能将 B 帧解码
  • 共享桌面原理

    • 对于共享者,每秒钟抓取多次屏幕(可以是 3 次、5 次等),每次抓取的屏幕都与上一次抓取的屏幕做比较,取它们的差值,然后对差值进行压缩。再将压缩后的数据通过传输模块传送到观看端;数据到达观看端后,再进行解码,这样即可还原出整幅图片并显示出来
    • 对于远程控制端,当用户通过鼠标点击共享桌面的某个位置时,会首先计算出鼠标实际点击的位置,然后将其作为参数,通过信令发送给共享端。共享端收到信令后,会模拟本地鼠标,即调用相关的 API,完成最终的操作

实时通信架构

img

img

协议

(S)RTP/(S)RTCP协议

  • 实时互动直播系统的时候必须使用UDP 协议

    • 因为如果网络不好,TCP的重传算法是指数回退的,极端情况下会导致1分钟以上的传输延迟,这对于实时通信系统是无法接受的
  • 在实时互动直播系统传输音视频数据流时,我们并不直接将音视频数据流交给 UDP 传输,而是先给音视频数据加个 RTP 头,然后再交给 UDP 进行传输

    • 因为音视频帧的大小远大于UDP的最大传输单元(1.5KB左右),需要对分帧的包进行标记
      • 例如I帧一般会有几十KB,这样就需要传输几十的UDP包到终点并重新组装成I帧并解码
    • 一般来说需要序号,起始和结束标记这几个字段
  • RTP包头字段

    • sequence number:序号,用于记录包的顺序
    • timestamp:时间戳,同一个帧的不同分片的时间戳是相同的
      • 这样就省去了前面所讲的起始标记结束标记,因为不同帧的时间戳肯定是不一样的
    • PT:Payload Type,数据的负载类型
      • 音频流的 PT 值与视频的 PT 值是不同的,通过它就可以知道这个包存放的是什么类型的数据

img

  • RTCP协议用于确定网络链路质量
    • RTCP 有两个重要的报文:**RR(Reciever Report)**和 SR(Sender Report)
    • 通过这两个报文的交换,各端就知道自己的网络质量到底如何了
  • RTP/RTCP 协议并没有对它的负载数据进行加密
    • 因此,如果你通过抓包工具,如 Wireshark,将音视频数据抓取到后,通过该工具就可以直接将音视频流播放出来
    • 为了防止这类事情发生,没有直接使用 RTP/RTCP 协议,而是使用了 SRTP/SRTCP 协议 ,即安全的 RTP/RTCP 协议

SDP协议

  • SDP就是用文本描述的各端(PC 端、Mac 端、Android 端、iOS 端等)的能力,用来进行媒体协商

    • 这里的能力指的是各端所支持的音频编解码器是什么,这些编解码器设定的参数是什么,使用的传输协议是什么,以及包括的音视频媒体是什么等等
    • 通信双方可以根据各自的能力进行协商,协商出大家认可的音视频编解码器、编解码器相关的参数(如音频通道数,采样率等)、传输协议等信息
  • SDP信息的交换是通过信令服务器完成的

    • 通信双方都要先与信令服务器建立websocket连接,之后通过服务器转发
  • 通信中断重连时要重新进行媒体协商

  • 多方通信时,新用户加入时,可以获得先前加入用户的音视频流,但是老用户无法获取新用户的流

    • 因为老用户在进行媒体协商时,新用户还不存在
    • 所以每当有新的用户进来之后,就通过 update 信令通知已经在房间内的所有用户,让它们重新与服务器进行媒体协商
    • 重新协商后,所有老用户就可以收到了新用户的视频流了
  • 对于 1 对 1 通信的双方来说,我们称首先发送媒体协商消息的一方为呼叫方,而另一方则为被呼叫方

    • 呼叫方发送的 SDP 消息称为 Offer,被呼叫方发送的 SDP 消息称为 Answer
  • SDP协议的片段

    • SDP的格式非常简单,由多个行组成,每个行都是<type>=<value>的格式
    • SDP 是由一个会话层和多个媒体层组成的;而对于每个媒体层,WebRTC 又将其细划为四部分,即媒体流、网络描述、安全描述和服务质量描述
    • 下面的例子中有两个媒体层——音频媒体层和视频媒体层

//=============会话描述====================
v=0 
o=- 7017624586836067756 2 IN IP4 127.0.0.1
s=-
t=0 0
...

//================媒体描述=================
//================音频媒体=================
/*
 * 音频使用端口1024收发数据
 * UDP/TLS/RTP/SAVPF 表示使用 dtls/srtp 协议对数据加密传输
 * 111、103 ... 表示本会话音频数据的 Payload Type
 */
 m=audio 1024 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126 

//==============网络描述==================
//指明接收或者发送音频使用的IP地址,由于WebRTC使用ICE传输,这个被忽略。
c=IN IP4 0.0.0.0
//用来设置rtcp地址和端口,WebRTC不使用
a=rtcp:9 IN IP4 0.0.0.0
...

//==============音频安全描述================
//ICE协商过程中的安全验证信息
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
...

//==============音频流媒体描述================
a=rtpmap:111 opus/48000/2
//minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性
a=fmtp:111 minptime=10;useinbandfec=1
...
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
...

//=================视频媒体=================
m=video 9 UDP/TLS/RTP/SAVPF 100 101 107 116 117 96 97 99 98
...
//=================网络描述=================
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
...
//=================视频安全描述=================
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
...

//================视频流描述===============
a=mid:video
...
a=rtpmap:100 VP8/90000
//================服务质量描述===============
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack //支持丢包重传,参考rfc4585
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb //支持使用rtcp包来控制发送方的码流
a=rtcp-fb:100 transport-cc
...

STUN/TURN协议

  • webrtc在建连过程中,如果同时存在多个有效连接时,它会进行连通性测试,首先选择传输质量最好的线路

    • 例如能用内网连通就不用公网,如果尝试了很多线路都连通不了,那么它还会使用服务端中继的方式让双方连通
    • 连通性检测时的超时设置比较重要,设置短了,会把可以连通的判断为不能连通,设置长了,就会在不能连通的配对上浪费时间
    • 在中国,P2P 成功率很低,尤其是移动互联网
  • 如果想在服务器保留音视频通话记录,P2P的连接方式就不能用了

  • 通信场景

    • 如果双方都在同一内网中,则优先走内网通信而不是公网
      • 难点在于如何判定双方位于同一网段
    • 通过公网通信时,优先使用P2P方式直接连接
    • 如果P2P不通,则通过服务器中继转发
  • **ICE Candidate (ICE 候选者)**表示 WebRTC 与远端通信时使用的协议、IP 地址和端口

    • 一般由本地IP和端口,候选类型,优先级,传输协议等字段组成
      • 候选类型包括host(本机或内网),srflx(内网经NAT映射的外网IP和端口)和relay(中继候选者)
      • relay候选者的连通率是所有候选者中连通率最高的
    • WebRTC 会对候选者进行排序,然后按优先级从高到低的顺序进行连通性测试
  • STUN 协议用于获取自己映射的外网IP和端口

    • 首先在外网搭建一个 STUN 服务器
    • 从内网主机发送一个 binding request 的 STUN 消息到 STUN 服务器
    • STUN 服务器收到该请求后,会将请求的 IP 地址和端口填充到 binding response 消息中,然后顺原路将该消息返回给内网主机
    • 收到 binding response 消息的内网主机就可以解析 binding response 消息了,并可以从中得到自己的外网 IP 和端口
  • TURN协议用于获取 relay 服务器(即 TURN 服务器)的 Candidate

    • 通过向 TURN 服务器发送 Allocation 指令,relay 服务就会在服务器端分配一个新的 relay 端口,用于中转 UDP 数据报
  • ICE 就是上面所讲的获取各种类型 Candidate 的过程,或者说就是包括了 STUN、TURN 协议的一套框架

  • 在本机收集所有的 host 类型的 Candidate,通过 STUN 协议收集 srflx 类型的 Candidate,使用 TURN 协议收集 relay 类型的 Candidate

NAT打洞

  • 所谓的“打洞”就是在 NAT 上建立一个内外网的映射表
  • UDP 是无连接协议,它没有连接状态的判断,也就是说只要你发送数据给它,它就能收到。而 TCP 协议必须建立连接后,才能收发数据,因此大多数人都选用 UDP 作为打洞协议
  • 通过借助 STUN/TURN 服务器完成 NAT 穿越

完全锥型

  • 完全锥型 NAT 的特点是,当 host 主机通过 NAT 访问外网的 B 主机时,就会在 NAT 上打个“洞”,所有知道这个“洞”的主机都可以通过它与内网主机上的侦听程序通信
    • 如果 host 主机与 B 主机“打洞”成功,且 A 与 C 从 B 主机那里获得了 host 主机的外网 IP 及端口,那么 A 与 C 就可以向该 IP 和端口发数据

img

IP限制型

  • IP 限制锥型要比完全锥型 NAT 严格得多,它主要的特点是,host 主机在 NAT 上“打洞”后,NAT 会对穿越洞口的 IP 地址做限制

    • 只有登记的 IP 地址才可以通过,也就是说,只有 host 主机访问过的外网主机才能穿越 NAT
    • 而其他主机即使知道“洞”的位置,也不能与 host 主机通信,因为在通过 NAT 时,NAT 会检查 IP 地址,如果发现发来数据的 IP 地址没有登记,则直接将该数据包丢弃
  • IP 限制型 NAT 只限制 IP 地址,如果是同一主机的不同端口穿越 NAT 是没有任何问题的

img

端口限制型

  • 端口限制锥型比 IP 限制锥型 NAT 更加严格,它主要的特点是,不光在 NAT 上对打洞的 IP 地址做了限制,而且还对具体的端口做了限制

img

对称型

  • 对称型 NAT 是所有 NAT 类型中最严格的一种类型

    • 对称型 NAT 对每个连接都使用不同的端口,甚至更换 IP 地址,而端口限制型 NAT 的多个连接则使用同一个端口,这对称型 NAT 与端口限制型 NAT 最大的不同
  • 这种特性为 NAT 穿越造成了很多麻烦,尤其是对称型 NAT 碰到对称型 NAT,或对称型 NAT 遇到端口限制型 NAT 时,基本上双方是无法穿越成功的

img

NAT类型检测步骤

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ogx7YRS2-1587457710647)(C:\Users\35135\Desktop\markdown\1587395288410.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y5qJeXhj-1587457710649)(C:\Users\35135\Desktop\markdown\1587395303318.png)]

img

服务质量

  • 物理链路质量

    • 影响因素:丢包,延迟,抖动
    • 延迟最好小于200ms
    • 抖动指的是数据一会儿快、一会儿慢,很不稳定。如果不加处理的话,你看到的视频效果就是一会儿快播了、一会儿又慢动作
      • WebRTC通过内部的 JitterBuffer(可以简单地理解为一块缓冲区)来解决该问题
  • 带宽大小

    • 指的是每秒钟可以传输多少bit,比如 1M 带宽,它表达的是每秒钟可以传输 1M 个 bit 位
    • 换算成字节就是 1Mbps/8 = 128KBps,也就是说 1M 带宽实际每秒钟只能传输 128K 个 Byte
    • 延迟是因为你的网终带宽与音视频流大小不匹配
  • 帧率

    • 通过减少帧率来控制码率的效果可能并不明显
    • 因为在传输数据之前是要将原始音视频数据进行压缩的,在同一个 GOP(Group Of Picture)中,除了 I/IDR 帧外,B 帧和 P 帧的数据量是非常小的
    • 因此帧率与延迟的关系不是特别大,实际上分辨率才是影响最大的

通信安全

  • TLS 底层是基于 TCP 协议的,而 WebRTC 音视频数据的传输主要基于 UDP 协议,因此 WebRTC 对数据的保护无法直接使用 TLS 协议
  • DTLS 就是运行在 UDP 协议之上的简化版本的 TLS,它使用的安全机制与 TLS 几乎一模一样
  • webRTC通过使用 SDP、STUN、DTLS、SRTP 等几个协议的结合来达到数据安全的
    • 首先通过信令服务器交换 SDP,SDP 信息中包括了对方的 ice-ufrag、ice-pwd 和 fingerprint 信息,有了这些信息后,就可验证对方是否是一个合法用户了
      • ice-ufrag 和 ice-pwd 是用户名和密码
      • 当 A 与 B 建立连接时,A 要带着它的用户名和密码过来,此时 B 端就可以通过验证 A 带来的用户名和密码与 SDP 中的用户名和密码是否一致的,来判断 A 是否是一个合法用户了
      • fingerprint 是存放公钥证书的指纹(或叫信息摘要)
        • 在通过 ice-ufrag 和 ice-pwd 验证用户的合法性之余,还要对它发送的证书做验证,看看证书在传输的过程中是否被窜改了
    • 紧接着通过 STUN 协议利用前面的信息进行身份认证
      • 如果 STUN 消息中的用户名和密码与交换的 SDP 中的用户名和密码一致,则说明是合法用户
    • 确认对端合法后,则发送 DTLS 消息与服务端进行 DTLS “握手”
      • 在“握手”过程中要交换双方的安全证书和公钥等相关信息,确认其没有在传输中被窜改
    • 使用协商后的密码信息和公钥对数据进行加密,开始传输音视频数据

多方通信方案

mesh方案

img

  • 多个终端之间两两进行连接,同时还分别与 STUN/TURN 服务器进行连接,形成一个网状结构

  • 当某个浏览器想要共享它的音视频流时,它会将共享的媒体流分别发送给其他 3 个浏览器,这样就实现了多人通

  • 优点

    • 不需要服务器中转数据,STUN/TUTN 只是负责 NAT 穿越,这样利用现有 WebRTC 通信模型就可以实现,而不需要开发媒体服务器
    • 充分利用了客户端的带宽资源
    • 节省了服务器资源,由于服务器带宽往往是专线,价格昂贵,这种方案可以很好地控制成本
  • 缺点

    • 这种方案对各终端的上行带宽占用很大,同时也会大量占用 CPU、Memory 等资源
    • 导致多人通信的规模非常有限
      • 通过实践来看,这种方案在超过 4 个人时,就会有非常大的问题
    • 如果有部分人不能实现 NAT 穿越,但还想让这些人与其他人互通,就显得很麻烦

MCU方案

img

  • 该方案由一个服务器和多个终端组成一个星形结构

  • 各终端将自己要共享的音视频流发送给服务器,服务器端会将在同一个房间中的所有终端的音视频流进行混合,最终生成一个混合后的音视频流再发给各个终端

    • 以上图为例,若B1 与 B2 同时共享音视频流,它们首先将流推送给 MCU 服务器,MCU 服务器收到两路流后,分别将两路流进行解码,之后将解码后的两路流进行混流,然后再编码,编码后的流数据再分发给 B3 和 B4

    img

  • 优点

    • 通过解码、再编码可以屏蔽不同编解码设备的差异化,满足更多客户的集成需求
  • 缺点

    • 重新解码、编码、混流,需要大量的运算,对服务器 CPU 资源的消耗很大,且会带来延迟
    • 由于机器资源耗费很大,所以 MCU 所提供的容量有限,一般十几路视频就是上限了

SFU方案

img

  • SFU 是三种架构方案中优势最明显而劣势又相对较少的一种架构方案
    • WebRTC 普及以后,支持 WebRTC 多方通信的媒体服务器基本都是 SFU 结构
  • 该方案也是由一个服务器和多个终端组成,但与 MCU 不同的是,SFU 不对音视频进行混流
    • SFU服务器收到某个终端共享的音视频流后,就直接将该音视频流转发给房间内的其他终端

img

  • 优点

    • 由于是数据包直接转发,不需要编码、解码,对 CPU 资源消耗很小,同时降低了延迟,提高了实时性
    • 可以根据终端下行网络状况做一些流控,可以根据当前带宽情况、网络延时情况,选择性地丢弃一些媒体数据,保证通信的连续性
  • 缺点

    • 由于是数据包直接转发,参与人观看多路视频的时候可能会出现不同步
    • 相同的视频流,不同的参与人看到的画面也可能不一致
  • simulcast模式

    • 指视频的共享者可以同时向 SFU 发送多路不同分辨率的视频流(一般为三路,如 1080P、720P、360P)
    • 而 SFU 可以将接收到的三路流根据各终端的情况而选择其中某一路发送出去
      • 例如,由于 PC 端网络特别好,给 PC 端发送 1080P 分辨率的视频;而移动网络较差,就给 Phone 发送 360P 分辨率的视频
    • 可以灵活而又智能地适应不同的网络环境

img

  • SVC模式
    • 在视频编码时将视频分成多层——核心层、中间层和扩展层
    • 上层依赖于底层,而且越上层越清晰,越底层越模糊。在带宽不好的情况下,可以只传输底层,即核心层,在带宽充足的情况下,可以将三层全部传输过去

img

  • 通过录制桌面,可以把多路音视频流录制下来以进行回放
    • 利用一个虚拟客户端接入 SFU 服务器,仅拉流,不上传流
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章